From 4652d81f1f052be25bbdaee6a65866bcfc7ffd64 Mon Sep 17 00:00:00 2001 From: Paul Le Corre Date: Tue, 6 Mar 2018 11:19:29 +0100 Subject: [PATCH 1/3] Fix sort for Elastica and Solarium --- .../Event/Subscriber/Paginate/ElasticaQuerySubscriber.php | 7 +++---- .../Pager/Event/Subscriber/Sortable/ArraySubscriber.php | 8 ++++++++ .../Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php | 8 ++++++++ .../Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php | 8 ++++++++ .../Event/Subscriber/Sortable/ElasticaQuerySubscriber.php | 8 ++++++++ .../Event/Subscriber/Sortable/PropelQuerySubscriber.php | 8 ++++++++ .../Event/Subscriber/Sortable/SolariumQuerySubscriber.php | 8 ++++++++ 7 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/Knp/Component/Pager/Event/Subscriber/Paginate/ElasticaQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Paginate/ElasticaQuerySubscriber.php index 723c3cd9..de530157 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Paginate/ElasticaQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Paginate/ElasticaQuerySubscriber.php @@ -19,16 +19,15 @@ public function items(ItemsEvent $event) list($searchable, $query) = $event->target; $query->setFrom($event->getOffset()); - $query->setLimit($event->getLimit()); + $query->setSize($event->getLimit()); $results = $searchable->search($query); $event->count = $results->getTotalHits(); - //Faceting is being replaced by aggregations + if ($results->hasAggregations()) { $event->setCustomPaginationParameter('aggregations', $results->getAggregations()); - } elseif ($results->hasFacets()) { - $event->setCustomPaginationParameter('facets', $results->getFacets()); } + $event->setCustomPaginationParameter('resultSet', $results); $event->items = $results->getResults(); $event->stopPropagation(); diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php index 461dad95..aa4520db 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php @@ -36,10 +36,18 @@ public function __construct(PropertyAccessorInterface $accessor = null) public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + if (!is_array($event->target) || empty($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]])) { return; } + $event->setCustomPaginationParameter('sorted', true); + if (isset($event->options[PaginatorInterface::SORT_FIELD_WHITELIST]) && !in_array($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]], $event->options[PaginatorInterface::SORT_FIELD_WHITELIST])) { throw new \UnexpectedValueException("Cannot sort by: [{$_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]]}] this field is not in whitelist"); } 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 cfd42639..5c4e7d47 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 @@ -11,7 +11,15 @@ class QuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + if ($event->target instanceof Query) { + $event->setCustomPaginationParameter('sorted', true); + if (isset($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]])) { $field = $_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]]; $dir = strtolower($_GET[$event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]]) == 'asc' ? 1 : -1; 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 74b0d58a..f0650266 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 @@ -13,7 +13,15 @@ class QuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + if ($event->target instanceof Query) { + $event->setCustomPaginationParameter('sorted', true); + if (isset($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]])) { $dir = isset($_GET[$event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]]) && strtolower($_GET[$event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]]) === 'asc' ? 'asc' : 'desc'; diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php index 509acb61..063f2ba4 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php @@ -12,7 +12,15 @@ class ElasticaQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + if (is_array($event->target) && 2 === count($event->target) && reset($event->target) instanceof SearchableInterface && end($event->target) instanceof Query) { + $event->setCustomPaginationParameter('sorted', true); + list($searchable, $query) = $event->target; if (isset($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]])) { diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php index 3cea640a..76e9d72b 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php @@ -10,8 +10,16 @@ class PropelQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + $query = $event->target; if ($query instanceof \ModelCriteria) { + $event->setCustomPaginationParameter('sorted', true); + if (isset($_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]])) { $part = $_GET[$event->options[PaginatorInterface::SORT_FIELD_PARAMETER_NAME]]; $directionParam = $event->options[PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME]; diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php index b41246a9..69b7273b 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php @@ -15,7 +15,15 @@ class SolariumQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { + // Check if the result has already been sorted + $customPaginationParameters = $event->getCustomPaginationParameters(); + if (!empty($customPaginationParameters['sorted']) ) { + return; + } + if (is_array($event->target) && 2 == count($event->target)) { + $event->setCustomPaginationParameter('sorted', true); + $values = array_values($event->target); list($client, $query) = $values; From acef1c456719b67c7cd854c349f28c50a1c7c215 Mon Sep 17 00:00:00 2001 From: Paul Le Corre Date: Tue, 20 Mar 2018 10:08:23 +0100 Subject: [PATCH 2/3] Fix tests --- src/Knp/Component/Pager/Event/ItemsEvent.php | 7 ++++++ .../Sortable/ArraySubscriberTest.php | 23 ++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Knp/Component/Pager/Event/ItemsEvent.php b/src/Knp/Component/Pager/Event/ItemsEvent.php index 9debcc69..c4c3da49 100644 --- a/src/Knp/Component/Pager/Event/ItemsEvent.php +++ b/src/Knp/Component/Pager/Event/ItemsEvent.php @@ -57,6 +57,13 @@ public function getCustomPaginationParameters() return $this->customPaginationParams; } + public function unsetCustomPaginationParameter($name) + { + if (isset($this->customPaginationParams[$name])) { + unset($this->customPaginationParams[$name]); + } + } + public function getLimit() { return $this->limit; diff --git a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php index cdd79acd..eae11f47 100644 --- a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php +++ b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php @@ -23,12 +23,17 @@ public function shouldSort() $itemsEvent = new ItemsEvent(0, 10); $itemsEvent->target = &$array; $itemsEvent->options = array(PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord'); - $_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc'); - $this->assertEquals(2, $array[0]['entry']['sortProperty']); $arraySubscriber = new ArraySubscriber(); + + // test asc sort + $_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc'); $arraySubscriber->items($itemsEvent); $this->assertEquals(1, $array[0]['entry']['sortProperty']); + + $itemsEvent->unsetCustomPaginationParameter('sorted'); + + // test desc sort $_GET ['ord'] = 'desc'; $arraySubscriber->items($itemsEvent); $this->assertEquals(3, $array[0]['entry']['sortProperty']); @@ -52,20 +57,26 @@ public function shouldSortWithCustomCallback() PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord', 'sortFunction' => function (&$target, $sortField, $sortDirection) { usort($target, function($object1, $object2) use ($sortField, $sortDirection) { - if ($object1[$sortField] == $object2[$sortField]) { + if ($object1[$sortField] === $object2[$sortField]) { return 0; } - return ($object1[$sortField] == 'hot' ? 1 : -1) * ($sortDirection == 'asc' ? 1 : -1); + return ($object1[$sortField] === 'hot' ? 1 : -1) * ($sortDirection === 'asc' ? 1 : -1); }); }, ); - $_GET = array('sort' => '.name', 'ord' => 'asc'); - $this->assertEquals('hot', $array[0]['name']); $arraySubscriber = new ArraySubscriber(); + + // test asc sort + $_GET = array('sort' => '.name', 'ord' => 'asc'); $arraySubscriber->items($itemsEvent); $this->assertEquals('cold', $array[0]['name']); + + + $itemsEvent->unsetCustomPaginationParameter('sorted'); + + // test desc sort $_GET['ord'] = 'desc'; $arraySubscriber->items($itemsEvent); $this->assertEquals('hot', $array[0]['name']); From bf5722037040d5d9b3f568cc98a18a863479dcae Mon Sep 17 00:00:00 2001 From: Paul Le Corre Date: Tue, 20 Mar 2018 10:54:46 +0100 Subject: [PATCH 3/3] Update comment --- .../Pager/Event/Subscriber/Sortable/ArraySubscriber.php | 2 +- .../Sortable/Doctrine/ODM/MongoDB/QuerySubscriber.php | 2 +- .../Event/Subscriber/Sortable/Doctrine/ORM/QuerySubscriber.php | 2 +- .../Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php | 2 +- .../Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php | 2 +- .../Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php index aa4520db..dfcfe34d 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php @@ -36,7 +36,7 @@ public function __construct(PropertyAccessorInterface $accessor = null) public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; 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 5c4e7d47..7a456940 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 @@ -11,7 +11,7 @@ class QuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; 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 f0650266..910745f0 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 @@ -13,7 +13,7 @@ class QuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php index 063f2ba4..99db79bc 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ElasticaQuerySubscriber.php @@ -12,7 +12,7 @@ class ElasticaQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php index 76e9d72b..b3b21be1 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/PropelQuerySubscriber.php @@ -10,7 +10,7 @@ class PropelQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return; diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php index 69b7273b..1a3d433d 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/SolariumQuerySubscriber.php @@ -15,7 +15,7 @@ class SolariumQuerySubscriber implements EventSubscriberInterface { public function items(ItemsEvent $event) { - // Check if the result has already been sorted + // Check if the result has already been sorted by an other sort subscriber $customPaginationParameters = $event->getCustomPaginationParameters(); if (!empty($customPaginationParameters['sorted']) ) { return;