vendor/friendsofsymfony/elastica-bundle/src/Subscriber/PaginateElasticaQuerySubscriber.php line 33

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSElasticaBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <https://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\ElasticaBundle\Subscriber;
  11. use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
  12. use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
  13. use Knp\Component\Pager\Event\ItemsEvent;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\RequestStack;
  17. class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
  18. {
  19.     /**
  20.      * @var RequestStack
  21.      */
  22.     private $requestStack;
  23.     public function __construct(RequestStack $requestStack)
  24.     {
  25.         $this->requestStack $requestStack;
  26.     }
  27.     public function items(ItemsEvent $event)
  28.     {
  29.         if ($event->target instanceof PaginatorAdapterInterface) {
  30.             // Add sort to query
  31.             $this->setSorting($event);
  32.             /** @var PartialResultsInterface $results */
  33.             $results $event->target->getResults($event->getOffset(), $event->getLimit());
  34.             $event->count $results->getTotalHits();
  35.             $event->items $results->toArray();
  36.             $aggregations $results->getAggregations();
  37.             if (null != $aggregations) {
  38.                 $event->setCustomPaginationParameter('aggregations'$aggregations);
  39.             }
  40.             $event->stopPropagation();
  41.         }
  42.     }
  43.     /**
  44.      * @return array
  45.      */
  46.     public static function getSubscribedEvents()
  47.     {
  48.         return [
  49.             'knp_pager.items' => ['items'1],
  50.         ];
  51.     }
  52.     /**
  53.      * Adds knp paging sort to query.
  54.      */
  55.     protected function setSorting(ItemsEvent $event)
  56.     {
  57.         // Bugfix for PHP 7.4 as options can be null and generate a "Trying to access array offset on value of type null" error
  58.         $options $event->options ?? [];
  59.         $sortField $this->getFromRequest($options['sortFieldParameterName'] ?? null);
  60.         if (!$sortField && isset($options['defaultSortFieldName'])) {
  61.             $sortField $options['defaultSortFieldName'];
  62.         }
  63.         if (!empty($sortField)) {
  64.             $event->target->getQuery()->setSort([
  65.                 $sortField => $this->getSort($sortField$options),
  66.             ]);
  67.         }
  68.     }
  69.     protected function getSort($sortField, array $options = [])
  70.     {
  71.         $sort = [
  72.             'order' => $this->getSortDirection($sortField$options),
  73.         ];
  74.         if (isset($options['sortNestedPath'])) {
  75.             $path \is_callable($options['sortNestedPath']) ?
  76.                 $options['sortNestedPath']($sortField) : $options['sortNestedPath'];
  77.             if (!empty($path)) {
  78.                 $sort['nested_path'] = $path;
  79.             }
  80.         }
  81.         if (isset($options['sortNestedFilter'])) {
  82.             $filter \is_callable($options['sortNestedFilter']) ?
  83.                 $options['sortNestedFilter']($sortField) : $options['sortNestedFilter'];
  84.             if (!empty($filter)) {
  85.                 $sort['nested_filter'] = $filter;
  86.             }
  87.         }
  88.         return $sort;
  89.     }
  90.     protected function getSortDirection($sortField, array $options = [])
  91.     {
  92.         $dir 'asc';
  93.         $sortDirection $this->getFromRequest($options['sortDirectionParameterName']);
  94.         if (empty($sortDirection) && isset($options['defaultSortDirection'])) {
  95.             $sortDirection $options['defaultSortDirection'];
  96.         }
  97.         if (null !== $sortDirection && 'desc' === \strtolower($sortDirection)) {
  98.             $dir 'desc';
  99.         }
  100.         // check if the requested sort field is in the sort whitelist
  101.         if (isset($options['sortFieldAllowList']) && !\in_array($sortField$options['sortFieldAllowList'], true)) {
  102.             throw new \UnexpectedValueException(\sprintf('Cannot sort by: [%s] this field is not in whitelist'$sortField));
  103.         }
  104.         return $dir;
  105.     }
  106.     private function getRequest(): ?Request
  107.     {
  108.         return $this->requestStack->getCurrentRequest();
  109.     }
  110.     /**
  111.      * @return mixed|null
  112.      */
  113.     private function getFromRequest(?string $key)
  114.     {
  115.         if (null !== $key && null !== $request $this->getRequest()) {
  116.             return $request->get($key);
  117.         }
  118.         return null;
  119.     }
  120. }