Skip to content

Commit

Permalink
feature #228
Browse files Browse the repository at this point in the history
  • Loading branch information
qr committed Dec 2, 2020
1 parent 41c9ae6 commit 0e3b221
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/Subscriber/PostgresPaginateSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace GemeenteAmsterdam\FixxxSchuldhulp\Subscriber;

use Knp\Component\Pager\Event\BeforeEvent;
use Knp\Component\Pager\Event\Subscriber\Filtration\Doctrine\ORM\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Filtration\PropelQuerySubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class PostgresPaginateSubscriber implements EventSubscriberInterface
{
/**
* Lazy-load state tracker
* @var bool
*/
private $isLoaded = false;

public function before(BeforeEvent $event): void
{
// Do not lazy-load more than once
if ($this->isLoaded) {
return;
}

$disp = $event->getEventDispatcher();
// hook all standard filtration subscribers

$listeners = $disp->getListeners('knp_pager.items');
$querySubscriber = null;

foreach ($listeners as $listener) {
if ($listener[0] instanceof QuerySubscriber) {
$querySubscriber = $listener[0];
}
}

if (null !== $querySubscriber) {
$disp->removeSubscriber($querySubscriber);
}
$disp->addSubscriber(new PostgresQuerySubscriber($event->getRequest()));
$disp->addSubscriber(new PropelQuerySubscriber($event->getRequest()));

$this->isLoaded = true;
}

public static function getSubscribedEvents(): array
{
return [
'knp_pager.before' => ['before', 0],
];
}
}
84 changes: 84 additions & 0 deletions src/Subscriber/PostgresQuerySubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace GemeenteAmsterdam\FixxxSchuldhulp\Subscriber;

use Doctrine\ORM\Query;
use Knp\Component\Pager\Event\ItemsEvent;
use Knp\Component\Pager\Event\Subscriber\Filtration\Doctrine\ORM\Query\WhereWalker;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\Helper as QueryHelper;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;

class PostgresQuerySubscriber implements EventSubscriberInterface
{
/**
* @var Request
*/
private $request;

public function __construct(?Request $request)
{
$this->request = $request ?? Request::createFromGlobals();
}

public function items(ItemsEvent $event): void
{
if ($event->target instanceof Query) {
$filterValue = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]);
if (null === $filterValue || (empty($filterValue) && $filterValue !== '0')) {
return;
}
$filterName = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_FIELD_PARAMETER_NAME]);
if (!empty($filterName)) {
$columns = $filterName;
} elseif (!empty($event->options[PaginatorInterface::DEFAULT_FILTER_FIELDS])) {
$columns = $event->options[PaginatorInterface::DEFAULT_FILTER_FIELDS];
} else {
return;
}
$value = $this->getQueryParameter($event->options[PaginatorInterface::FILTER_VALUE_PARAMETER_NAME]);
if (false !== strpos($value, '*')) {
$value = str_replace('*', '%', $value);
}
if (is_string($columns) && false !== strpos($columns, ',')) {
$columns = explode(',', $columns);
}
$columns = (array) $columns;
if (isset($event->options[PaginatorInterface::FILTER_FIELD_WHITELIST])) {
trigger_deprecation('knplabs/knp-components', '2.4.0', \sprintf('%s option is deprecated. Use %s option instead.', PaginatorInterface::FILTER_FIELD_WHITELIST, PaginatorInterface::FILTER_FIELD_ALLOW_LIST));
$event->options[PaginatorInterface::FILTER_FIELD_ALLOW_LIST] = $event->options[PaginatorInterface::FILTER_FIELD_WHITELIST];
}
if (isset($event->options[PaginatorInterface::FILTER_FIELD_ALLOW_LIST])) {
foreach ($columns as $column) {
if (!in_array($column, $event->options[PaginatorInterface::FILTER_FIELD_ALLOW_LIST])) {
throw new \UnexpectedValueException("Cannot filter by: [{$column}] this field is not in whitelist");
}
}
}

$value = strtolower($value);

foreach ($columns as &$column) {
$column = strtolower($column);
}

$event->target
->setHint(WhereWalker::HINT_PAGINATOR_FILTER_VALUE, $value)
->setHint(WhereWalker::HINT_PAGINATOR_FILTER_COLUMNS, $columns);
QueryHelper::addCustomTreeWalker($event->target, WhereWalker::class);
}
}

public static function getSubscribedEvents(): array
{
return [
'knp_pager.items' => ['items', 0],
];
}

private function getQueryParameter(string $name): ?string
{
return $this->request->query->get($name);
}
}

0 comments on commit 0e3b221

Please sign in to comment.