19/10/2014 - DOCTRINE, SYMFONY
The preUpdate won't work on its own when carrying out one more flush()
in event listener so for that reason we need help from postFlush. E.g. persisting logs into another entity when the listened entity is being updated. In example below, we're updating a particular field of actual User entity and persisting a new record into UserLog entity with event listener when updating User entity in controller.
public function updateAction()
{
$user = $this->userRepository->findOneByUsername('inanzzz');
if ($user instanceof User) {
$user->setPassword(time());
$this->entityManager->flush();
}
}
services:
application_backend.event_listener.user_entity:
class: Application\BackendBundle\EventListener\UserEntityListener
tags:
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: postFlush }
namespace Application\BackendBundle\EventListener;
use Application\BackendBundle\Entity\User;
use Application\BackendBundle\Entity\UserLog;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
class UserEntityListener
{
private $log = [];
public function preUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof User) {
$entity->setPreUpdate('preUpdate at ' . date('d/m/Y H:i:s'));
$userLog = new UserLog();
$userLog->setUserId($entity->getId());
$userLog->setMessage('preUpdate at ' . date('d/m/Y H:i:s'));
$this->log[] = $userLog;
}
}
public function postFlush(PostFlushEventArgs $args)
{
if (! empty($this->log)) {
$em = $args->getEntityManager();
foreach ($this->log as $log) {
$em->persist($log);
}
$this->log = [];
$em->flush();
}
}
}
mysql> SELECT id, username, password, pre_update FROM user LIMIT 1;
+----+----------+------------------------------------------+------------+
| id | username | password | pre_update |
+----+----------+------------------------------------------+------------+
| 32 | inanzzz | 09cd68a2a77b22a312dded612dd0d9988685189f | NULL |
+----+----------+------------------------------------------+------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM user_log;
Empty set (0.00 sec)
mysql> SELECT id, username, password, pre_update FROM user LIMIT 1;
+----+----------+------------+----------------------------------+
| id | username | password | pre_update |
+----+----------+------------+----------------------------------+
| 32 | inanzzz | 1435609558 | preUpdate at 29/06/2015 21:25:58 |
+----+----------+------------+----------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM user_log;
+----+---------+----------------------------------+
| id | user_id | message |
+----+---------+----------------------------------+
| 9 | 32 | preUpdate at 29/06/2015 21:25:58 |
+----+---------+----------------------------------+
1 row in set (0.00 sec)