更新域模型,除了 TYPO3 6.2 中的一个 属性

Update Domain Model except for one property in TYPO3 6.2

我维护了一个在后端管理前端用户的 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() 不 return 来自数据库的密码字段的当前值?还是有另一种方法可以在更新所有其他属性的同时 "skip" 域模型的 属性?奇怪的是它在 TYPO3 4.5 中工作...

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

这是因为 Extbase 有一种一级缓存:如果对象从持久化中获取一次,则不会在同一请求中第二次从数据库中获取,而是直接 returned 形成内存.

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

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

可能的解决方法是清理干净属性

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

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

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

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

注意:记住属性状态后,_getCleanProperty()会return这个值,这个值是set*()设置的方法 - 不是数据库中的原始方法(以防您设置不同的值)。