Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass ArgumentAccess with the knp_pager.items event #343

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Knp/Component/Pager/Event/ItemsEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Knp\Component\Pager\Event;

use Knp\Component\Pager\ArgumentAccess\ArgumentAccessInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -67,4 +71,9 @@ public function getOffset(): int
{
return $this->offset;
}

public function getArgumentAccess(): ArgumentAccessInterface
{
return $this->argumentAccess;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@

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;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

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 {
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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] === '.') {
Expand All @@ -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<string, mixed> $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';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@
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;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

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']) ) {
Expand All @@ -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.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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']) ) {
Expand All @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,17 @@

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;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

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']) ) {
Expand All @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@

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;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

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']) ) {
Expand All @@ -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);
Expand Down
Loading