Update Domain Model except for one property in TYPO3 6.2

巧了我就是萌 提交于 2019-12-08 08:12:19

问题


I maintain a TYPO3 extension that manages frontend users in the backend. Therefore I extend the FrontendUserRepository with my own model. My extension provides CRUD operations and I have a problem with updating the password of existing persons. The idea is to only update the password, if the password field in the edit form is filled, otherwise (if it's left empty) the old password value remains in the database.

Now everything was working fine with TYPO3 4.5, but now after I upgraded to 6.2, an empty string is saved to the database when submitting the edit form with an empty password field...

This is my updateAction():

/**
 * 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));
}

Does anybody know, why $oldPerson->getPassword() does not return the current value for the password field from the database? Or is there another way to "skip" a property of a domain model while updating all other properties? The strange thing is that it worked in TYPO3 4.5 ...


回答1:


Does anybody know, why $oldPerson->getPassword() does not return the current value for the password field from the database?

This is because Extbase has a kind of 1st level cache: if the object was fetched form persistence once, it will not be fetched second time from database during same request, but returned directly form a memory.

So, in your case $person object is fetched from database 1st time, when a property mapping happens (internal Extbase operation which translates your POST data to instance of \My\Vendor\Domain\Model\Person).

When you call $this->personRepository->findByUid($person->getUid()); Extbase doesn't make a database lookup, but fetches object directly form memory resulting in $oldPerson === $person. And since $person has already changed password (via POST data), $oldPerson->getPassword() returns also the changed value.

Possible solution for this is to get clean property

If the property of model was changed but not yet saved there is almost always a possibility to fetch the original value (e.g. one, that exists in db). You can use a _getCleanProperty($propertyName) method of model for this:

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

Optionally if you don't even want a db update of password field, you can even memorize clean property state, which will tell Extbase: do not update the property in db:

$person->_memorizePropertyCleanState('password');

Note: after you memorize property state, _getCleanProperty() will return the value, which was set by set*() method - not the original one present in db (in case you set a differnet value).



来源:https://stackoverflow.com/questions/40114773/update-domain-model-except-for-one-property-in-typo3-6-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!