我维护一个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 ......
答案 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中存在的原始值(如果您设置不同的值)。