Calcul d'une propriété virtuelle d'une entité Doctrine suite à son chargement
Publié le 15/05/2021 • Actualisé le 15/05/2021
Dans ce bout de code, nous voyons comment calculer la valeur d'un champ virtuel d'une entité Doctrine juste après con chargement. Nous utilisons l'événement Doctrine
postLoad
. Bien sûr, ici un simple accesseur suffirait. L'écouteur
d'événements est indispensable quand on a besoin d'injecter un service comme
c'est fait dans cet exemple (même si je n'utilise pas le service injecté).
La propriété iri est déclarée comme ceci :
Retrouvez un squelette d'écouteur d'événements Doctrine complet dans ce
snippet.
/**
* Propriété pour le snippet 147.
*
* @var ?string IRI API Platform de la ressource (example factice)
*/
protected ?string $iri = null;
<?php
/** @noinspection PhpPropertyOnlyWrittenInspection */
// src/Doctrine/Listener/ArticleListener.php
declare(strict_types=1);
namespace App\Doctrine\Listener;
use App\Entity\Article;
final class ArticleListener
{
/**
* This is a dummy example.
*/
public function postLoad(Article $article): void
{
$article->setIri('/articles/'.$article->getId());
}
}
En bonus, le snippet permettant d'utiliser ce code : 🎉<?php
declare(strict_types=1);
namespace App\Controller\Snippet;
use App\Repository\ArticleRepository;
/**
* J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
* Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
* ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
* Les services sont injectés dans le constructeur du contrôleur principal.
*
* @property ArticleRepository $articleRepo
*/
trait Snippet147Trait
{
/**
* @noinspection OneTimeUseVariablesInspection
*/
public function snippet147(): void
{
$article = $this->articleRepo->findById(147);
echo $article->getIri(); // The IRI is computed in the Article listener
// That's it! 😁
}
}
Exécuter le snippet ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫ Plus sur Stackoverflow Lire la doc Plus sur le web
<?php
declare(strict_types=1);
namespace App\Tests\Integration\Controller\Snippets;
use App\Repository\ArticleRepository;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* @see Snippet147Trait
*/
final class Snippet147Test extends KernelTestCase
{
private ArticleRepository $articleRepo;
protected function setUp(): void
{
$this->articleRepo = self::getContainer()->get(ArticleRepository::class);
}
/**
* @see ArticleListener::postLoad
*/
public function testSnippet147(): void
{
$article = $this->articleRepo->findById(147);
self::assertSame('/articles/147', $article->getIri());
}
}