It may happen that, in a project, you need a history of actions on a particular table (create, update, delete). For example, you have a table containing rights and you would like to know who changed what and when.
For this, a library called auditor-bundle, developed by Damien Harper, provides a very simple solution to this need.
You can consult the full documentation here: Auditor Documentation.
Library Installation
To install the library, use the following command:
composer require damienharper/auditor-bundleAfter creating a User table (which contains only one username field), we will create a table for rights:
<?php
namespace App\Entity;
use App\Repository\PermissionRepository;
use DH\Auditor\Provider\Doctrine\Auditing\Annotation\Auditable;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: PermissionRepository::class)]
#[Auditable]
class Permission
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'permissions')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
#[ORM\Column(length: 20)]
private ?string $role = null;
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
public function getRole(): ?string
{
return $this->role;
}
public function setRole(string $role): static
{
$this->role = $role;
return $this;
}
}Audit of Changes
Note the #[Auditable] attribute which indicates to the library that this table should be audited.
After running your migration, a new permission_audit table will be created, and it will store all the actions performed on the permission table.
Test with a Controller
Let’s create a controller to test the operation (do not reproduce this in production):
<?php
namespace App\Controller;
use App\Entity\Permission;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
class AuditController extends AbstractController
{
#[Route('/audit', name: 'app_audit')]
public function index(EntityManagerInterface $entityManager, Security $security): Response
{
$user = new User();
$user->setUsername('admin');
$entityManager->persist($user);
$entityManager->flush();
$security->login($user);
$permission = new Permission();
$permission->setUser($user);
$permission->setRole('ADMIN');
$entityManager->persist($permission);
$entityManager->flush();
$permission->setRole('USER');
$entityManager->flush();
$entityManager->remove($permission);
$entityManager->flush();
return $this->render('audit/index.html.twig', []);
}
}Result in the Audit Table
After visiting the /audit page, here is a preview of what the permission_audit table contains:

The important column is diffs, a JSON containing the differences between two versions of the entity.
Happy auditing!
