Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

Example below acts like pre-update database triggers where we log all activities made by users for auditing, reporting or security reasons. If someone changes the value from X to Y in a controller or a service class, this event listener records everything in another table in database.


Listeners.yml


services:
application_backend.event_listener.user_entity_audit:
class: Application\BackendBundle\EventListener\UserEntityAuditListener
arguments: [ @security.context ]
tags:
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: postFlush }

UserEntityAuditListener


namespace Application\BackendBundle\EventListener;

use Application\BackendBundle\Entity\User;
use Application\BackendBundle\Entity\UserAudit;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\Security\Core\SecurityContextInterface;

class UserEntityAuditListener
{
private $securityContext;
private $fields = ['username', 'password'];
private $audit = [];

public function __construct(SecurityContextInterface $securityContextInterface)
{
$this->securityContext = $securityContextInterface;
}

public function preUpdate(PreUpdateEventArgs $args) // OR LifecycleEventArgs
{
$entity = $args->getEntity();

if ($entity instanceof User) {
foreach ($this->fields as $field) {
if ($args->getOldValue($field) != $args->getNewValue($field)) {
$audit = new UserAudit();
$audit->setField($field);
$audit->setOld($args->getOldValue($field));
$audit->setNew($args->getNewValue($field));
$audit->setUser($this->securityContext->getToken()->getUsername());

$this->audit[] = $audit;
}
}
}
}

public function postFlush(PostFlushEventArgs $args)
{
if (! empty($this->audit)) {
$em = $args->getEntityManager();

foreach ($this->audit as $audit) {
$em->persist($audit);
}

$this->audit = [];
$em->flush();
}
}
}