src/App/Util/Pagination.php line 155

Open in your IDE?
  1. <?php
  2. namespace App\Util;
  3. use Doctrine\ORM\AbstractQuery;
  4. use Doctrine\ORM\Query;
  5. use Doctrine\ORM\QueryBuilder;
  6. use Doctrine\ORM\Tools\Pagination\Paginator;
  7. final class Pagination
  8. {
  9.     public const PAGE_LIMIT 12;
  10.     public const PAGE_START 0;
  11.     public const PAGE_VAR 'pagination';
  12.     /**
  13.      * @param int|null $limit
  14.      * @return int
  15.      */
  16.     static public function limit(?int $limit null): int
  17.     {
  18.         return (((int) $limit) <= 0) ? self::PAGE_LIMIT $limit;
  19.     }
  20.     /**
  21.      * @param int $page
  22.      * @return int
  23.      */
  24.     static public function page(int $page self::PAGE_START): int
  25.     {
  26.         return ($page self::PAGE_START) ? self::PAGE_START $page;
  27.     }
  28.     /**
  29.      * @param int $page
  30.      * @param int $limit
  31.      * @return int
  32.      */
  33.     static public function offset(int $pageint $limit self::PAGE_LIMIT): int
  34.     {
  35.         return (self::page($page) * self::limit($limit));
  36.     }
  37.     /**
  38.      * @param QueryBuilder|Query $query
  39.      * @param int|null $limit
  40.      * @param int|null $offset
  41.      * @return QueryBuilder|Query
  42.      */
  43.     static public function paginate($query, ?int $limit null, ?int $offset null)
  44.     {
  45.         if ($limit !== null || $offset !== null) {
  46.             $query
  47.                 ->setMaxResults(self::limit($limit))
  48.                 ->setFirstResult($offset ?? 0);
  49.         }
  50.         return $query;
  51.     }
  52.     /**
  53.      * @param QueryBuilder|Query $query
  54.      * @return iterable|array|Paginator
  55.      */
  56.     static function query($query): iterable
  57.     {
  58.         if ($query instanceof QueryBuilder) {
  59.             $query $query->getQuery();
  60.         }
  61.         if ( ! $query instanceof Query) {
  62.             throw new \Exception();
  63.         }
  64.         if ($query->getFirstResult() !== null && $query->getMaxResults() !== null) {
  65.             return new Paginator($query);
  66.         }
  67.         return $query->getResult($query->getHydrationMode() ?: AbstractQuery::HYDRATE_OBJECT);
  68.     }
  69.     /**
  70.      * @param QueryBuilder|Query $query
  71.      * @param int|null $limit
  72.      * @param int|null $offset
  73.      * @return iterable|array|Paginator
  74.      */
  75.     static public function paginateThenQuery($query, ?int $limit null, ?int $offset null): iterable
  76.     {
  77.         return self::query(
  78.             self::paginate($query$limit$offset)
  79.         );
  80.     }
  81.     /**
  82.      * @param QueryBuilder $qb
  83.      * @return int
  84.      */
  85.     static public function count(QueryBuilder $qb): int
  86.     {
  87.         return $qb
  88.             ->resetDQLParts([
  89.                 'select',
  90.                 'orderBy',
  91.             ])
  92.             ->select(sprintf(
  93.                 'COUNT(%s)',
  94.                 $qb->getRootAliases()[0]
  95.             ))
  96.             ->getQuery()
  97.             ->getSingleScalarResult()
  98.         ;
  99.     }
  100.     /**
  101.      * @param mixed $objects
  102.      * @param int $max
  103.      * @param int $page
  104.      * @param int $limit
  105.      * @return array
  106.      */
  107.     static public function controller($objectsint $maxint $pageint $limit self::PAGE_LIMIT): array
  108.     {
  109.         return array_merge(
  110.             self::stats($objects$max$page$limit),
  111.             [
  112.                 'results' => $objects,
  113.             ]
  114.         );
  115.     }
  116.     /**
  117.      * @param mixed $objects
  118.      * @param int $max
  119.      * @param int $page
  120.      * @param int $limit
  121.      * @return array
  122.      */
  123.     static public function stats($objectsint $maxint $pageint $limit self::PAGE_LIMIT): array
  124.     {
  125.         return [
  126.             'results_count' => count($objects),
  127.             'results_max' => $max,
  128.             'page_prev' => max(self::PAGE_START$page 1),
  129.             'page' => $page,
  130.             'limit' => self::limit($limit),
  131.             'page_next' => min(self::maxPage($objects$limit), $page 1),
  132.             'pages_min' => self::PAGE_START,
  133.             'pages_max' => self::maxPage($objects$limit),
  134.         ];
  135.     }
  136.     /**
  137.      * @param mixed $objects
  138.      * @param int $page
  139.      * @param int $limit
  140.      * @return bool
  141.      */
  142.     static public function outOfBounds($objectsint $pageint $limit self::PAGE_LIMIT): bool
  143.     {
  144.         return (self::page($page) > self::maxPage($objects$limit));
  145.     }
  146.     /**
  147.      * @param mixed $objects
  148.      * @param int $limit
  149.      * @return int
  150.      */
  151.     static public function maxPage($objectsint $limit self::PAGE_LIMIT): int
  152.     {
  153.         return max((intval(ceil(count($objects) / self::limit($limit))) - 1), 0);
  154.     }
  155. }