From 4998b8044530a83c617194d544b76a98f742386e Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 22 Aug 2016 11:21:50 +0100 Subject: [PATCH] FIX ArrayList sorting now caseinsensitive --- model/ArrayList.php | 7 ++- tests/model/ArrayListTest.php | 93 ++++++++++++++++++++++++++++++----- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/model/ArrayList.php b/model/ArrayList.php index 21db8740d..9bad92c0c 100644 --- a/model/ArrayList.php +++ b/model/ArrayList.php @@ -430,6 +430,7 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta // This the main sorting algorithm that supports infinite sorting params $multisortArgs = array(); $values = array(); + $firstRun = true; foreach($columnsToSort as $column => $direction) { // The reason these are added to columns is of the references, otherwise when the foreach // is done, all $values and $direction look the same @@ -437,7 +438,7 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta $sortDirection[$column] = $direction; // We need to subtract every value into a temporary array for sorting foreach($this->items as $index => $item) { - $values[$column][] = $this->extractValue($item, $column); + $values[$column][] = strtolower($this->extractValue($item, $column)); } // PHP 5.3 requires below arguments to be reference when using array_multisort together // with call_user_func_array @@ -445,6 +446,10 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta $multisortArgs[] = &$values[$column]; // First argument is the direction to be sorted, $multisortArgs[] = &$sortDirection[$column]; + if ($firstRun) { + $multisortArgs[] = defined('SORT_NATURAL') ? SORT_NATURAL : SORT_STRING; + } + $firstRun = false; } $multisortArgs[] = &$originalKeys; diff --git a/tests/model/ArrayListTest.php b/tests/model/ArrayListTest.php index 1f91a58d6..48f87ef91 100644 --- a/tests/model/ArrayListTest.php +++ b/tests/model/ArrayListTest.php @@ -247,39 +247,108 @@ class ArrayListTest extends SapphireTest { $list = new ArrayList(array( array('Name' => 'Steve'), (object) array('Name' => 'Bob'), - array('Name' => 'John') + array('Name' => 'John'), + array('Name' => 'bonny'), )); // Unquoted name $list1 = $list->sort('Name'); - $this->assertEquals($list1->toArray(), array( + $this->assertEquals(array( (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), array('Name' => 'John'), - array('Name' => 'Steve') - )); + array('Name' => 'Steve'), + ), $list1->toArray()); // Quoted name name $list2 = $list->sort('"Name"'); - $this->assertEquals($list2->toArray(), array( + $this->assertEquals(array( (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), array('Name' => 'John'), - array('Name' => 'Steve') - )); + array('Name' => 'Steve'), + ), $list2->toArray()); // Array (non-associative) $list3 = $list->sort(array('"Name"')); - $this->assertEquals($list3->toArray(), array( + $this->assertEquals(array( (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), array('Name' => 'John'), - array('Name' => 'Steve') - )); + array('Name' => 'Steve'), + ), $list3->toArray()); // Check original list isn't altered - $this->assertEquals($list->toArray(), array( + $this->assertEquals(array( array('Name' => 'Steve'), (object) array('Name' => 'Bob'), - array('Name' => 'John') + array('Name' => 'John'), + array('Name' => 'bonny'), + ), $list->toArray()); + } + + public function testNaturalSort() { + //natural sort is only available in 5.4+ + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->markTestSkipped(); + } + $list = new ArrayList(array( + array('Name' => 'Steve'), + (object) array('Name' => 'Bob'), + array('Name' => 'John'), + array('Name' => 'bonny'), + array('Name' => 'bonny1'), + array('Name' => 'bonny10'), + array('Name' => 'bonny2'), )); + + // Unquoted name + $list1 = $list->sort('Name'); + $this->assertEquals(array( + (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), + array('Name' => 'bonny1'), + array('Name' => 'bonny2'), + array('Name' => 'bonny10'), + array('Name' => 'John'), + array('Name' => 'Steve'), + ), $list1->toArray()); + + // Quoted name name + $list2 = $list->sort('"Name"'); + $this->assertEquals(array( + (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), + array('Name' => 'bonny1'), + array('Name' => 'bonny2'), + array('Name' => 'bonny10'), + array('Name' => 'John'), + array('Name' => 'Steve'), + ), $list2->toArray()); + + // Array (non-associative) + $list3 = $list->sort(array('"Name"')); + $this->assertEquals(array( + (object) array('Name' => 'Bob'), + array('Name' => 'bonny'), + array('Name' => 'bonny1'), + array('Name' => 'bonny2'), + array('Name' => 'bonny10'), + array('Name' => 'John'), + array('Name' => 'Steve'), + ), $list3->toArray()); + + // Check original list isn't altered + $this->assertEquals(array( + array('Name' => 'Steve'), + (object) array('Name' => 'Bob'), + array('Name' => 'John'), + array('Name' => 'bonny'), + array('Name' => 'bonny1'), + array('Name' => 'bonny10'), + array('Name' => 'bonny2'), + ), $list->toArray()); + } public function testSortSimpleASCOrder() {