#php #typo3 #extbase #typo3-6.2.x #domain-model
#php #typo3 #extbase #typo3-6.2.x #domain-model
Вопрос:
Я поддерживаю расширение TYPO3, которое управляет внешними пользователями в серверной части. Поэтому я расширяю FrontendUserRepository своей собственной моделью. Мое расширение обеспечивает операции CRUD, и у меня проблема с обновлением пароля существующих пользователей. Идея состоит в том, чтобы обновлять пароль только в том случае, если поле пароля в форме редактирования заполнено, в противном случае (если оно оставлено пустым) старое значение пароля остается в базе данных.
Теперь все работало нормально с TYPO3 4.5, но теперь, после обновления до версии 6.2, пустая строка сохраняется в базе данных при отправке формы редактирования с пустым полем пароля…
Это мой updateAction()
:
/**
* action update
*
* @param MyVendorDomainModelPerson $person
*
* @return void
*/
public function updateAction(MyVendorDomainModelPerson $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:
Кто-нибудь знает,
$oldPerson->getPassword()
почему не возвращает текущее значение для поля пароля из базы данных?
Это связано с тем, что Extbase имеет своего рода кэш 1-го уровня: если объект был извлечен из формы сохранения один раз, он не будет извлечен во второй раз из базы данных во время того же запроса, а будет возвращен непосредственно из памяти.
Итак, в вашем случае $person
объект извлекается из базы данных 1-й раз, когда происходит сопоставление свойств (внутренняя операция Extbase, которая преобразует ваши данные POST в экземпляр MyVendorDomainModelPerson
).
Когда вы вызываете $this->personRepository->findByUid($person->getUid());
Extbase, он не выполняет поиск в базе данных, а извлекает объект непосредственно из памяти, что приводит к $oldPerson === $person
. И поскольку $person
пароль уже изменен (через данные POST), $oldPerson->getPassword()
возвращает также измененное значение.
Возможное решение для этого — получить чистое свойство
Если свойство модели было изменено, но еще не сохранено, почти всегда есть возможность получить исходное значение (например, то, которое существует в БД). Для этого вы можете использовать _getCleanProperty($propertyName)
метод model:
$person->setPassword($oldPerson->_getCleanProperty('password')));
При желании, если вы даже не хотите обновлять password
поле в БД, вы можете даже запомнить состояние чистого свойства, которое сообщит Extbase: не обновлять свойство в БД:
$person->_memorizePropertyCleanState('password');
Примечание: после того, как вы запомните состояние свойства, _getCleanProperty()
будет возвращено значение, которое было установлено set*()
методом, а не исходное, присутствующее в БД (в случае, если вы установили другое значение).
Комментарии:
1. Спасибо за этот подробный ответ!
_getCleanProperty()
Функция работает