Эх сурвалжийг харах

Pagination en avancement, seulement sur liste complète

Sangfroid 8 сар өмнө
parent
commit
4bad005087

+ 0 - 1
src/Controller/FilmAbstractController.php

@@ -13,7 +13,6 @@ abstract class FilmAbstractController extends AbstractController
     public function formPagination(Request $request): FormInterface
     {
         $session = $request->getSession();
-
         
         $filterDto = $session->get('filters', new FiltersDTO());
         $filtersForm = $this->createForm(FiltersType::class, $filterDto);

+ 11 - 4
src/Controller/VideothequeListController.php

@@ -15,6 +15,7 @@ use App\Repository\GenreRepository;
 use App\Repository\RealisateurRepository;
 use App\Service\CommentaireManager;
 use App\Service\OptionsManager;
+use App\Service\Pagination;
 use Symfony\Bundle\SecurityBundle\Security;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -23,14 +24,20 @@ class VideothequeListController extends FilmAbstractController
 	#[Route("/", name: "videotheque_liste")]
 	public function listeAction(Request $request, FilmRepository $filmRepository, OptionsManager $options): Response
 	{
+        $page = (int)$request->get('p', 1);
+        $page = $page > 0 ? $page : 1;
+        if ($request->isMethod('POST')) {
+            $page = 1;
+        }
         $filtersForm = $this->formPagination($request);
-        $listeFilms = $filmRepository->findTous($filtersForm->getData()->toArray());
-        dump($filtersForm->getData());
+        $qb = $filmRepository->queryTous($filtersForm->getData()->toArray(), $page);
+        $pagination = new Pagination($qb, $filtersForm->getData()->nbResults, $page);
 
 		return $this->render('videotheque/liste_'.$options->vue().'.html.twig', array(
-            'listeFilms'	=>	$listeFilms,
+            'listeFilms'	=>	$pagination->getPaginator(),
             'titre'         =>  'Liste complète',
-            'filtersForm'   =>  $filtersForm->createView()
+            'filtersForm'   =>  $filtersForm->createView(),
+            'pagination'    =>  $pagination
 		));
     }
 

+ 21 - 16
src/Repository/FilmRepository.php

@@ -33,27 +33,27 @@ class FilmRepository extends ServiceEntityRepository
         return $query->getSingleResult();
     }
 
-    public function findFilmWithGenre(array $genreNames, array $filters = []) : Paginator
+    public function findFilmWithGenre(array $genreNames, array $filters = [], int $page) : QueryBuilder
     {
-        $qb = $this->queryFilter($filters);
+        $qb = $this->queryFilter($filters, $page);
         $qb
             ->innerJoin('f.genres', 'g')
             ->addSelect('f');
 
         $qb->where($qb->expr()->in('g.name', $genreNames));
 
-        return new Paginator($qb->getQuery());
+        return $qb;
     }
 
-    public function findFilmWithReal(array $realisateursnames, array $filters = []): Paginator
+    public function findFilmWithReal(array $realisateursnames, array $filters = [], int $page): QueryBuilder
     {
-        $qb = $this->queryFilter($filters);
+        $qb = $this->queryFilter($filters, $page);
         $qb
             ->leftJoin('f.realisateurs', 'rea')
             ->addSelect('f')
             ->where($qb->expr()->in('rea.nomComplet', $realisateursnames));
 
-        return new Paginator($qb->getQuery());
+        return $qb;
     }
 
     public function findFilmWithRealLike($query): array
@@ -85,12 +85,17 @@ class FilmRepository extends ServiceEntityRepository
             ->getResult();
     }
 
