<?php
namespace App\Controller;
use App\Entity\Comment;
use App\Entity\Post;
use App\Entity\User;
use App\Form\CommentType;
use App\Repository\BlogRepository;
use App\Repository\PostRepository;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
use Pagerfanta\Doctrine\ORM\QueryAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class BlogController extends AbstractController
{
private ?string $layout;
public const PER_PAGE = 10;
public const RECENT_POSTS_COUNT = 3;
private PostRepository $postRepository;
public function __construct(PostRepository $postRepository)
{
$this->postRepository = $postRepository;
}
/**
* @Route("/blog", name="blog")
*
* @throws Exception
*/
public function index(Request $request, BlogRepository $blogRepository, PostRepository $postRepository): Response
{
$this->get_layout($request, $blogRepository);
$queryBuilder = $postRepository->getOrCreateQueryBuilder();
$pagerfanta = new Pagerfanta(new QueryAdapter($queryBuilder));
$pagerfanta->setMaxPerPage(self::PER_PAGE); // for test default value:10
$pagerfanta->setCurrentPage($request->query->get('page', 1));
$categories = $this->getCategoriesFromPost();
$recent = $this->getRecentPosts();
return $this->render('blog/index.html.twig', [
'controller_name' => 'BlogController',
'layout' => $this->layout,
'posts' => $pagerfanta,
'posts_recent' => $recent,
'categories' => array_unique($categories),
]);
}
/**
* @Route("blog/{slug}", name="blog_post")
*
* @throws Exception
*/
public function post(Request $request, PostRepository $postRepository, ManagerRegistry $registry): Response
{
$slug = $request->attributes->get('slug');
$post = $this->get_post($slug, $postRepository);
$comment = new Comment();
$form = $this->createForm(CommentType::class, $comment);
$form->handleRequest($request);
$recent = $this->getRecentPosts();
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $registry->getManager();
/**
* @var User $user
*/
$user = $this->getUser();
if (empty($user) || !in_array('ROLE_USER', $user->getRoles())) {
$this->addFlash('error', 'You need to be logged in to comment on this post');
return $this->redirectToRoute('blog_post', [
'slug' => $slug,
], Response::HTTP_SEE_OTHER);
}
$comment->setCreatedBy($user);
$comment->setPost($post);
$entityManager->persist($comment);
$entityManager->flush();
return $this->redirectToRoute('blog_post', ['slug' => $slug], Response::HTTP_SEE_OTHER);
}
return $this->render('blog/page.html.twig', [
'controller_name' => 'BlogController',
'post' => $this->get_post($slug, $postRepository),
'form' => $form->createView(),
'posts_recent' => $recent,
'categories' => $this->getCategoriesFromPost(),
] + $this->get_pagination($post, $postRepository));
}
public function get_post($slug, PostRepository $repository): ?Post
{
return $repository
->findOneBy(['slug' => $slug]);
}
public function get_pagination(Post $post, PostRepository $repository): array
{
$records = $repository->findAll();
$index = array_search($post->getId(), array_reduce($records, function ($memo, $record) {
array_push($memo, $record->getId());
return $memo;
}, []));
return [
'next' => @$records[($index + 1)] ?: null,
'prev' => @$records[$index - 1] ?: null,
];
}
public function get_layout(Request $request, BlogRepository $blogRepository): void
{
$route = $request->attributes->get('_route');
$this->layout = $blogRepository
->findOneBy(['slug' => $route])
->getTemplate()
->getLayout() ?: 'grid';
}
/**
* @throws Exception
*/
public function getCategoriesFromPost(): array
{
$categories = [];
foreach ($this->postRepository->findAll() as $post) {
$cat_iterator = $post->getCategories()->getIterator();
foreach ($cat_iterator as $cat) {
$categories[] = $cat;
}
}
return $categories;
}
public function getRecentPosts(): array
{
$posts = [];
foreach (array_reverse($this->postRepository->findAll()) as $index => $post) {
if ($index == self::RECENT_POSTS_COUNT) {
return $posts;
}
$content = $post->getContent();
$block_types = array_column($content, 'type');
$image_index = array_search('image', $block_types);
$posts[] = [
'image' => $image_index ? $content['blocks'][$image_index] : [
'data' => [
'file' => [
'url' => '',
],
],
],
'slug' => $post->getSlug(),
'title' => $post->getTitle(),
'created_at' => $post->getCreatedAt(),
];
}
return $posts;
}
}