Событие PreUpdate
Событие PreUpdate вызывается перед тем,
как обновлённая сущность будет записана в базу данных.
Оно позволяет изменить данные сущности непосредственно
перед выполнением SQL-запроса UPDATE. Событие срабатывает
только для существующих сущностей, которые уже были
сохранены ранее. Для новых сущностей используется
событие PrePersist.
Обработчик события получает объект
PreUpdateEventArgs, который содержит ссылку
на сущность, менеджер сущностей и информацию
об изменённых полях. Событие не срабатывает,
если сущность не была изменена.
Синтаксис
#[HasLifecycleCallbacks]
class EntityName
{
#[PreUpdate]
public function methodName(PreUpdateEventArgs $args): void
{
}
}
Пример
Давайте создадим сущность Article
с обработчиком события PreUpdate,
который автоматически обновляет поле updatedAt
при каждом изменении:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use DoctrineORMMappingHasLifecycleCallbacks;
use DoctrineORMMappingPreUpdate;
use DoctrineORMEntityManagerInterface;
use DoctrineORMEventPreUpdateEventArgs;
#[ORMEntity]
#[ORMTable(name: 'articles')]
#[HasLifecycleCallbacks]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $title = '';
#[ORMColumn(type: 'text')]
private string $content = '';
#[ORMColumn(type: 'datetime')]
private DateTimeInterface $updatedAt;
public function __construct()
{
$this->updatedAt = new DateTime();
}
#[PreUpdate]
public function setUpdatedAt(PreUpdateEventArgs $args): void
{
$this->updatedAt = new DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getUpdatedAt(): DateTimeInterface
{
return $this->updatedAt;
}
}
?>
Пример
Давайте используем событие PreUpdate
для логирования изменений полей сущности:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use DoctrineORMMappingHasLifecycleCallbacks;
use DoctrineORMMappingPreUpdate;
use DoctrineORMEventPreUpdateEventArgs;
#[ORMEntity]
#[ORMTable(name: 'articles')]
#[HasLifecycleCallbacks]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $title = '';
#[ORMColumn(type: 'text')]
private string $content = '';
#[PreUpdate]
public function logChanges(PreUpdateEventArgs $args): void
{
$entity = $args->getObject();
$em = $args->getObjectManager();
if ($args->hasChangedField('title')) {
$oldValue = $args->getOldValue('title');
$newValue = $args->getNewValue('title');
echo "Title changed from {$oldValue} to {$newValue}";
}
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
}
?>
Пример
Давайте проверим работу события PreUpdate
в контроллере при обновлении сущности:
<?php
namespace AppController;
use AppEntityArticle;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/update/{id}', name: 'article_update')]
public function update(int $id, EntityManagerInterface $em): Response
{
$article = $em->getRepository(Article::class)->find($id);
if (!$article) {
return new Response('article not found');
}
$article->setTitle('abcde');
$em->flush();
return new Response('updated');
}
}
?>
Результат выполнения кода:
"updated"
Смотрите также
-
событие
PrePersist,
которое вызывается перед сохранением новой сущности -
событие
PostUpdate,
которое вызывается после обновления сущности -
атрибут
HasLifecycleCallbacks,
который включает поддержку событий жизненного цикла -
событие
PreRemove,
которое вызывается перед удалением сущности