src/Controller/Admin/BlogController.php line 55

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace App\Controller\Admin;
  11. use App\Entity\Post;
  12. use App\Form\PostType;
  13. use App\Repository\PostRepository;
  14. use App\Security\PostVoter;
  15. use Doctrine\ORM\EntityManagerInterface;
  16. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  17. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  18. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\Response;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. /**
  23.  * Controller used to manage blog contents in the backend.
  24.  *
  25.  * Please note that the application backend is developed manually for learning
  26.  * purposes. However, in your real Symfony application you should use any of the
  27.  * existing bundles that let you generate ready-to-use backends without effort.
  28.  * See https://symfony.com/bundles
  29.  *
  30.  * @author Ryan Weaver <weaverryan@gmail.com>
  31.  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  32.  */
  33. #[Route('/admin/post'), IsGranted('ROLE_ADMIN')]
  34. class BlogController extends AbstractController
  35. {
  36.     /**
  37.      * Lists all Post entities.
  38.      *
  39.      * This controller responds to two different routes with the same URL:
  40.      *   * 'admin_post_index' is the route with a name that follows the same
  41.      *     structure as the rest of the controllers of this class.
  42.      *   * 'admin_index' is a nice shortcut to the backend homepage. This allows
  43.      *     to create simpler links in the templates. Moreover, in the future we
  44.      *     could move this annotation to any other controller while maintaining
  45.      *     the route name and therefore, without breaking any existing link.
  46.      */
  47.     #[
  48.         Route('/'methods: ['GET'], name'admin_index'),
  49.         Route('/'methods: ['GET'], name'admin_post_index'),
  50.     ]
  51.     public function index(PostRepository $posts): Response
  52.     {
  53.         $authorPosts $posts->findBy(['author' => $this->getUser()], ['publishedAt' => 'DESC']);
  54.         return $this->render('admin/blog/index.html.twig', ['posts' => $authorPosts]);
  55.     }
  56.     /**
  57.      * Creates a new Post entity.
  58.      *
  59.      * NOTE: the Method annotation is optional, but it's a recommended practice
  60.      * to constraint the HTTP methods each controller responds to (by default
  61.      * it responds to all methods).
  62.      */
  63.     #[Route('/new'methods: ['GET''POST'], name'admin_post_new')]
  64.     public function new(Request $requestEntityManagerInterface $entityManager): Response
  65.     {
  66.         $post = new Post();
  67.         $post->setAuthor($this->getUser());
  68.         // See https://symfony.com/doc/current/form/multiple_buttons.html
  69.         $form $this->createForm(PostType::class, $post)
  70.             ->add('saveAndCreateNew'SubmitType::class);
  71.         $form->handleRequest($request);
  72.         // the isSubmitted() method is completely optional because the other
  73.         // isValid() method already checks whether the form is submitted.
  74.         // However, we explicitly add it to improve code readability.
  75.         // See https://symfony.com/doc/current/forms.html#processing-forms
  76.         if ($form->isSubmitted() && $form->isValid()) {
  77.             $entityManager->persist($post);
  78.             $entityManager->flush();
  79.             // Flash messages are used to notify the user about the result of the
  80.             // actions. They are deleted automatically from the session as soon
  81.             // as they are accessed.
  82.             // See https://symfony.com/doc/current/controller.html#flash-messages
  83.             $this->addFlash('success''post.created_successfully');
  84.             if ($form->get('saveAndCreateNew')->isClicked()) {
  85.                 return $this->redirectToRoute('admin_post_new');
  86.             }
  87.             return $this->redirectToRoute('admin_post_index');
  88.         }
  89.         return $this->render('admin/blog/new.html.twig', [
  90.             'post' => $post,
  91.             'form' => $form->createView(),
  92.         ]);
  93.     }
  94.     /**
  95.      * Finds and displays a Post entity.
  96.      */
  97.     #[Route('/{id<\d+>}'methods: ['GET'], name'admin_post_show')]
  98.     public function show(Post $post): Response
  99.     {
  100.         // This security check can also be performed
  101.         // using a PHP attribute: #[IsGranted('show', subject: 'post', message: 'Posts can only be shown to their authors.')]
  102.         $this->denyAccessUnlessGranted(PostVoter::SHOW$post'Posts can only be shown to their authors.');
  103.         return $this->render('admin/blog/show.html.twig', [
  104.             'post' => $post,
  105.         ]);
  106.     }
  107.     /**
  108.      * Displays a form to edit an existing Post entity.
  109.      */
  110.     #[Route('/{id<\d+>}/edit'methods: ['GET''POST'], name'admin_post_edit')]
  111.     #[IsGranted('edit'subject'post'message'Posts can only be edited by their authors.')]
  112.     public function edit(Request $requestPost $postEntityManagerInterface $entityManager): Response
  113.     {
  114.         $form $this->createForm(PostType::class, $post);
  115.         $form->handleRequest($request);
  116.         if ($form->isSubmitted() && $form->isValid()) {
  117.             $entityManager->flush();
  118.             $this->addFlash('success''post.updated_successfully');
  119.             return $this->redirectToRoute('admin_post_edit', ['id' => $post->getId()]);
  120.         }
  121.         return $this->render('admin/blog/edit.html.twig', [
  122.             'post' => $post,
  123.             'form' => $form->createView(),
  124.         ]);
  125.     }
  126.     /**
  127.      * Deletes a Post entity.
  128.      */
  129.     #[Route('/{id}/delete'methods: ['POST'], name'admin_post_delete')]
  130.     #[IsGranted('delete'subject'post')]
  131.     public function delete(Request $requestPost $postEntityManagerInterface $entityManager): Response
  132.     {
  133.         if (!$this->isCsrfTokenValid('delete'$request->request->get('token'))) {
  134.             return $this->redirectToRoute('admin_post_index');
  135.         }
  136.         // Delete the tags associated with this blog post. This is done automatically
  137.         // by Doctrine, except for SQLite (the database used in this application)
  138.         // because foreign key support is not enabled by default in SQLite
  139.         $post->getTags()->clear();
  140.         $entityManager->remove($post);
  141.         $entityManager->flush();
  142.         $this->addFlash('success''post.deleted_successfully');
  143.         return $this->redirectToRoute('admin_post_index');
  144.     }
  145. }