2016-10-18 2 views
1

Je gère une extension TYPO3 qui gère les utilisateurs frontend dans le backend. Par conséquent j'étend le FrontendUserRepository avec mon propre modèle. Mon extension fournit des opérations CRUD et j'ai un problème avec la mise à jour du mot de passe des personnes existantes. L'idée est de ne mettre à jour le mot de passe que si le champ de mot de passe dans le formulaire d'édition est rempli, sinon (s'il est vide) l'ancienne valeur du mot de passe reste dans la base de données.Mise à jour du modèle de domaine à l'exception d'une propriété dans TYPO3 6.2

Maintenant, tout fonctionnait très bien avec TYPO3 4.5, mais maintenant après avoir mis à jour à 6.2, une chaîne vide est enregistrée dans la base de données lors de la présentation du formulaire d'édition avec un champ de mot de passe vide ...

Ceci est mon :

/** 
* action update 
* 
* @param \My\Vendor\Domain\Model\Person $person 
* 
* @return void 
*/ 
public function updateAction(\My\Vendor\Domain\Model\Person $person) { 
    // only hash and set password if not empty 
    if ($person->getPassword() == '') { 
     // if password was left empty, get current password from database 
     $oldPerson = $this->personRepository->findByUid($person->getUid()); 
     $person->setPassword($oldPerson->getPassword())); 
    } else { 
     $person->setPassword(md5($person->getPassword())); 
    } 

    // save updated person to repository 
    $this->personRepository->update($person); 

    $this->flashMessageContainer->add('The person data was saved.'); 
    $this->redirect('edit', NULL, NULL, array('person' => $person)); 
} 

Quelqu'un sait-il, pourquoi $oldPerson->getPassword() ne retourne pas la valeur actuelle du champ de mot de passe de la base de données? Ou existe-t-il un autre moyen de "sauter" une propriété d'un modèle de domaine tout en mettant à jour toutes les autres propriétés? La chose étrange est que cela a fonctionné dans TYPO3 4.5 ...

Répondre

3

Quelqu'un sait-il, pourquoi $oldPerson->getPassword() ne retourne pas la valeur actuelle du champ de mot de passe de la base de données?

En effet, Extbase a une sorte de cache 1er niveau: si l'objet était la persistance de la forme une fois tiré par les cheveux, il ne sera pas la deuxième fois la base de données extraites au cours même demande, mais directement une forme retourné mémoire. Par conséquent, dans votre cas, l'objet $person est extrait de la base de données 1ère fois, lors du mappage d'une propriété (opération Extbase interne qui traduit vos données POST en instance de \My\Vendor\Domain\Model\Person).

Lorsque vous appelez $this->personRepository->findByUid($person->getUid()); Extbase n'effectue pas de recherche dans la base de données, mais récupère l'objet directement dans la mémoire, ce qui correspond à $oldPerson === $person. Et puisque $person a déjà changé le mot de passe (via les données POST), $oldPerson->getPassword() renvoie également la valeur modifiée.

solution possible est de obtenir la propriété propre

Si la propriété du modèle a été modifié, mais pas encore enregistré il y a presque toujours une possibilité de récupérer la valeur d'origine (par exemple un, qui existe dans db). Vous pouvez utiliser une méthode _getCleanProperty($propertyName) de modèle pour ceci:

$person->setPassword($oldPerson->_getCleanProperty('password'))); 

En option si vous ne voulez même pas une mise à jour de db de password champ, vous pouvez même mémoriser l'état de la propriété propre, qui dira Extbase: ne met pas à jour la propriété dans db:

$person->_memorizePropertyCleanState('password'); 

Remarque: Une fois que vous mémorisez état de la propriété, _getCleanProperty() renvoie la valeur, qui a été fixée par set*() méthode - pas l'original présent dans db (au cas où vous définissez une valeur differnet).

+0

Merci pour cette réponse détaillée! La fonction '_getCleanProperty()' fonctionne – andreas