From 0e3b221fba89f6fdb2bea82a8b6f4e82205bf59b Mon Sep 17 00:00:00 2001 From: Bart Elferink Date: Wed, 2 Dec 2020 14:22:37 +0100 Subject: [PATCH] feature #228 --- src/Subscriber/PostgresPaginateSubscriber.php | 52 ++++++++++++ src/Subscriber/PostgresQuerySubscriber.php | 84 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/Subscriber/PostgresPaginateSubscriber.php create mode 100644 src/Subscriber/PostgresQuerySubscriber.php diff --git a/src/Subscriber/PostgresPaginateSubscriber.php b/src/Subscriber/PostgresPaginateSubscriber.php new file mode 100644 index 00000000..67864ade --- /dev/null +++ b/src/Subscriber/PostgresPaginateSubscriber.php @@ -0,0 +1,52 @@ +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], + ]; + } +} diff --git a/src/Subscriber/PostgresQuerySubscriber.php b/src/Subscriber/PostgresQuerySubscriber.php new file mode 100644 index 00000000..83471bbe --- /dev/null +++ b/src/Subscriber/PostgresQuerySubscriber.php @@ -0,0 +1,84 @@ +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); + } +}