diff --git a/src/AppBundle/Controller/Admin/BlogController.php b/src/AppBundle/Controller/Admin/BlogController.php index 903a69c76..5146b4153 100644 --- a/src/AppBundle/Controller/Admin/BlogController.php +++ b/src/AppBundle/Controller/Admin/BlogController.php @@ -12,6 +12,7 @@ namespace AppBundle\Controller\Admin; use AppBundle\Entity\Post; +use AppBundle\Entity\Tag; use AppBundle\Form\PostType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; @@ -146,7 +147,10 @@ public function editAction(Post $post, Request $request) if ($form->isSubmitted() && $form->isValid()) { $post->setSlug($this->get('slugger')->slugify($post->getTitle())); - $entityManager->flush(); + $entityManager->transactional(function ($entityManager) { + $entityManager->flush(); + $this->getDoctrine()->getRepository(Tag::class)->cleanUnusedTags(); + }); $this->addFlash('success', 'post.updated_successfully'); @@ -176,14 +180,14 @@ public function deleteAction(Request $request, Post $post) } $entityManager = $this->getDoctrine()->getManager(); - - // Delete the tags associated with this blog post. This is done automatically - // by Doctrine, except for SQLite (the database used in this application) - // because foreign key support is not enabled by default in SQLite - $post->getTags()->clear(); - - $entityManager->remove($post); - $entityManager->flush(); + $entityManager->transactional(function ($entityManager) use ($post) { + // Delete the tags associated with this blog post. This is done automatically + // by Doctrine, except for SQLite (the database used in this application) + // because foreign key support is not enabled by default in SQLite + $post->getTags()->clear(); + $entityManager->remove($post); + $this->getDoctrine()->getRepository(Tag::class)->cleanUnusedTags(); + }); $this->addFlash('success', 'post.deleted_successfully'); diff --git a/src/AppBundle/Entity/Tag.php b/src/AppBundle/Entity/Tag.php index 69bbe93a3..fbe14ca4c 100644 --- a/src/AppBundle/Entity/Tag.php +++ b/src/AppBundle/Entity/Tag.php @@ -5,7 +5,7 @@ use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Entity() + * @ORM\Entity(repositoryClass="AppBundle\Repository\TagRepository") * @ORM\Table(name="symfony_demo_tag") * * Defines the properties of the Tag entity to represent the post tags. diff --git a/src/AppBundle/Repository/TagRepository.php b/src/AppBundle/Repository/TagRepository.php new file mode 100644 index 000000000..419744403 --- /dev/null +++ b/src/AppBundle/Repository/TagRepository.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace AppBundle\Repository; + +use AppBundle\Entity\Post; +use AppBundle\Entity\Tag; +use Doctrine\ORM\EntityRepository; +use Doctrine\ORM\Query\ResultSetMapping; + +/** + * This custom Doctrine repository contains some methods to about tags. + * + * See http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes + */ +class TagRepository extends EntityRepository +{ + /** + * Remove unused Tag from the Database. + */ + public function cleanUnusedTags() + { + $joinTable = $this->getEntityManager()->getClassMetadata(Post::class)->getAssociationMapping('tags')['joinTable']['name']; + $tagTable = $this->getClassMetadata()->getTableName(); + $unused_tags = $this->getEntityManager()->createNativeQuery(" + DELETE FROM `$tagTable` WHERE id IN + ( + SELECT t.id FROM `$tagTable` t + LEFT JOIN `$joinTable` j ON j.tag_id = t.id + WHERE j.tag_id IS NULL + ) + ", new ResultSetMapping())->execute(); + } +}