Jelajahi Sumber

Suppression des tags orphelins

Sangfroid 4 minggu lalu
induk
melakukan
a8c7424e02

+ 10 - 3
src/Controller/ArticleController.php

@@ -5,6 +5,7 @@ namespace App\Controller;
 use App\Entity\Article;
 use App\Form\ArticleType;
 use App\Repository\ArticleRepository;
+use App\Service\TagService;
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\DependencyInjection\Attribute\Target;
@@ -31,7 +32,8 @@ final class ArticleController extends AbstractController
         Request $request,
         EntityManagerInterface $entityManager,
         #[Target('blog_publishing')]
-        WorkflowInterface $workflow
+        WorkflowInterface $workflow,
+        TagService $tagService
     ): Response
     {
         $article = new Article($this->getUser());
@@ -58,6 +60,8 @@ final class ArticleController extends AbstractController
             $entityManager->persist($article);
             $entityManager->flush();
 
+            $tagService->clearOrphansTags();
+
             return $this->redirectToRoute('app_article_show', ['id' => $article->getId()], Response::HTTP_SEE_OTHER);
         }
 
@@ -83,7 +87,8 @@ final class ArticleController extends AbstractController
         Article $article,
         EntityManagerInterface $entityManager,
         #[Target('blog_publishing')]
-        WorkflowInterface $workflow
+        WorkflowInterface $workflow,
+        TagService $tagService
     ): Response
     {
         $transitions = $workflow->getEnabledTransitions($article);
@@ -103,8 +108,10 @@ final class ArticleController extends AbstractController
             if ($publicationChoice !== null) {
                 $workflow->apply($article, $publicationChoice);
             }
-
+            
             $entityManager->flush();
+            
+            $tagService->clearOrphansTags();
 
             return $this->redirectToRoute('app_article_show', ['id' => $article->getId()], Response::HTTP_SEE_OTHER);
         }

+ 5 - 2
src/Entity/Article.php

@@ -45,7 +45,7 @@ class Article
     /**
      * @var Collection<int, Tag>
      */
-    #[ORM\ManyToMany(targetEntity: Tag::class)]
+    #[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'articles')]
     private Collection $tags;
 
     public function __construct(User $author)
@@ -144,6 +144,7 @@ class Article
     {
         if (!$this->tags->contains($tag)) {
             $this->tags->add($tag);
+            $tag->addArticle($this);
         }
 
         return $this;
@@ -151,7 +152,9 @@ class Article
 
     public function removeTag(Tag $tag): static
     {
-        $this->tags->removeElement($tag);
+        if ($this->tags->removeElement($tag)) {
+            $tag->removeArticle($this);
+        }
 
         return $this;
     }

+ 37 - 0
src/Entity/Tag.php

@@ -3,6 +3,8 @@
 namespace App\Entity;
 
 use App\Repository\TagRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 
 #[ORM\Entity(repositoryClass: TagRepository::class)]
@@ -16,6 +18,17 @@ class Tag implements \Stringable
     #[ORM\Column(length: 50)]
     private ?string $name = null;
 
+    /**
+     * @var Collection<int, Article>
+     */
+    #[ORM\ManyToMany(targetEntity: Article::class, mappedBy: 'tags')]
+    private Collection $articles;
+
+    public function __construct()
+    {
+        $this->articles = new ArrayCollection();
+    }
+
     public function __toString(): string
     {
         return $this->getName();
@@ -37,4 +50,28 @@ class Tag implements \Stringable
 
         return $this;
     }
+
+    /**
+     * @return Collection<int, Article>
+     */
+    public function getArticles(): Collection
+    {
+        return $this->articles;
+    }
+
+    public function addArticle(Article $article): static
+    {
+        if (!$this->articles->contains($article)) {
+            $this->articles->add($article);
+        }
+
+        return $this;
+    }
+
+    public function removeArticle(Article $article): static
+    {
+        $this->articles->removeElement($article);
+
+        return $this;
+    }
 }

+ 10 - 0
src/Repository/TagRepository.php

@@ -40,4 +40,14 @@ class TagRepository extends ServiceEntityRepository
     //            ->getOneOrNullResult()
     //        ;
     //    }
+
+    public function findOrphanTags(): array
+    {
+        return $this->createQueryBuilder('t')
+            ->leftJoin('t.articles', 'a')
+            ->where('a.id IS NULL')
+            ->getQuery()
+            ->getResult()
+        ;
+    }
 }

+ 27 - 0
src/Service/TagService.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Service;
+
+use App\Repository\TagRepository;
+use Doctrine\ORM\EntityManagerInterface;
+
+class TagService
+{
+    public function __construct(
+        protected readonly TagRepository $tagRepository,
+        protected EntityManagerInterface $em
+    )
+    {
+        
+    }
+
+    public function clearOrphansTags(): void
+    {
+        $tags = $this->tagRepository->findOrphanTags();
+        foreach($tags as $tag) {
+            $this->em->remove($tag);
+        }
+        dump($tags);
+        $this->em->flush();
+    }
+}