-    public function queryFilter(array $filters = []): QueryBuilder
+    public function queryFilter(array $filters = [], int $page = 1): QueryBuilder
     {
         $qb =  $this->createQueryBuilder('f')
-            ->orderBy('f.'.($filters['sortBy'] ?? 'dateSubmited'), $filters['sortOrder'] ?? 'DESC')
-            ->setMaxResults((int)($filters['limit'] ?? 100))
-        ;
+            ->orderBy('f.'.($filters['sortBy'] ?? 'dateSubmited'), $filters['sortOrder'] ?? 'DESC');
+
+        if ($filters['limit']) {
+            $limit = (int)$filters['limit'];
+            $qb->setFirstResult(($page * $limit) - $limit);
+            $qb->setMaxResults($limit);
+        }
+    
         if ($filters['note']) {
             $qb
                 ->andWhere('f.note >= :note')
@@ -108,19 +113,19 @@ class FilmRepository extends ServiceEntityRepository
         
     }
 
-    public function findTous (array $filters = []): Paginator
+    public function queryTous (array $filters = [], int $page): QueryBuilder
     {
-        $qb = $this->queryFilter($filters)
+        $qb = $this->queryFilter($filters, $page)
             ->leftJoin('f.authered', 'aut')->addSelect('aut')
             ->leftJoin('f.genres', 'gen')->addSelect('gen')
             ->leftJoin('f.realisateurs', 'rea')->addSelect('rea')
         ;
-        return new Paginator($qb->getQuery());
+        return $qb;
     }
 
-    public function findTousFavoritesByUser($user, array $filters = []): Paginator
+    public function queryTousFavoritesByUser($user, array $filters = [], int $page): QueryBuilder
     {
-        $qb = $this->queryFilter($filters);
+        $qb = $this->queryFilter($filters, $page);
         $qb
             ->leftJoin('f.authered', 'aut')->addSelect('aut')
             ->leftJoin('f.genres', 'gen')->addSelect('gen')
@@ -129,7 +134,7 @@ class FilmRepository extends ServiceEntityRepository
             ->where($qb->expr()->in('wan', ':user'))
             ->setParameter('user', $user)
         ;
-        return new Paginator($qb->getQuery());
+        return $qb;
     }
 
     public function findProchaines(): array

+ 40 - 0
src/Service/Pagination.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Service;
+
+use Doctrine\ORM\QueryBuilder;
+use Doctrine\ORM\Tools\Pagination\Paginator;
+
+class Pagination
+{
+    protected readonly Paginator $paginator;
+
+    public function __construct(
+        protected readonly QueryBuilder $queryBuilder,
+        protected readonly int $limit,
+        protected readonly int $currentPage
+    )
+    {
+        $this->paginator = new Paginator($this->queryBuilder);
+    }
+
+    public function getPaginator(): Paginator
+    {
+        return $this->paginator;
+    }
+
+    public function getTotal(): int
+    {
+        return $this->paginator->count();
+    }
+
+    public function getPages(): int
+    {
+        return ceil($this->paginator->count() / $this->limit);
+    }
+
+    public function getCurrentPage(): int
+    {
+        return $this->currentPage;
+    }
+}

+ 4 - 7
templates/videotheque/_filters_form.html.twig

@@ -2,8 +2,8 @@
 <div data-controller="collapser mb-3">
     <button class="btn text-primary" data-bs-toggle="collapse" data-bs-target="#collapse-filters">Filtres <i data-collapser-target="button" class="fa fa-chevron-circle-right fa-lg"></i></button>
     <div id="collapse-filters" class="collapse" data-collapser-target="collapse">
-        {% form_theme filtersForm 'bootstrap_5_horizontal_layout.html.twig' %}
-            {{ form_start(filtersForm) }}
+        {#{% form_theme filtersForm 'bootstrap_5_horizontal_layout.html.twig' %}#}
+            {{ form_start(filtersForm, {'attr': {'class': 'row row-cols-lg-auto g-3 align-items-center'} } ) }}
         
             {{ form_row(filtersForm.note) }}
             {{ form_row(filtersForm.nbResults) }}
@@ -12,11 +12,8 @@
             {{ form_row(filtersForm.sortBy) }}
             {{ form_row(filtersForm.sortOrder) }}
             {{ form_rest(filtersForm)}}
-            <div class="d-flex">
-                <div class="me-auto"></div>
-                <button class="btn btn-primary mb-3" type="submit">Filtrer</button>
-            </div>
-                
+            
+            <button class="btn btn-primary mb-3" type="submit">Filtrer</button>
             {{ form_end(filtersForm) }}
     </div>
 </div>

+ 12 - 0
templates/videotheque/_liste_footer.html.twig

@@ -0,0 +1,12 @@
+{% if pagination is defined %}
+<nav aria-label="pagination">
+    <ul class="pagination">
+        <li class="page-item {{ pagination.getCurrentPage() > 1 ?: 'disabled' }}"><a class="page-link" href="{{ path(app.request.attributes.get('_route'), {'p': pagination.getCurrentPage() - 1}) }}">{{ "Previous" | trans }}</a></li>
+        {% for i in 1..pagination.getPages() %}
+        <li class="page-item {{ pagination.getCurrentPage() is not same as i ?: 'active'}}"><a class="page-link" href="{{ path(app.request.attributes.get('_route'), {'p': i}) }}">{{ i }}</a></li>
+        {% endfor %}
+        <li class="page-item {{ pagination.getCurrentPage() < pagination.getPages() ?: 'disabled' }}"><a class="page-link" href="{{ path(app.request.attributes.get('_route'), {'p': pagination.getCurrentPage() + 1}) }}">{{ "Next" | trans }}</a></li>
+    </ul>
+</nav>
+<div class="mb-6"></div>
+{% endif %}

+ 1 - 0
templates/videotheque/liste_tableaux.html.twig

@@ -119,4 +119,5 @@
 			{% endfor %}
 		</tbody>
 	</table>
+	{{ include('videotheque/_liste_footer.html.twig') }}
 {% endblock %}

+ 1 - 0
templates/videotheque/liste_vignettes.html.twig

@@ -145,4 +145,5 @@
 		</article>
 		{% endfor %}
 	</section>
+	{{ include('videotheque/_liste_footer.html.twig') }}
 {% endblock %}