diff --git a/src/Knp/Component/Pager/Event/ItemsEvent.php b/src/Knp/Component/Pager/Event/ItemsEvent.php index 216713f9..82ca96cb 100644 --- a/src/Knp/Component/Pager/Event/ItemsEvent.php +++ b/src/Knp/Component/Pager/Event/ItemsEvent.php @@ -2,6 +2,7 @@ namespace Knp\Component\Pager\Event; +use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Symfony\Contracts\EventDispatcher\Event; /** @@ -34,8 +35,11 @@ final class ItemsEvent extends Event */ private array $customPaginationParams = []; - public function __construct(private readonly int $offset, private readonly int $limit) - { + public function __construct( + private readonly int $offset, + private readonly int $limit, + private readonly ArgumentAccessInterface $argumentAccess + ) { } public function setCustomPaginationParameter(string $name, mixed $value): void @@ -67,4 +71,9 @@ public function getOffset(): int { return $this->offset; } + + public function getArgumentAccess(): ArgumentAccessInterface + { + return $this->argumentAccess; + } } diff --git a/src/Knp/Component/Pager/Event/Subscriber/Filtration/Doctrine/ORM/QuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Filtration/Doctrine/ORM/QuerySubscriber.php index 5d57a4ab..3203e9bf 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Filtration/Doctrine/ORM/QuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Filtration/Doctrine/ORM/QuerySubscriber.php @@ -13,25 +13,23 @@ class QuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { if (!$event->target instanceof Query) { return; } - if (!$this->hasQueryParameter($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME])) { + $argumentAccess = $event->getArgumentAccess(); + + if (!$argumentAccess->has($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME])) { return; } - $filterValue = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); + $filterValue = $argumentAccess->get($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); if ((empty($filterValue) && $filterValue !== '0')) { return; } $filterName = null; - if ($this->hasQueryParameter($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME])) { - $filterName = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME]); + if ($argumentAccess->has($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME])) { + $filterName = $argumentAccess->get($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME]); } if (!empty($filterName)) { $columns = $filterName; @@ -40,7 +38,7 @@ public function items(ItemsEvent $event): void } else { return; } - $value = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); + $value = $argumentAccess->get($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); if (str_contains($value, '*')) { $value = str_replace('*', '%', $value); } @@ -67,14 +65,4 @@ public static function getSubscribedEvents(): array 'knp_pager.items' => ['items', 0], ]; } - - private function hasQueryParameter(string $name): bool - { - return $this->argumentAccess->has($name); - } - - private function getQueryParameter(string $name): ?string - { - return $this->argumentAccess->get($name); - } } diff --git a/src/Knp/Component/Pager/Event/Subscriber/Filtration/FiltrationSubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Filtration/FiltrationSubscriber.php index d0774e7c..01656086 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Filtration/FiltrationSubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Filtration/FiltrationSubscriber.php @@ -22,8 +22,8 @@ public function before(BeforeEvent $event): void /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ $dispatcher = $event->getEventDispatcher(); // hook all standard filtration subscribers - $dispatcher->addSubscriber(new Doctrine\ORM\QuerySubscriber($event->getArgumentAccess())); - $dispatcher->addSubscriber(new PropelQuerySubscriber($event->getArgumentAccess())); + $dispatcher->addSubscriber(new Doctrine\ORM\QuerySubscriber()); + $dispatcher->addSubscriber(new PropelQuerySubscriber()); $this->isLoaded = true; } diff --git a/src/Knp/Component/Pager/Event/Subscriber/Filtration/PropelQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Filtration/PropelQuerySubscriber.php index ea1843d6..4de83cb3 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Filtration/PropelQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Filtration/PropelQuerySubscriber.php @@ -2,7 +2,6 @@ namespace Knp\Component\Pager\Event\Subscriber\Filtration; -use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Exception\InvalidValueException; use Knp\Component\Pager\PaginatorInterface; @@ -10,19 +9,17 @@ class PropelQuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { $query = $event->target; + $argumentAccess = $event->getArgumentAccess(); + if ($query instanceof \ModelCriteria) { - if (!$this->argumentAccess->has($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME])) { + if (!$argumentAccess->has($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME])) { return; } - if ($this->argumentAccess->has($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME])) { - $columns = $this->argumentAccess->get($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME]); + if ($argumentAccess->has($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME])) { + $columns = $argumentAccess->get($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME]); } elseif (!empty($event->options[PaginatorInterface::DEFAULT_FILTER_FIELDS])) { $columns = $event->options[PaginatorInterface::DEFAULT_FILTER_FIELDS]; } else { @@ -39,7 +36,7 @@ public function items(ItemsEvent $event): void } } } - $value = $this->argumentAccess->get($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); + $value = $argumentAccess->get($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]); $criteria = \Criteria::EQUAL; if (str_contains($value, '*')) { $value = str_replace('*', '%', $value); diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php index 257b3877..802099b2 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php @@ -25,7 +25,7 @@ class ArraySubscriber implements EventSubscriberInterface private readonly ?PropertyAccessorInterface $propertyAccessor; - public function __construct(private readonly ArgumentAccessInterface $argumentAccess, ?PropertyAccessorInterface $accessor = null) + public function __construct(?PropertyAccessorInterface $accessor = null) { if (!$accessor && class_exists(PropertyAccess::class)) { $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor(); @@ -36,24 +36,26 @@ public function __construct(private readonly ArgumentAccessInterface $argumentAc public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; } $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; - if (!is_array($event->target) || null === $sortField || !$this->argumentAccess->has($sortField)) { + if (!is_array($event->target) || null === $sortField || !$argumentAccess->has($sortField)) { return; } $event->setCustomPaginationParameter('sorted', true); - if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($this->argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { - throw new InvalidValueException("Cannot sort by: [{$this->argumentAccess->get($sortField)}] this field is not in allow list."); + if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { + throw new InvalidValueException("Cannot sort by: [{$argumentAccess->get($sortField)}] this field is not in allow list."); } $sortFunction = $event->options['sortFunction'] ?? [$this, 'proxySortFunction']; - $sortField = $this->argumentAccess->get($sortField); + $sortField = $argumentAccess->get($sortField); // compatibility layer if ($sortField[0] === '.') { @@ -63,19 +65,19 @@ public function items(ItemsEvent $event): void call_user_func_array($sortFunction, [ &$event->target, $sortField, - $this->getSortDirection($event->options), + $this->getSortDirection($event), ]); } - /** - * @param array $options - */ - private function getSortDirection(array $options): string + private function getSortDirection(ItemsEvent $event): string { - if (!$this->argumentAccess->has($options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME])) { + $argumentAccess = $event->getArgumentAccess(); + $options = $event->options; + + if (!$argumentAccess->has($options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME])) { return 'desc'; } - $direction = $this->argumentAccess->get($options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]); + $direction = $argumentAccess->get($options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]); if (strtolower($direction) === 'asc') { return 'asc'; } diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php index f6e389ee..6dec9cdf 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php @@ -3,7 +3,6 @@ namespace Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ODM\MongoDB; use Doctrine\ODM\MongoDB\Query\Query; -use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Exception\InvalidValueException; use Knp\Component\Pager\PaginatorInterface; @@ -11,12 +10,10 @@ class QuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { @@ -27,9 +24,9 @@ public function items(ItemsEvent $event): void $event->setCustomPaginationParameter('sorted', true); $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; $sortDir = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; - if (null !== $sortField && $this->argumentAccess->has($sortField)) { - $field = $this->argumentAccess->get($sortField); - $dir = null !== $sortDir && strtolower($this->argumentAccess->get($sortDir)) === 'asc' ? 1 : -1; + if (null !== $sortField && $argumentAccess->has($sortField)) { + $field = $argumentAccess->get($sortField); + $dir = null !== $sortDir && strtolower($argumentAccess->get($sortDir)) === 'asc' ? 1 : -1; if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && (!in_array($field, $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]))) { throw new InvalidValueException("Cannot sort by: [$field] this field is not in allow list."); diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php index 9c7c0d29..a42768f9 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php @@ -3,7 +3,6 @@ namespace Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ORM; use Doctrine\ORM\Query; -use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\Helper as QueryHelper; use Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ORM\Query\OrderByWalker; @@ -13,12 +12,10 @@ class QuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { @@ -29,14 +26,14 @@ public function items(ItemsEvent $event): void $event->setCustomPaginationParameter('sorted', true); $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; $sortDir = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; - if (null !== $sortField && $this->argumentAccess->has($sortField)) { - $dir = null !== $sortDir && $this->argumentAccess->has($sortDir) && strtolower($this->argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; + if (null !== $sortField && $argumentAccess->has($sortField)) { + $dir = null !== $sortDir && $argumentAccess->has($sortDir) && strtolower($argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; - if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($this->argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { - throw new InvalidValueException("Cannot sort by: [{$this->argumentAccess->get($sortField)}] this field is not in allow list."); + if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { + throw new InvalidValueException("Cannot sort by: [{$argumentAccess->get($sortField)}] this field is not in allow list."); } - $sortFieldParameterNames = $this->argumentAccess->get($sortField); + $sortFieldParameterNames = $argumentAccess->get($sortField); $fields = []; $aliases = []; if (!is_string($sortFieldParameterNames)) { diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php index 114fe671..2ad05ccd 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php @@ -4,7 +4,6 @@ use Elastica\Query; use Elastica\SearchableInterface; -use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Exception\InvalidValueException; use Knp\Component\Pager\PaginatorInterface; @@ -12,12 +11,10 @@ class ElasticaQuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { @@ -29,9 +26,9 @@ public function items(ItemsEvent $event): void $event->setCustomPaginationParameter('sorted', true); $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; $sortDir = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; - if (null !== $sortField && $this->argumentAccess->has($sortField)) { - $field = $this->argumentAccess->get($sortField); - $dir = null !== $sortDir && $this->argumentAccess->has($sortDir) && strtolower($this->argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; + if (null !== $sortField && $argumentAccess->has($sortField)) { + $field = $argumentAccess->get($sortField); + $dir = null !== $sortDir && $argumentAccess->has($sortDir) && strtolower($argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($field, $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { throw new InvalidValueException(sprintf('Cannot sort by: [%s] this field is not in allow list.', $field)); diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php index 5b79af10..026f5380 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php @@ -2,7 +2,6 @@ namespace Knp\Component\Pager\Event\Subscriber\Sortable; -use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Exception\InvalidValueException; use Knp\Component\Pager\PaginatorInterface; @@ -10,12 +9,10 @@ class PropelQuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { @@ -27,13 +24,13 @@ public function items(ItemsEvent $event): void $event->setCustomPaginationParameter('sorted', true); $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; $sortDir = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; - if (null !== $sortField && $this->argumentAccess->has($sortField)) { - $part = $this->argumentAccess->get($sortField); - $direction = (null !== $sortDir && $this->argumentAccess->has($sortDir) && strtolower($this->argumentAccess->get($sortDir)) === 'asc') + if (null !== $sortField && $argumentAccess->has($sortField)) { + $part = $argumentAccess->get($sortField); + $direction = (null !== $sortDir && $argumentAccess->has($sortDir) && strtolower($argumentAccess->get($sortDir)) === 'asc') ? 'asc' : 'desc'; - if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($this->argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { - throw new InvalidValueException("Cannot sort by: [{$this->argumentAccess->get($sortField)}] this field is not in allow list."); + if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { + throw new InvalidValueException("Cannot sort by: [{$argumentAccess->get($sortField)}] this field is not in allow list."); } $query->orderBy($part, $direction); diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php index ab74bd00..86f5c4e8 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php @@ -15,12 +15,10 @@ */ class SolariumQuerySubscriber implements EventSubscriberInterface { - public function __construct(private readonly ArgumentAccessInterface $argumentAccess) - { - } - public function items(ItemsEvent $event): void { + $argumentAccess = $event->getArgumentAccess(); + // Check if the result has already been sorted by another sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { @@ -34,12 +32,12 @@ public function items(ItemsEvent $event): void if ($client instanceof \Solarium\Client && $query instanceof \Solarium\QueryType\Select\Query\Query) { $event->setCustomPaginationParameter('sorted', true); $sortField = $event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]; - if (null !== $sortField && $this->argumentAccess->has($sortField)) { - if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($this->argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { - throw new InvalidValueException("Cannot sort by: [{$this->argumentAccess->get($sortField)}] this field is not in allow list."); + if (null !== $sortField && $argumentAccess->has($sortField)) { + if (isset($event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST]) && !in_array($argumentAccess->get($sortField), $event->options[PaginatorInterface::SORT_FIELD_ALLOW_LIST])) { + throw new InvalidValueException("Cannot sort by: [{$argumentAccess->get($sortField)}] this field is not in allow list."); } - $query->addSort($this->argumentAccess->get($sortField), $this->getSortDirection($event)); + $query->addSort($argumentAccess->get($sortField), $this->getSortDirection($event)); } } } @@ -55,9 +53,11 @@ public static function getSubscribedEvents(): array private function getSortDirection(ItemsEvent $event): string { + $argumentAccess = $event->getArgumentAccess(); + $sortDir = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; - return null !== $sortDir && $this->argumentAccess->has($sortDir) && - strtolower($this->argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; + return null !== $sortDir && $argumentAccess->has($sortDir) && + strtolower($argumentAccess->get($sortDir)) === 'asc' ? 'asc' : 'desc'; } } diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SortableSubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SortableSubscriber.php index 720f8d40..ee0aa7d3 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SortableSubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SortableSubscriber.php @@ -22,13 +22,12 @@ public function before(BeforeEvent $event): void /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher */ $dispatcher = $event->getEventDispatcher(); // hook all standard sortable subscribers - $argumentAccess = $event->getArgumentAccess(); - $dispatcher->addSubscriber(new Doctrine\ORM\QuerySubscriber($argumentAccess)); - $dispatcher->addSubscriber(new Doctrine\ODM\MongoDB\QuerySubscriber($argumentAccess)); - $dispatcher->addSubscriber(new ElasticaQuerySubscriber($argumentAccess)); - $dispatcher->addSubscriber(new PropelQuerySubscriber($argumentAccess)); - $dispatcher->addSubscriber(new SolariumQuerySubscriber($argumentAccess)); - $dispatcher->addSubscriber(new ArraySubscriber($argumentAccess)); + $dispatcher->addSubscriber(new Doctrine\ORM\QuerySubscriber()); + $dispatcher->addSubscriber(new Doctrine\ODM\MongoDB\QuerySubscriber()); + $dispatcher->addSubscriber(new ElasticaQuerySubscriber()); + $dispatcher->addSubscriber(new PropelQuerySubscriber()); + $dispatcher->addSubscriber(new SolariumQuerySubscriber()); + $dispatcher->addSubscriber(new ArraySubscriber()); $this->isLoaded = true; } diff --git a/src/Knp/Component/Pager/Paginator.php b/src/Knp/Component/Pager/Paginator.php index 87ad542b..285b3c21 100644 --- a/src/Knp/Component/Pager/Paginator.php +++ b/src/Knp/Component/Pager/Paginator.php @@ -91,7 +91,7 @@ public function paginate($target, int $page = 1, ?int $limit = null, array $opti $beforeEvent->options = &$options; $this->eventDispatcher->dispatch($beforeEvent, 'knp_pager.before'); // items - $itemsEvent = new Event\ItemsEvent($offset, $limit); + $itemsEvent = new Event\ItemsEvent($offset, $limit, $this->argumentAccess); $itemsEvent->options = &$options; $itemsEvent->target = &$target; $this->eventDispatcher->dispatch($itemsEvent, 'knp_pager.items'); diff --git a/tests/Test/Pager/PaginatorTest.php b/tests/Test/Pager/PaginatorTest.php index 850c8529..a8869c74 100644 --- a/tests/Test/Pager/PaginatorTest.php +++ b/tests/Test/Pager/PaginatorTest.php @@ -2,10 +2,12 @@ namespace Test\Pager; +use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface; use Knp\Component\Pager\Event\BeforeEvent; use Knp\Component\Pager\Event\ItemsEvent; use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber; use Knp\Component\Pager\Pagination\SlidingPagination; +use Knp\Component\Pager\Paginator; use PHPUnit\Framework\Attributes\Test; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -74,4 +76,27 @@ public function items(ItemsEvent $event): void $paginator->paginate([], 1, 10, ['some_option' => 'value']); } + #[Test] + public function shouldPassArgumentAccessToItemsEventSubscriber(): void + { + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new PaginationSubscriber()); + $dispatcher->addSubscriber(new class implements EventSubscriberInterface { + public static function getSubscribedEvents(): array + { + return [ + 'knp_pager.items' => ['items', 1], + ]; + } + public function items(ItemsEvent $event): void + { + BaseTestCase::assertInstanceOf(ArgumentAccessInterface::class, $event->getArgumentAccess()); + } + }); + + $accessor = $this->createMock(ArgumentAccessInterface::class); + $paginator = new Paginator($dispatcher, $accessor); + + $paginator->paginate([]); + } } diff --git a/tests/Test/Pager/Subscriber/Filtration/Doctrine/ORM/QueryTest.php b/tests/Test/Pager/Subscriber/Filtration/Doctrine/ORM/QueryTest.php index e9be9429..32ab750a 100644 --- a/tests/Test/Pager/Subscriber/Filtration/Doctrine/ORM/QueryTest.php +++ b/tests/Test/Pager/Subscriber/Filtration/Doctrine/ORM/QueryTest.php @@ -428,18 +428,9 @@ public function shouldFilterSimpleDoctrineQueryWithMultipleProperties(): void $this->assertEquals('summer', $items[0]->getTitle()); $this->assertEquals('winter', $items[1]->getTitle()); - $requestStack = $this->createRequestStack(['filterParam' => ['a.id', 'a.title'], 'filterValue' => '*er']); - $accessor = new RequestArgumentAccess($requestStack); - $p = new Paginator($dispatcher, $accessor); - $view = $p->paginate($query, 1, 10); - $items = $view->getItems(); - $this->assertCount(2, $items); - $this->assertEquals('summer', $items[0]->getTitle()); - $this->assertEquals('winter', $items[1]->getTitle()); $executed = $this->queryAnalyzer->getExecutedQueries(); $this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10', $executed[1]); - $this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10', $executed[3]); } #[Test] diff --git a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php index a8c62fe0..d3da98c8 100644 --- a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php +++ b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php @@ -22,23 +22,19 @@ public function shouldSort(): void ['entry' => ['sortProperty' => 1]], ]; - $itemsEvent = new ItemsEvent(0, 10); - $itemsEvent->target = &$array; - $itemsEvent->options = [PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord']; + $arraySubscriber = new ArraySubscriber(); // test asc sort - $requestStack = $this->createRequestStack(['sort' => '[entry][sortProperty]', 'ord' => 'asc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '[entry][sortProperty]', 'ord' => 'asc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertEquals(1, $array[0]['entry']['sortProperty']); - $itemsEvent->unsetCustomPaginationParameter('sorted'); - // test desc sort - $requestStack = $this->createRequestStack(['sort' => '[entry][sortProperty]', 'ord' => 'desc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '[entry][sortProperty]', 'ord' => 'desc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertEquals(3, $array[0]['entry']['sortProperty']); } @@ -52,35 +48,31 @@ public function shouldSortWithCustomCallback(): void ['name' => 'hot'], ]; - $itemsEvent = new ItemsEvent(0, 10); - $itemsEvent->target = &$array; - $itemsEvent->options = [ - PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', - PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord', - 'sortFunction' => static function (&$target, $sortField, $sortDirection): void { - \usort($target, static function ($object1, $object2) use ($sortField, $sortDirection) { - if ($object1[$sortField] === $object2[$sortField]) { - return 0; - } - - return ($object1[$sortField] === 'hot' ? 1 : -1) * ($sortDirection === 'asc' ? 1 : -1); - }); - }, - ]; + $arraySubscriber = new ArraySubscriber(); + + $sortFunction = static function (&$target, $sortField, $sortDirection): void { + \usort($target, static function ($object1, $object2) use ($sortField, $sortDirection) { + if ($object1[$sortField] === $object2[$sortField]) { + return 0; + } + + return ($object1[$sortField] === 'hot' ? 1 : -1) * ($sortDirection === 'asc' ? 1 : -1); + }); + }; // test asc sort - $requestStack = $this->createRequestStack(['sort' => '.name', 'ord' => 'asc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '.name', 'ord' => 'asc']); + $itemsEvent->target = &$array; + $itemsEvent->options['sortFunction'] = $sortFunction; + $arraySubscriber->items($itemsEvent); $this->assertEquals('cold', $array[0]['name']); - $itemsEvent->unsetCustomPaginationParameter('sorted'); - // test desc sort - $requestStack = $this->createRequestStack(['sort' => '.name', 'ord' => 'desc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '.name', 'ord' => 'desc']); + $itemsEvent->target = &$array; + $itemsEvent->options['sortFunction'] = $sortFunction; + $arraySubscriber->items($itemsEvent); $this->assertEquals('hot', $array[0]['name']); } @@ -94,23 +86,19 @@ public function shouldSortEvenWhenTheSortPropertyIsNotAccessible(): void ['entry' => ['sortProperty' => 1]], ]; - $itemsEvent = new ItemsEvent(0, 10); - $itemsEvent->target = &$array; - $itemsEvent->options = [PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord']; + $arraySubscriber = new ArraySubscriber(); // test asc sort - $requestStack = $this->createRequestStack(['sort' => '[entry][sortProperty]', 'ord' => 'asc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '[entry][sortProperty]', 'ord' => 'asc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertFalse(isset($array[0]['entry']['sortProperty'])); - $itemsEvent->unsetCustomPaginationParameter('sorted'); - // test desc sort - $requestStack = $this->createRequestStack(['sort' => '[entry][sortProperty]', 'ord' => 'desc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => '[entry][sortProperty]', 'ord' => 'desc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertEquals(2, $array[0]['entry']['sortProperty']); } @@ -124,26 +112,20 @@ public function shouldBeKeptTheOrderWhenSortPropertyDoesNotExist(array $items): $items[1], $items[2], ]; - $itemsEvent = new ItemsEvent(0, 10); - $itemsEvent->target = &$items; - $itemsEvent->options = [ - PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', - PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord', - ]; + + $arraySubscriber = new ArraySubscriber(); // test asc sort - $requestStack = $this->createRequestStack(['sort' => 'notExistProperty', 'ord' => 'asc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => 'notExistProperty', 'ord' => 'asc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertSame($sameSortOrderItems, $items); - $itemsEvent->unsetCustomPaginationParameter('sorted'); - // test desc sort - $requestStack = $this->createRequestStack(['sort' => 'notExistProperty', 'ord' => 'desc']); - $accessor = new RequestArgumentAccess($requestStack); - $arraySubscriber = new ArraySubscriber($accessor); + $itemsEvent = $this->createItemsEvent(['sort' => 'notExistProperty', 'ord' => 'desc']); + $itemsEvent->target = &$array; + $arraySubscriber->items($itemsEvent); $this->assertSame($sameSortOrderItems, $items); } @@ -170,4 +152,15 @@ public static function getItemsData(): array ], ]; } + + private function createItemsEvent(array $requestParams = []): ItemsEvent + { + $requestStack = $this->createRequestStack($requestParams); + $accessor = new RequestArgumentAccess($requestStack); + + $event = new ItemsEvent(0, 10, $accessor); + $event->options = [PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord']; + + return $event; + } }