Skip to content

Commit

Permalink
Overload $type parameter instead of adding another parameter for case…
Browse files Browse the repository at this point in the history
… insensitive sort
  • Loading branch information
Adrian Gunawan committed Aug 13, 2015
1 parent a217556 commit f23e658
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
19 changes: 15 additions & 4 deletions lib/Cake/Test/Case/Utility/HashTest.php
Expand Up @@ -1317,7 +1317,7 @@ public function testSortNaturalIgnoreCase() {
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')),
Expand All @@ -1327,7 +1327,7 @@ public function testSortNaturalIgnoreCase() {
);
$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')),
Expand Down Expand Up @@ -1436,7 +1436,7 @@ public function testSortStringIgnoreCase() {
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')),
Expand All @@ -1458,7 +1458,7 @@ public function testSortRegularIgnoreCase() {
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')),
Expand All @@ -1468,6 +1468,17 @@ public function testSortRegularIgnoreCase() {
$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()
*
Expand Down
35 changes: 25 additions & 10 deletions lib/Cake/Utility/Hash.php
Expand Up @@ -838,16 +838,18 @@ public static function apply(array $data, $path, $function) {
* - `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();
}
Expand All @@ -870,15 +872,28 @@ public static function sort(array $data, $path, $dir = 'asc', $type = 'regular',
$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') {
Expand Down

0 comments on commit f23e658

Please sign in to comment.