You all, at some point, faced the necessity to compare old and new values when storing an entity.
Here is where Doctrine EntityListener comes at help.
Let imagine you have this User entity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App/Entity; class User { /** @var string $email */ private $email; public function getEmail(): string { return $this->email; } } |
and you want to notify the user when the email address has been changed.
All you have to do is create an EntityListener as described here and end up with something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Entity\Listener; use App\Entity\User; use Doctrine\ORM\Event\PreUpdateEventArgs; class UserListener { public function preUpdate(User $user, PreUpdateEventArgs $args) { // Put some code here } } |
The core is the preUpdate method. It will be called every time there will be a flush on User entity before making any updates.
The preUpdate method is only one of all methods you can use. You can find more informations here.
Remember that every event has its own peculiarities and limitations, check it in the doc.
Now you only need to check for changes using hasChangedField method passing the name of the property you want to check. Here it’s where all happen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace App\Entity\Listener; use App\Entity\User; use Doctrine\ORM\Event\PreUpdateEventArgs; class UserListener { public function preUpdate(User $user, PreUpdateEventArgs $args) { if ($args->hasChangedField('email')) { // Do stuff like sending mail, writing some logs, etc. } } } |
You don’t have to bother about entity change sets, units of works, etc. The hasChangedField method takes care of this for you and if you need/want to access the previous stored email address and the new one you simply need to call getOldValue and getNewValue methods.
I hope you found it useful and stay tuned for more tips.