1
0
Fork 0

Posts administration

This commit is contained in:
Ethanell 2021-01-16 17:48:59 +01:00
parent 1a03203d01
commit 513d5ff4d4
8 changed files with 188 additions and 13 deletions

View file

@ -19,8 +19,8 @@ class HomeController extends AbstractController
$repo = $this->getDoctrine()->getRepository(Post::class); $repo = $this->getDoctrine()->getRepository(Post::class);
return $this->render('home/index.html.twig', [ return $this->render('home/index.html.twig', [
'controller_name' => 'HomeController', 'controller_name' => 'HomeController',
'posts' => $repo->findBy(array(), array('publishedAt' => 'DESC'), 5, $page*5), 'posts' => $repo->getPublished($page*5, 5),
'pages' => round($repo->count(array())/5, 0, PHP_ROUND_HALF_UP), 'pages' => round(count($repo->getPublished())/5, 0, PHP_ROUND_HALF_UP),
'page' => $page 'page' => $page
]); ]);
} }

View file

@ -2,14 +2,17 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Category;
use App\Entity\Comment; use App\Entity\Comment;
use App\Entity\Post; use App\Entity\Post;
use App\Form\CommentType; use App\Form\CommentType;
use App\Form\PostType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\AsciiSlugger;
class PostController extends AbstractController class PostController extends AbstractController
{ {
@ -22,7 +25,7 @@ class PostController extends AbstractController
public function index(Request $request, string $slug): Response public function index(Request $request, string $slug): Response
{ {
$post = $this->getDoctrine()->getRepository(Post::class)->findOneBy(array('slug' => $slug)); $post = $this->getDoctrine()->getRepository(Post::class)->findOneBy(array('slug' => $slug));
$form = $this->formGenerator($post); $form = $this->commentFormGenerator($post);
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$comment = $form->getData(); $comment = $form->getData();
@ -31,7 +34,7 @@ class PostController extends AbstractController
$manager = $this->getDoctrine()->getManager(); $manager = $this->getDoctrine()->getManager();
$manager->persist($comment); $manager->persist($comment);
$manager->flush(); $manager->flush();
$form = $this->formGenerator($post); $form = $this->commentFormGenerator($post);
} }
return $this->render('post/index.html.twig', [ return $this->render('post/index.html.twig', [
'controller_name' => 'PostController', 'controller_name' => 'PostController',
@ -47,11 +50,82 @@ class PostController extends AbstractController
{ {
return $this->render('post/posts.html.twig', [ return $this->render('post/posts.html.twig', [
'controller_name' => 'PostController', '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 = new Comment();
$comment->setPost($post); $comment->setPost($post);

View file

@ -68,6 +68,10 @@ class Post
{ {
$this->comments = new ArrayCollection(); $this->comments = new ArrayCollection();
$this->categories = new ArrayCollection(); $this->categories = new ArrayCollection();
$date = new \DateTime();
$this->createdAt = $date;
$this->publishedAt = $date;
$this->updatedAt = $date;
} }
public function getId(): ?int public function getId(): ?int

36
src/Form/PostType.php Normal file
View file

@ -0,0 +1,36 @@
<?php
namespace App\Form;
use App\Entity\Category;
use App\Entity\Post;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->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
]);
}
}

View file

@ -19,6 +19,21 @@ class PostRepository extends ServiceEntityRepository
parent::__construct($registry, Post::class); 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 // * @return Post[] Returns an array of Post objects
// */ // */

View file

@ -1,7 +0,0 @@
{% extends 'admin/base-admin.html.twig' %}
{% block title %}Hello AdminController!{% endblock %}
{% block body %}
{% endblock %}

View file

@ -0,0 +1,34 @@
{% extends 'admin/base-admin.html.twig' %}
{% block title %}{{ title }}{% endblock %}
{% block body %}
<div class="container-fluid">
<h1>{{ title }}</h1>
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="form-outline">
{{ form_widget(form.title) }}
{{ form_label(form.title, null, {'label_attr': {'class': 'form-label'}}) }}
</div>
<div class="form-outline">
{{ form_widget(form.description) }}
{{ form_label(form.description, null, {'label_attr': {'class': 'form-label'}}) }}
</div>
<div class="form-outline">
{{ form_widget(form.content) }}
{{ form_label(form.content, null, {'label_attr': {'class': 'form-label'}}) }}
</div>
<div class="form-outline">
{{ form_label(form.publishedAt) }}
{{ form_widget(form.publishedAt) }}
</div>
{{ form_row(form.categories) }}
{{ form_row(form.save) }}
{{ form_end(form) }}
</div>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends 'admin/base-admin.html.twig' %}
{% block title %}Administration - Posts{% endblock %}
{% block body %}
<div class="container-fluid">
{% for post in posts %}
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text">{{ post.description }}</p>
<a href="{{ path('post-remove', {slug: post.slug}) }}" class="btn btn-danger">Delete</a>
<a href="{{ path('post-edit', {slug: post.slug}) }}" class="btn btn-primary">Edit</a>
</div>
<div class="card-footer text-muted">{{ post.publishedAt.format('Y-m-d H:i:s') }}</div>
</div>
{% endfor %}
</div>
{% endblock %}