From 8663e9f5d9b3b159244ee250da9a81cd52260aec Mon Sep 17 00:00:00 2001 From: Alexey Skobkin Date: Sat, 4 Apr 2020 01:03:50 +0300 Subject: [PATCH] TwitterBootstrap4PagelessView and PagelessDoctrineORMAdapter implemented to remove unnecessary COUNT() queries. --- config/packages/pagefanta.yaml | 2 +- config/services.yaml | 6 ++ src/Api/V1/Controller/TorrentController.php | 5 +- src/Controller/TorrentController.php | 5 +- src/Pager/PagelessDoctrineORMAdapter.php | 16 ++++ .../View/TwitterBootstrap4PagelessView.php | 96 +++++++++++++++++++ 6 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/Pager/PagelessDoctrineORMAdapter.php create mode 100644 src/Pager/View/TwitterBootstrap4PagelessView.php diff --git a/config/packages/pagefanta.yaml b/config/packages/pagefanta.yaml index e9d6dd9..32fb384 100644 --- a/config/packages/pagefanta.yaml +++ b/config/packages/pagefanta.yaml @@ -1,2 +1,2 @@ white_october_pagerfanta: - default_view: twitter_bootstrap4 + default_view: twitter_bootstrap4_pageless diff --git a/config/services.yaml b/config/services.yaml index 9fff03b..4e114fc 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -48,3 +48,9 @@ services: Monolog\Processor\PsrLogMessageProcessor: tags: { name: monolog.processor, handler: sentry } + + # Pagerfanta overrides + pagerfanta.view.bootstrap4_pageless: + class: App\Pager\View\TwitterBootstrap4PagelessView + public: false + tags: [{ name: pagerfanta.view, alias: twitter_bootstrap4_pageless }] diff --git a/src/Api/V1/Controller/TorrentController.php b/src/Api/V1/Controller/TorrentController.php index 14414c0..833d028 100644 --- a/src/Api/V1/Controller/TorrentController.php +++ b/src/Api/V1/Controller/TorrentController.php @@ -4,8 +4,8 @@ namespace App\Api\V1\Controller; use App\Api\V1\DTO\ListPage; use App\Magnetico\Entity\Torrent; +use App\Pager\PagelessDoctrineORMAdapter; use App\Search\TorrentSearcher; -use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Pagerfanta; use Symfony\Component\HttpFoundation\{JsonResponse, Request}; @@ -20,9 +20,10 @@ class TorrentController extends AbstractApiController $orderBy = $request->query->get('order-by'); $order = $request->query->get('order', 'asc'); - $pagerAdapter = new DoctrineORMAdapter($searcher->createSearchQueryBuilder($query, $orderBy, $order)); + $pagerAdapter = new PagelessDoctrineORMAdapter($searcher->createSearchQueryBuilder($query, $orderBy, $order)); $pager = new Pagerfanta($pagerAdapter); $pager + ->setAllowOutOfRangePages(true) ->setCurrentPage($page) ->setMaxPerPage(self::PER_PAGE) ; diff --git a/src/Controller/TorrentController.php b/src/Controller/TorrentController.php index d2ae926..903f0e6 100644 --- a/src/Controller/TorrentController.php +++ b/src/Controller/TorrentController.php @@ -4,7 +4,7 @@ namespace App\Controller; use App\Magnetico\Entity\Torrent; use App\Search\TorrentSearcher; -use Pagerfanta\Adapter\DoctrineORMAdapter; +use App\Pager\PagelessDoctrineORMAdapter; use Pagerfanta\Pagerfanta; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\{Request, Response}; @@ -20,9 +20,10 @@ class TorrentController extends AbstractController $orderBy = $request->query->get('order-by'); $order = $request->query->get('order', 'asc'); - $pagerAdapter = new DoctrineORMAdapter($searcher->createSearchQueryBuilder($query, $orderBy, $order)); + $pagerAdapter = new PagelessDoctrineORMAdapter($searcher->createSearchQueryBuilder($query, $orderBy, $order)); $pager = new Pagerfanta($pagerAdapter); $pager + ->setAllowOutOfRangePages(true) ->setCurrentPage($page) ->setMaxPerPage(self::PER_PAGE) ; diff --git a/src/Pager/PagelessDoctrineORMAdapter.php b/src/Pager/PagelessDoctrineORMAdapter.php new file mode 100644 index 0000000..fbf7ade --- /dev/null +++ b/src/Pager/PagelessDoctrineORMAdapter.php @@ -0,0 +1,16 @@ +template = $template ?: $this->createDefaultTemplate(); + } + + public function render(PagerfantaInterface $pagerfanta, $routeGenerator, array $options = array()) + { + $this->initializePagerfanta($pagerfanta); + + $this->configureTemplate($routeGenerator, $options); + + return $this->generate(); + } + + public function getName() + { + return 'twitter_bootstrap4_pageless'; + } + + protected function createDefaultTemplate() + { + return new TwitterBootstrap4Template(); + } + + private function initializePagerfanta(PagerfantaInterface $pagerfanta) + { + $this->pagerfanta = $pagerfanta; + $this->currentPage = $pagerfanta->getCurrentPage(); + } + + private function configureTemplate($routeGenerator, $options) + { + $this->template->setRouteGenerator($routeGenerator); + $this->template->setOptions($options); + } + + private function generate() + { + $pages = $this->generatePages(); + + return $this->generateContainer($pages); + } + + private function generateContainer($pages) + { + return str_replace('%pages%', $pages, $this->template->container()); + } + + private function generatePages() + { + return $this->previous().$this->currentPage().$this->next(); + } + + private function previous(): string + { + if ($this->currentPage > 1) { + return $this->template->previousEnabled($this->pagerfanta->getPreviousPage()); + } + + return $this->template->previousDisabled(); + } + + private function next(): string + { + return $this->template->nextEnabled($this->currentPage + 1); + } + + private function currentPage(): string + { + return $this->template->current($this->currentPage); + } +}