feat(controller): add post lists controller
This commit is contained in:
8
src/Controller/DetailPostController.php
Normal file
8
src/Controller/DetailPostController.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
class DetailPostController
|
||||
{
|
||||
|
||||
}
|
||||
56
src/Controller/ListPostController.php
Normal file
56
src/Controller/ListPostController.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Repository\Post\PostRepository;
|
||||
use App\Utils\Paginator\Paginator;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
final class ListPostController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly int $pageSize,
|
||||
private readonly int $maxVisiblePages,
|
||||
private readonly PostRepository $postRepository,
|
||||
private readonly Paginator $paginator,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/', name: 'default')]
|
||||
public function default(): Response
|
||||
{
|
||||
return $this->forward(ListPostController::class . '::pageList', ['page' => 1]);
|
||||
}
|
||||
|
||||
#[Route('/posts/{page}', name: 'page_list', requirements: ['page' => '\d+'], defaults: ['page' => 1])]
|
||||
public function pageList(int $page): Response
|
||||
{
|
||||
$totalPages = (int) ceil($this->postRepository->count([]) / $this->pageSize); /* TODO: tohle by si zaslouzilo asi cache */
|
||||
|
||||
if ($totalPages === 0) {
|
||||
$this->logger->error('No posts found. Try run brilo:refresh-database command.');
|
||||
throw new NotFoundHttpException('No posts found.');
|
||||
}
|
||||
|
||||
if ($page === 0) {
|
||||
return $this->redirectToRoute('page_list', ['page' => 1]);
|
||||
}
|
||||
|
||||
// If page number is out of range, redirect to the last page.
|
||||
if ($page > $totalPages) {
|
||||
return $this->redirectToRoute('page_list', ['page' => $totalPages]);
|
||||
}
|
||||
|
||||
$posts = $this->postRepository->getPaginatedPosts($page, $this->pageSize);
|
||||
|
||||
return $this->render('list_post/list.html.twig', [
|
||||
'posts' => $posts,
|
||||
'page' => $this->paginator->getVisiblePages($page, $totalPages, $this->maxVisiblePages),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,20 @@ class PostRepository extends ServiceEntityRepository
|
||||
{
|
||||
parent::__construct($registry, Post::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
* @return array<Post>
|
||||
*/
|
||||
public function getPaginatedPosts(int $page, int $pageSize): array
|
||||
{
|
||||
$query = $this->createQueryBuilder('p')
|
||||
->orderBy('p.id', 'DESC')
|
||||
->setFirstResult(($page - 1) * $pageSize)
|
||||
->setMaxResults($pageSize)
|
||||
->getQuery();
|
||||
|
||||
return $query->getResult();
|
||||
}
|
||||
}
|
||||
|
||||
45
src/Utils/Paginator/Paginator.php
Normal file
45
src/Utils/Paginator/Paginator.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Utils\Paginator;
|
||||
|
||||
class Paginator
|
||||
{
|
||||
/**
|
||||
* Determinate which pages are visible in the paginator
|
||||
* @param int $page
|
||||
* @param int $totalPages
|
||||
* @param int $maxVisiblePages
|
||||
* @return PaginatorResult
|
||||
*/
|
||||
public function getVisiblePages(int $page, int $totalPages, int $maxVisiblePages): PaginatorResult
|
||||
{
|
||||
$half = floor($maxVisiblePages / 2);
|
||||
|
||||
if ($page <= $half) {
|
||||
$start = 1;
|
||||
$end = min($totalPages, $maxVisiblePages);
|
||||
} elseif ($page > $totalPages - $half) {
|
||||
$start = max(1, $totalPages - $maxVisiblePages + 1);
|
||||
$end = $totalPages;
|
||||
} else {
|
||||
$start = $page - $half;
|
||||
$end = min($totalPages, $page + $half);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array<int> $range
|
||||
*/
|
||||
$range = range($start, $end);
|
||||
|
||||
return new PaginatorResult(
|
||||
$page,
|
||||
$start == 1,
|
||||
$end == $totalPages,
|
||||
$totalPages,
|
||||
$totalPages,
|
||||
$range
|
||||
);
|
||||
}
|
||||
}
|
||||
21
src/Utils/Paginator/PaginatorResult.php
Normal file
21
src/Utils/Paginator/PaginatorResult.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Utils\Paginator;
|
||||
|
||||
readonly class PaginatorResult
|
||||
{
|
||||
public function __construct(
|
||||
public int $currentPage,
|
||||
public bool $firstPageVisible,
|
||||
public bool $lastPageVisible,
|
||||
public int $totalPages,
|
||||
public int $lastPage,
|
||||
/**
|
||||
* @var array<int>
|
||||
*/
|
||||
public array $visiblePages,
|
||||
) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user