From 84eb450e4a37369419b6d93f22ba230d59d9dc80 Mon Sep 17 00:00:00 2001 From: Nicolas MURE Date: Fri, 7 Sep 2018 16:28:40 +0200 Subject: [PATCH] be able to sort on NULL relation with PropertyAccessor --- .../Subscriber/Sortable/ArraySubscriber.php | 23 +++++++++++--- .../Sortable/ArraySubscriberTest.php | 30 +++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php index dfcfe34d..99617685 100644 --- a/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php +++ b/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php @@ -4,6 +4,7 @@ use Knp\Component\Pager\Event\ItemsEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Knp\Component\Pager\PaginatorInterface; @@ -78,7 +79,7 @@ private function proxySortFunction(&$target, $sortField, $sortDirection) { * @param mixed $object1 first object to compare * @param mixed $object2 second object to compare * - * @return boolean + * @return int */ private function sortFunction($object1, $object2) { @@ -86,8 +87,17 @@ private function sortFunction($object1, $object2) throw new \UnexpectedValueException('You need symfony/property-access component to use this sorting function'); } - $fieldValue1 = $this->propertyAccessor->getValue($object1, $this->currentSortingField); - $fieldValue2 = $this->propertyAccessor->getValue($object2, $this->currentSortingField); + try { + $fieldValue1 = $this->propertyAccessor->getValue($object1, $this->currentSortingField); + } catch (UnexpectedTypeException $e) { + return -1 * $this->getSortCoefficient(); + } + + try { + $fieldValue2 = $this->propertyAccessor->getValue($object2, $this->currentSortingField); + } catch (UnexpectedTypeException $e) { + return 1 * $this->getSortCoefficient(); + } if (is_string($fieldValue1)) { $fieldValue1 = mb_strtolower($fieldValue1); @@ -101,7 +111,12 @@ private function sortFunction($object1, $object2) return 0; } - return ($fieldValue1 > $fieldValue2 ? 1 : -1) * ($this->sortDirection === 'asc' ? 1 : -1); + return ($fieldValue1 > $fieldValue2 ? 1 : -1) * $this->getSortCoefficient(); + } + + private function getSortCoefficient() + { + return $this->sortDirection === 'asc' ? 1 : -1; } public static function getSubscribedEvents() diff --git a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php index eae11f47..e4cc2dec 100644 --- a/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php +++ b/tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php @@ -82,4 +82,34 @@ public function shouldSortWithCustomCallback() $this->assertEquals('hot', $array[0]['name']); } + + /** + * @test + */ + public function shouldSortEvenWhenTheSortPropertyIsNotAccessible() + { + $array = array( + array('entry' => array('sortProperty' => 2)), + array('entry' => array()), + array('entry' => array('sortProperty' => 1)), + ); + + $itemsEvent = new ItemsEvent(0, 10); + $itemsEvent->target = &$array; + $itemsEvent->options = array(PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord'); + + $arraySubscriber = new ArraySubscriber(); + + // test asc sort + $_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc'); + $arraySubscriber->items($itemsEvent); + $this->assertEquals(false, isset($array[0]['entry']['sortProperty'])); + + $itemsEvent->unsetCustomPaginationParameter('sorted'); + + // test desc sort + $_GET ['ord'] = 'desc'; + $arraySubscriber->items($itemsEvent); + $this->assertEquals(2, $array[0]['entry']['sortProperty']); + } }