Tester si une entité Doctrine a déjà été persistée en base

Publié le 11/09/2018 • Mis à jour le 23/09/2018


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

Ce code est appelé d'une fonction action d'un controller standard Symfony 4.1. (qui étend donc la classe Symfony Symfony\Bundle\FrameworkBundle\Controller\Controller) :


<?php declare(strict_types=1);

namespace App\Controller\Snippet;

use App\Entity\Article;
use App\Entity\ArticleType;
use App\Repository\ArticleTypeRepository;
use Doctrine\Bundle\DoctrineBundle\Registry;

/**
 * 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.
 */
trait Snippet2Trait
{
    public function snippet2(): void
    {
        // Get doctrine manager (From a Symfony >4.2 controller)
        $doctrine = $this->getDoctrine();
        if (!$doctrine instanceof Registry) {
            throw new \RuntimeException("Houston, We Have a Problem. 💥");
        }

        $manager = $doctrine->getManager();
        $article = new Article(); // create a fresh Doctrine object
        $isPersisted = $manager->contains($article);
        echo $isPersisted ? 'true' : 'false'; // returns false

        // Set minimum database constraints so the entity can be persisted
        $repo = $manager->getRepository(ArticleType::class);
        if (!$repo instanceof ArticleTypeRepository) {
            throw new \RuntimeException('Doctrine repository not found.');
        }
        $article->setType($repo->getArticleType());
        $article->setActive(false);
        // $manager->persist($article); // persist in database
        // (I will not persist because I don't want to pollute my database
        // but you've got the spirit!)
        $manager->flush();

        $isPersisted = $manager->contains($article);
        echo PHP_EOL;
        echo $isPersisted ? 'true' : 'false'; // would returns true without the line commented.

        // That's it! 😁
    }
}

 Exécuter le snippet  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  Plus sur Stackoverflow  Snippet aléatoire

<?php declare(strict_types=1);

namespace App\Tests\Controller\Snippets;

use App\Entity\Article;
use App\Entity\ArticleType;
use App\Repository\ArticleTypeRepository;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @covers Snippet2Trait
 */
final class Snippet2Test extends KernelTestCase
{
    private Registry $doctrine;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->doctrine = self::$container->get('doctrine');
    }

    /**
     * @covers Snippet2Trait::snippet2
     */
    public function testSnippet2(): void
    {
        $projectDir = self::$container->getParameter('kernel.project_dir');
        self::assertFileExists($projectDir.'/src/Controller/Snippet/Snippet2Trait.php');

        $manager = $this->doctrine->getManager();
        $article = new Article();
        self::assertFalse($manager->contains($article));

        $repo = $manager->getRepository(ArticleType::class);
        if (!$repo instanceof ArticleTypeRepository) {
            throw new \RuntimeException('Doctrine repository not found.');
        }
        $article->setType($repo->getArticleType());
        $article->setActive(false);
        $manager->persist($article);
        $manager->flush();
        self::assertTrue($manager->contains($article));

        $manager->remove($article);
        $manager->flush();
        self::assertFalse($manager->contains($article));
    }
}