El preUpdate de Doctrine2 falta el argumento PreUpdateEventArgs en Symfony2

La documentación de Doctrine2 sobre el evento preUpdate dice

Sin embargo, este evento tiene una característica poderosa, se ejecuta con una instancia PreUpdateEventArgs , que contiene una referencia al conjunto de cambios calculado de esta entidad. Esto significa que tiene acceso a todos los campos que han cambiado para esta entidad con su valor anterior y nuevo.

Suena útil! Entonces, lo que hago:

 /** * Acme\TestBundle\Entity\Article * * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class Article { // ... /** * @ORM\PreUpdate */ public function preUpdate(\Doctrine\ORM\Event\PreUpdateEventArgs $eventArgs) { if ( /* use $eventArgs here */ ) $this->updatedAt = new \DateTime(); } // ... } 

Pero sin suerte, no se pasan argumentos:

Error grave detectable: el argumento 1 pasó a
Acme\TestBundle\Entity\Article::preUpdate() debe ser una instancia de
Doctrine\ORM\Event\PreUpdateEventArgs , none given , llamado en
...\vendor\doctrine\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php en la línea 1540 y definido en ...\src\Acme\TestBundle\Entity\Article.php línea 163

Supongo que esto debe funcionar de otra manera en Symfony2. ¿Cómo lo hago?

Hay dos formas de manejar eventos del ciclo de vida.

Primero, simplemente anote un método de su entidad de doctrine como @ORM \ PreUpdate. Este método se llamará antes de la actualización. El segundo es más complicado. Implica preUpdate . Es una clase separada a la que se suscribe para escuchar eventos particulares.

Lea cuidadosamente de nuevo aquí y el libro de cocina de Symfony.

Debería recordar que con la instancia PreUpdateEventArgs tiene acceso a todos los campos que han CAMBIADO para esta entidad con su valor anterior y nuevo. Pero en su ejemplo, updatedAt no estará en ese conjunto de cambios. Si intentas establecer el valor de updatedAt, deberías obtener el error: “Field ‘updatedAt’ no es un campo válido de la entidad”. Por lo tanto, puede cambiar la actualización en el campo y luego usar UnitOfWork: recomputeSingleEntityChangeSet. Ejemplo:

 public function preUpdate(PreUpdateEventArgs $args) { $entity = $args->getEntity(); $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); if ($entity instanceof Product) { $entity->setDiscount(123); $uow->recomputeSingleEntityChangeSet( $em->getClassMetadata("XXXBundle:Product"), $entity ); } } 

Más ejemplos de código en mi publicación de blog (en russain :)): actualización de la entidad doctine en el evento preUpdate