Doctrine2 documentation on preUpdate
event says
This event has a powerful feature however, it is executed with a
PreUpdateEventArgs
instance, which contains a reference to the computed change-set of this entity. This means you have access to all the fields that have changed for this entity with their old and new value.
Sounds useful! So what I do:
/**
* 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();
}
// ...
}
But no luck - no arguments are passed:
Catchable Fatal Error: Argument 1 passed to
Acme\TestBundle\Entity\Article::preUpdate()
must be an instance ofDoctrine\ORM\Event\PreUpdateEventArgs
, none given, called in...\vendor\doctrine\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php
on line 1540 and defined in...\src\Acme\TestBundle\Entity\Article.php
line 163
I guess this must work some other way in Symfony2. How do I do it?
You should remember what with PreUpdateEventArgs instance you have access to all the fields that have CHANGED for this entity with their old and new value. But in you example updatedAt will not be at that changeset. If you try to set updatedAt value, you should get error: "Field 'updatedAt' is not a valid field of the entity". So, you can change updateAt field and then use UnitOfWork:recomputeSingleEntityChangeSet. Example:
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
);
}
}
More code examples in my blog post (on russain:)): Update doctine entity in preUpdate event
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With