Skip to content

Commit fc1755b

Browse files
authored
Merge pull request #207 from KnpLabs/fix/unaccessible-property
[RFR] be able to sort on NULL relation with PropertyAccessor
2 parents f0f8303 + 84eb450 commit fc1755b

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php

+19-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Knp\Component\Pager\Event\ItemsEvent;
66
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
7+
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
78
use Symfony\Component\PropertyAccess\PropertyAccess;
89
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
910
use Knp\Component\Pager\PaginatorInterface;
@@ -78,16 +79,25 @@ private function proxySortFunction(&$target, $sortField, $sortDirection) {
7879
* @param mixed $object1 first object to compare
7980
* @param mixed $object2 second object to compare
8081
*
81-
* @return boolean
82+
* @return int
8283
*/
8384
private function sortFunction($object1, $object2)
8485
{
8586
if (!$this->propertyAccessor) {
8687
throw new \UnexpectedValueException('You need symfony/property-access component to use this sorting function');
8788
}
8889

89-
$fieldValue1 = $this->propertyAccessor->getValue($object1, $this->currentSortingField);
90-
$fieldValue2 = $this->propertyAccessor->getValue($object2, $this->currentSortingField);
90+
try {
91+
$fieldValue1 = $this->propertyAccessor->getValue($object1, $this->currentSortingField);
92+
} catch (UnexpectedTypeException $e) {
93+
return -1 * $this->getSortCoefficient();
94+
}
95+
96+
try {
97+
$fieldValue2 = $this->propertyAccessor->getValue($object2, $this->currentSortingField);
98+
} catch (UnexpectedTypeException $e) {
99+
return 1 * $this->getSortCoefficient();
100+
}
91101

92102
if (is_string($fieldValue1)) {
93103
$fieldValue1 = mb_strtolower($fieldValue1);
@@ -101,7 +111,12 @@ private function sortFunction($object1, $object2)
101111
return 0;
102112
}
103113

104-
return ($fieldValue1 > $fieldValue2 ? 1 : -1) * ($this->sortDirection === 'asc' ? 1 : -1);
114+
return ($fieldValue1 > $fieldValue2 ? 1 : -1) * $this->getSortCoefficient();
115+
}
116+
117+
private function getSortCoefficient()
118+
{
119+
return $this->sortDirection === 'asc' ? 1 : -1;
105120
}
106121

107122
public static function getSubscribedEvents()

tests/Test/Pager/Subscriber/Sortable/ArraySubscriberTest.php

+30
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,34 @@ public function shouldSortWithCustomCallback()
8282
$this->assertEquals('hot', $array[0]['name']);
8383

8484
}
85+
86+
/**
87+
* @test
88+
*/
89+
public function shouldSortEvenWhenTheSortPropertyIsNotAccessible()
90+
{
91+
$array = array(
92+
array('entry' => array('sortProperty' => 2)),
93+
array('entry' => array()),
94+
array('entry' => array('sortProperty' => 1)),
95+
);
96+
97+
$itemsEvent = new ItemsEvent(0, 10);
98+
$itemsEvent->target = &$array;
99+
$itemsEvent->options = array(PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord');
100+
101+
$arraySubscriber = new ArraySubscriber();
102+
103+
// test asc sort
104+
$_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc');
105+
$arraySubscriber->items($itemsEvent);
106+
$this->assertEquals(false, isset($array[0]['entry']['sortProperty']));
107+
108+
$itemsEvent->unsetCustomPaginationParameter('sorted');
109+
110+
// test desc sort
111+
$_GET ['ord'] = 'desc';
112+
$arraySubscriber->items($itemsEvent);
113+
$this->assertEquals(2, $array[0]['entry']['sortProperty']);
114+
}
85115
}

0 commit comments

Comments
 (0)