我维护一个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 回答
这是因为Extbase有一种一级缓存:如果对象是从持久性中提取一次,则在同一请求期间不会从数据库中第二次获取,而是直接从内存中返回 .
因此,在您的情况下,第一次从数据库中获取
$person
对象,此时发生属性映射(内部Extbase操作将您的POST数据转换为\My\Vendor\Domain\Model\Person
的实例) .当您调用
$this->personRepository->findByUid($person->getUid());
时,Extbase不会进行数据库查找,而是直接从内存中获取对象,从而导致$oldPerson === $person
. 由于$person
已经更改了密码(通过POST数据),$oldPerson->getPassword()
也返回更改的值 .可能的解决办法是 get clean property
如果模型的属性已更改但尚未保存,则几乎总是有可能获取原始值(例如,db中存在的值) . 您可以使用
_getCleanProperty($propertyName)
模型方法:(可选)如果你甚至不想要
password
字段的db更新,你甚至可以 memorize clean property state ,这将告诉Extbase:不要更新db中的属性:Note :记住属性状态后,
_getCleanProperty()
将返回由set*()
方法设置的值 - 而不是db中存在的原始值(如果设置了不同的值) .