Comment automatiser une action sur une entité lors de son ajout/update en db
Non pas que je sois fainéant, mais si une tâche peut se faire toute seule et m’éviter de l’oublier à certain endroit de mon code, je suis pour !
La tâche la plus récurrente est l’ajout de la date de création et celle d’update.
La solution classique se présenterait comme ceci:
$myEntity = new Entity();
$myEntity = $myEntity->setCreatedAt(new \DateTime());
Bon pas que ça va prendre beaucoup plus de ligne, mais c’est principalement le risque d’oubli qui est… très élevé… Surtout lors de l’update.
Je vais donc vous présenter une méthode permettant d’automatiser ces ajouts!
Création d’une entité de test
On va commencer par créer une entité de test
symfony console make:entity Test
Et nous allons créer deux champs:
- createdAt (datetime_immutable, nullable: true)
- updatedAt (datetime_immutable, nullable: true)
Certains vont se demander pourquoi le ‘createdAt’ peut être null et ils ont raison.
La réponse est simple, votre entité ne sera pas validée si vous ne lui donnez pas de date. L’action que nous allons définir ci-dessous s’exécute après cette vérification et donne donc une erreur.
La seconde chose à faire est de préciser au niveau de notre classe entité que celle-ci utilisera les events produit par doctrine à savoir:
- prePersist
- postPersist
- preUpdate
- postUpdate
- loadClassMetadata
- onClear
Et pour ce faire, nous allons simplement ajouter ceci:
#[ORM\HasLifecycleCallbacks]
Pour être précis, celà s’ajoute ici
#[ORM\Entity(repositoryClass: TestRepository::class)]
#[ORM\HasLifecycleCallbacks]
class Test
{}
Ajout des méthodes en fonction des callbacks
Notre entité étant désormais prête à écouter les callbacks envoyés par Doctrine, nous allons lui préciser les actions à effectuer en fonction de l’event.
Pour se faire il suffit simplement d’ajouter des fonctions dans notre entité en les précédant d’une annotation, par exemple, “#[ORM\PrePersist]”.
#[ORM\PrePersist]
public function setCreatedAtValue(): void
{
$this->createdAt = new \DateTimeImmutable();
}
#[ORM\PreUpdate]
public function setUpdatedAtValue(): void
{
$this->updatedAt = new \DateTimeImmutable();
}
La première s'exécutera avant le persist de votre entité en db. Idéal pour la date de création.
La seconde s'exécutera à chaque update de l’entité en db. Parfait pour la date d’édition ou un compteur d’update.
Grâce à ces deux petites fonctions vous n’aurez plus à vous souciez d’indiquer les dates lorsque vous gérer vos entités, tout est automatisé !