更新域模型,但TYPO3 6.2

时间:2016-10-18 17:43:52

标签: php typo3 extbase typo3-6.2.x domain-model

我维护一个TYPO3扩展,用于管理后端的前端用户。因此,我使用自己的模型扩展FrontendUserRepository。我的扩展程序提供CRUD操作,我在更新现有人员的密码时遇到问题。如果填写了编辑表单中的密码字段,则只想更新密码;否则(如果它保留为空)旧密码值将保留在数据库中。

现在TYPO3 4.5一切正常,但现在我升级到6.2后,在提交带有空密码字段的编辑表单时,会将一个空字符串保存到数据库...

这是我的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));
}

有人知道,为什么$oldPerson->getPassword()没有从数据库返回密码字段的当前值?或者是否有另一种方式来跳过"跳过"更新所有其他属性时域模型的属性?奇怪的是它适用于TYPO3 4.5 ......

1 个答案:

答案 0 :(得分:3)

  

有人知道,为什么$oldPerson->getPassword()没有从数据库返回密码字段的当前值?

这是因为Extbase有一种一级缓存:如果对象是从持久性中提取一次,则在同一请求期间不会从数据库中第二次获取,而是直接从内存中返回。

因此,在你的情况下,$person对象是从数据库中第一次获取,当一个属性映射发生时(内部Extbase操作将你的POST数据转换为\My\Vendor\Domain\Model\Person的实例)。

当您调用$this->personRepository->findByUid($person->getUid());时,Extbase不进行数据库查找,但直接从内存中获取对象,从而导致$oldPerson === $person。由于$person已经更改了密码(通过POST数据),$oldPerson->getPassword()也会返回更改后的值。

可能的解决办法是获取清洁属性

如果模型的属性已更改但尚未保存,则几乎总是有可能获取原始值(例如,db中存在的值)。您可以使用_getCleanProperty($propertyName)模型方法:

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

(可选)如果您甚至不想要password字段的数据库更新,您甚至可以记住清洁属性状态,这将告诉Extbase :不要更新db:

中的属性
$person->_memorizePropertyCleanState('password');

注意:记住属性状态后,_getCleanProperty()将返回由set*()方法设置的值 - 而不是db中存在的原始值(如果您设置不同的值)。