From 513d5ff4d43134d59c81585cac40596b4ed82a5d Mon Sep 17 00:00:00 2001 From: flifloo Date: Sat, 16 Jan 2021 17:48:59 +0100 Subject: [PATCH] Posts administration --- src/Controller/HomeController.php | 4 +- src/Controller/PostController.php | 82 +++++++++++++++++++++++++++-- src/Entity/Post.php | 4 ++ src/Form/PostType.php | 36 +++++++++++++ src/Repository/PostRepository.php | 15 ++++++ templates/admin/posts.html.twig | 7 --- templates/post/posts-form.html.twig | 34 ++++++++++++ templates/post/posts.html.twig | 19 +++++++ 8 files changed, 188 insertions(+), 13 deletions(-) create mode 100644 src/Form/PostType.php delete mode 100644 templates/admin/posts.html.twig create mode 100644 templates/post/posts-form.html.twig create mode 100644 templates/post/posts.html.twig diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index 3f8b996..55a4425 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -19,8 +19,8 @@ class HomeController extends AbstractController $repo = $this->getDoctrine()->getRepository(Post::class); return $this->render('home/index.html.twig', [ 'controller_name' => 'HomeController', - 'posts' => $repo->findBy(array(), array('publishedAt' => 'DESC'), 5, $page*5), - 'pages' => round($repo->count(array())/5, 0, PHP_ROUND_HALF_UP), + 'posts' => $repo->getPublished($page*5, 5), + 'pages' => round(count($repo->getPublished())/5, 0, PHP_ROUND_HALF_UP), 'page' => $page ]); } diff --git a/src/Controller/PostController.php b/src/Controller/PostController.php index 18b8cce..7446268 100644 --- a/src/Controller/PostController.php +++ b/src/Controller/PostController.php @@ -2,14 +2,17 @@ namespace App\Controller; +use App\Entity\Category; use App\Entity\Comment; use App\Entity\Post; use App\Form\CommentType; +use App\Form\PostType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\String\Slugger\AsciiSlugger; class PostController extends AbstractController { @@ -22,7 +25,7 @@ class PostController extends AbstractController public function index(Request $request, string $slug): Response { $post = $this->getDoctrine()->getRepository(Post::class)->findOneBy(array('slug' => $slug)); - $form = $this->formGenerator($post); + $form = $this->commentFormGenerator($post); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $comment = $form->getData(); @@ -31,7 +34,7 @@ class PostController extends AbstractController $manager = $this->getDoctrine()->getManager(); $manager->persist($comment); $manager->flush(); - $form = $this->formGenerator($post); + $form = $this->commentFormGenerator($post); } return $this->render('post/index.html.twig', [ 'controller_name' => 'PostController', @@ -47,11 +50,82 @@ class PostController extends AbstractController { return $this->render('post/posts.html.twig', [ 'controller_name' => 'PostController', - 'posts' => $this->getDoctrine()->getRepository(Post::class)->findAll() + 'posts' => $this->getDoctrine()->getRepository(Post::class)->findBy(array(), array('publishedAt' => 'DESC')) ]); } - private function formGenerator(Post $post) : FormInterface + /** + * @Route("/admin/posts/add", name="post-add") + * @param Request $request + * @return Response + */ + public function add(Request $request): Response + { + $post = new Post(); + $form = $this->createForm(PostType::class, $post); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $post = $form->getData(); + $post->setSlug((new AsciiSlugger())->slug($post->getTitle())); + $manager = $this->getDoctrine()->getManager(); + $manager->persist($post); + $manager->flush(); + return $this->redirectToRoute('posts'); + } + return $this->render('post/posts-form.html.twig', [ + 'controller_name' => 'PostController', + 'form' => $form->createView(), + 'title' => 'Add new post' + ]); + } + + /** + * @Route("/admin/posts/edit/{slug}", name="post-edit") + * @param Request $request + * @param string $slug + * @return Response + */ + public function edit(Request $request, string $slug): Response + { + $manager = $this->getDoctrine()->getManager(); + $post = $manager->getRepository(Post::class)->findOneBy(array('slug' => $slug)); + if (!$post) { + throw $this->createNotFoundException("Post not found"); + } + $form = $this->createForm(PostType::class, $post); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $post = $form->getData(); + $post->setUpdatedAt(new \DateTime()); + $post->setSlug((new AsciiSlugger())->slug($post->getTitle())); + $manager->flush(); + return $this->redirectToRoute('posts'); + } + return $this->render('post/posts-form.html.twig', [ + 'controller_name' => 'PostController', + 'form' => $form->createView(), + 'title' => 'Edit '.$post->getTitle() + ]); + } + + /** + * @Route("/admin/posts/remove/{slug}", name="post-remove") + * @param string $slug + * @return Response + */ + public function remove(string $slug): Response + { + $manager = $this->getDoctrine()->getManager(); + $post = $manager->getRepository(Post::class)->findOneBy(array('slug' => $slug)); + if (!$post) { + throw $this->createNotFoundException("Post not found"); + } + $manager->remove($post); + $manager->flush(); + return $this->redirectToRoute('posts'); + } + + private function commentFormGenerator(Post $post) : FormInterface { $comment = new Comment(); $comment->setPost($post); diff --git a/src/Entity/Post.php b/src/Entity/Post.php index 948b276..3b51661 100644 --- a/src/Entity/Post.php +++ b/src/Entity/Post.php @@ -68,6 +68,10 @@ class Post { $this->comments = new ArrayCollection(); $this->categories = new ArrayCollection(); + $date = new \DateTime(); + $this->createdAt = $date; + $this->publishedAt = $date; + $this->updatedAt = $date; } public function getId(): ?int diff --git a/src/Form/PostType.php b/src/Form/PostType.php new file mode 100644 index 0000000..3a6807b --- /dev/null +++ b/src/Form/PostType.php @@ -0,0 +1,36 @@ +add('title', TextType::class, ['attr' => ['class' => 'form-control']]) + ->add('description', TextType::class, ['attr' => ['class' => 'form-control']]) + ->add('content', TextareaType::class, ['attr' => ['class' => 'form-control']]) + ->add('publishedAt', DateTimeType::class, ['attr' => ['class' => 'form-control']]) + ->add('categories', EntityType::class, ['attr' => ['class' => 'form-control'], 'class' => Category::class, 'choice_label' => 'name', 'multiple' => true, 'expanded' => true, 'by_reference' => false]) + ->add('save', SubmitType::class, ['attr' => ['class' => 'btn btn-primary btn-block']]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Post::class + ]); + } +} diff --git a/src/Repository/PostRepository.php b/src/Repository/PostRepository.php index e5bbf8a..a974a86 100644 --- a/src/Repository/PostRepository.php +++ b/src/Repository/PostRepository.php @@ -19,6 +19,21 @@ class PostRepository extends ServiceEntityRepository parent::__construct($registry, Post::class); } + public function getPublished(int $offset = null, int $max = null) { + $q = $this->createQueryBuilder("p") + ->andWhere('p.publishedAt <= :now') + ->setParameter('now', new \DateTime()) + ->orderBy('p.publishedAt', 'DESC'); + if ($offset) { + $q->setFirstResult($offset); + } + if ($max) { + $q->setMaxResults($max); + } + return $q->getQuery() + ->getResult(); + } + // /** // * @return Post[] Returns an array of Post objects // */ diff --git a/templates/admin/posts.html.twig b/templates/admin/posts.html.twig deleted file mode 100644 index 2b9eca2..0000000 --- a/templates/admin/posts.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'admin/base-admin.html.twig' %} - -{% block title %}Hello AdminController!{% endblock %} - -{% block body %} - -{% endblock %} diff --git a/templates/post/posts-form.html.twig b/templates/post/posts-form.html.twig new file mode 100644 index 0000000..48209c6 --- /dev/null +++ b/templates/post/posts-form.html.twig @@ -0,0 +1,34 @@ +{% extends 'admin/base-admin.html.twig' %} +{% block title %}{{ title }}{% endblock %} + +{% block body %} +
+

