Overload $type parameter instead of adding another parameter for case insensitive sort

This commit is contained in:
Adrian Gunawan 2015-08-13 11:14:08 +10:00
parent a217556c13
commit f23e6589d0
2 changed files with 40 additions and 14 deletions

View file

@ -1317,7 +1317,7 @@ class HashTest extends CakeTestCase {
array('Item' => array('image' => 'Img10.jpg')), array('Item' => array('image' => 'Img10.jpg')),
array('Item' => array('image' => 'img2.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( $expected = array(
array('Item' => array('image' => 'img99.jpg')), array('Item' => array('image' => 'img99.jpg')),
array('Item' => array('image' => 'Img12.jpg')), array('Item' => array('image' => 'Img12.jpg')),
@ -1327,7 +1327,7 @@ class HashTest extends CakeTestCase {
); );
$this->assertEquals($expected, $result); $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( $expected = array(
array('Item' => array('image' => 'img1.jpg')), array('Item' => array('image' => 'img1.jpg')),
array('Item' => array('image' => 'img2.jpg')), array('Item' => array('image' => 'img2.jpg')),
@ -1436,7 +1436,7 @@ class HashTest extends CakeTestCase {
array('Item' => array('name' => 'Baz')), array('Item' => array('name' => 'Baz')),
array('Item' => array('name' => 'bat')), 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( $expected = array(
array('Item' => array('name' => 'Baby')), array('Item' => array('name' => 'Baby')),
array('Item' => array('name' => 'bar')), array('Item' => array('name' => 'bar')),
@ -1458,7 +1458,7 @@ class HashTest extends CakeTestCase {
array('Item' => array('name' => 'Baz')), array('Item' => array('name' => 'Baz')),
array('Item' => array('name' => 'bat')), 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( $expected = array(
array('Item' => array('name' => 'Baby')), array('Item' => array('name' => 'Baby')),
array('Item' => array('name' => 'bar')), array('Item' => array('name' => 'bar')),
@ -1468,6 +1468,17 @@ class HashTest extends CakeTestCase {
$this->assertEquals($expected, $sorted); $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() * Test insert()
* *

View file

@ -838,16 +838,18 @@ class Hash {
* - `string` Compare values as strings * - `string` Compare values as strings
* - `natural` Compare items as strings using "natural ordering" in a human friendly way. * - `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' * 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 array $data An array of data to sort
* @param string $path A Set-compatible path to the array value * @param string $path A Set-compatible path to the array value
* @param string $dir See directions above. Defaults to 'asc'. * @param string $dir See directions above. Defaults to 'asc'.
* @param string $type See direction types above. Defaults to 'regular'. * @param mixed $type See direction types above. Defaults to 'regular'.
* @param string $ignoreCase Case insensitive sorting. Defaults to false.
* @return array Sorted array of data * @return array Sorted array of data
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::sort * @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)) { if (empty($data)) {
return array(); return array();
} }
@ -870,15 +872,28 @@ class Hash {
$values = static::extract($result, '{n}.value'); $values = static::extract($result, '{n}.value');
$dir = strtolower($dir); $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 (!empty($type['ignoreCase'])) {
if (version_compare(PHP_VERSION, '5.4.0', '<')) { $ignoreCase = $type['ignoreCase'];
if ($type === 'natural' || $type === 'natural_ignore_case' || $type === 'regular_ignore_case') {
$type = 'regular';
} elseif ($type == 'string_ignore_case') {
$type = 'string';
} }
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') { if ($dir === 'asc') {