From f23e6589d0e4a318d3f1da873b034eab010379c8 Mon Sep 17 00:00:00 2001 From: Adrian Gunawan Date: Thu, 13 Aug 2015 11:14:08 +1000 Subject: [PATCH] Overload $type parameter instead of adding another parameter for case insensitive sort --- lib/Cake/Test/Case/Utility/HashTest.php | 19 +++++++++++--- lib/Cake/Utility/Hash.php | 35 ++++++++++++++++++------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/HashTest.php b/lib/Cake/Test/Case/Utility/HashTest.php index 51841e1f8..64858bfbb 100644 --- a/lib/Cake/Test/Case/Utility/HashTest.php +++ b/lib/Cake/Test/Case/Utility/HashTest.php @@ -1317,7 +1317,7 @@ class HashTest extends CakeTestCase { array('Item' => array('image' => 'Img10.jpg')), array('Item' => array('image' => 'img2.jpg')), ); - $result = Hash::sort($items, '{n}.Item.image', 'desc', 'natural', true); + $result = Hash::sort($items, '{n}.Item.image', 'desc', ['type' => 'natural', 'ignoreCase' => true]); $expected = array( array('Item' => array('image' => 'img99.jpg')), array('Item' => array('image' => 'Img12.jpg')), @@ -1327,7 +1327,7 @@ class HashTest extends CakeTestCase { ); $this->assertEquals($expected, $result); - $result = Hash::sort($items, '{n}.Item.image', 'asc', 'natural', true); + $result = Hash::sort($items, '{n}.Item.image', 'asc', ['type' => 'natural', 'ignoreCase' => true]); $expected = array( array('Item' => array('image' => 'img1.jpg')), array('Item' => array('image' => 'img2.jpg')), @@ -1436,7 +1436,7 @@ class HashTest extends CakeTestCase { array('Item' => array('name' => 'Baz')), array('Item' => array('name' => 'bat')), ); - $sorted = Hash::sort($toSort, '{n}.Item.name', 'asc', 'string', true); + $sorted = Hash::sort($toSort, '{n}.Item.name', 'asc', ['type' => 'string', 'ignoreCase' => true]); $expected = array( array('Item' => array('name' => 'Baby')), array('Item' => array('name' => 'bar')), @@ -1458,7 +1458,7 @@ class HashTest extends CakeTestCase { array('Item' => array('name' => 'Baz')), array('Item' => array('name' => 'bat')), ); - $sorted = Hash::sort($toSort, '{n}.Item.name', 'asc', 'regular', true); + $sorted = Hash::sort($toSort, '{n}.Item.name', 'asc', ['type' => 'regular', 'ignoreCase' => true]); $expected = array( array('Item' => array('name' => 'Baby')), array('Item' => array('name' => 'bar')), @@ -1468,6 +1468,17 @@ class HashTest extends CakeTestCase { $this->assertEquals($expected, $sorted); } +/** + * Tests that sort() throws an InvalidArgumentException when providing an invalid input. + * + * @expectedException InvalidArgumentException + * @return void + */ + public function testSortInvalidType() { + $toSort = ['a', 'b', 'c']; + Hash::sort($toSort, '{n}', 'asc', ['regular'], true); + } + /** * Test insert() * diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index c14fe5c5b..6cf14a01e 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -838,16 +838,18 @@ class Hash { * - `string` Compare values as strings * - `natural` Compare items as strings using "natural ordering" in a human friendly way. * Will sort foo10 below foo2 as an example. Requires PHP 5.4 or greater or it will fallback to 'regular' + * To do case insensitive sorting, pass the type as an array as follows: + * ['type' => 'regular', 'ignoreCase' => true] * * @param array $data An array of data to sort * @param string $path A Set-compatible path to the array value * @param string $dir See directions above. Defaults to 'asc'. - * @param string $type See direction types above. Defaults to 'regular'. - * @param string $ignoreCase Case insensitive sorting. Defaults to false. + * @param mixed $type See direction types above. Defaults to 'regular'. * @return array Sorted array of data * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::sort + * @throws InvalidArgumentException */ - public static function sort(array $data, $path, $dir = 'asc', $type = 'regular', $ignoreCase = false) { + public static function sort(array $data, $path, $dir = 'asc', $type = 'regular') { if (empty($data)) { return array(); } @@ -870,15 +872,28 @@ class Hash { $values = static::extract($result, '{n}.value'); $dir = strtolower($dir); - $type = strtolower($type); + $ignoreCase = false; + + // $type can be overloaded for case insensitive sort + if (is_array($type)) { - // Natural and case insensitive sort is only supported from >= 5.4.0 - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - if ($type === 'natural' || $type === 'natural_ignore_case' || $type === 'regular_ignore_case') { - $type = 'regular'; - } elseif ($type == 'string_ignore_case') { - $type = 'string'; + if (!empty($type['ignoreCase'])) { + $ignoreCase = $type['ignoreCase']; } + + if (!empty($type['ignoreCase'])) { + $type = $type['type']; + } else { + throw new InvalidArgumentException(__d('cake_dev', + 'Invalid parameter $type. It requires type key to be specified.' + )); + } + } else { + $type = strtolower($type); + } + + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $type = 'regular'; } if ($dir === 'asc') {