{{ title }}

+ {{ form_start(form) }} + {{ form_errors(form) }} +
+ {{ form_widget(form.title) }} + {{ form_label(form.title, null, {'label_attr': {'class': 'form-label'}}) }} +
+ +
+ {{ form_widget(form.description) }} + {{ form_label(form.description, null, {'label_attr': {'class': 'form-label'}}) }} +
+ +
+ {{ form_widget(form.content) }} + {{ form_label(form.content, null, {'label_attr': {'class': 'form-label'}}) }} +
+ +
+ {{ form_label(form.publishedAt) }} + {{ form_widget(form.publishedAt) }} +
+ + {{ form_row(form.categories) }} + + {{ form_row(form.save) }} + {{ form_end(form) }} +
+{% endblock %} diff --git a/templates/post/posts.html.twig b/templates/post/posts.html.twig new file mode 100644 index 0000000..f4708ce --- /dev/null +++ b/templates/post/posts.html.twig @@ -0,0 +1,19 @@ +{% extends 'admin/base-admin.html.twig' %} + +{% block title %}Administration - Posts{% endblock %} + +{% block body %} +
+ {% for post in posts %} +
+
+
{{ post.title }}
+

{{ post.description }}

+ Delete + Edit +
+ +
+ {% endfor %} +
+{% endblock %}