Commit 6e779e02 by Qiang Xue

Fixed issue #7: ArrayHelper::multisort is not compatible with PHP 5.3

parent 6166e70f
...@@ -236,15 +236,17 @@ class ArrayHelper ...@@ -236,15 +236,17 @@ class ArrayHelper
* To sort by multiple keys, provide an array of keys here. * To sort by multiple keys, provide an array of keys here.
* @param boolean|array $ascending whether to sort in ascending or descending order. When * @param boolean|array $ascending whether to sort in ascending or descending order. When
* sorting by multiple keys with different ascending orders, use an array of ascending flags. * sorting by multiple keys with different ascending orders, use an array of ascending flags.
* @param integer|array $sortFlag the PHP sort flag. Valid values include: * @param integer|array $sortFlag the PHP sort flag. Valid values include
* `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, and `SORT_STRING | SORT_FLAG_CASE`. The last * `SORT_REGULAR`, `SORT_NUMERIC`, `SORT_STRING`, `SORT_LOCALE_STRING` and `SORT_NATURAL`.
* value is for sorting strings in case-insensitive manner. Please refer to * and `SORT_STRING | SORT_FLAG_CASE`. Please refer to [PHP manual](http://php.net/manual/en/function.sort.php)
* See [PHP manual](http://php.net/manual/en/function.sort.php) for more details. * for more details. When sorting by multiple keys with different sort flags, use an array of sort flags.
* When sorting by multiple keys with different sort flags, use an array of sort flags. * @param boolean|array $caseSensitive whether to sort string in case-sensitive manner. This parameter
* is used only when `$sortFlag` is either `SORT_STRING` or `SORT_NATURAL`.
* When sorting by multiple keys with different case sensitivities, use an array of boolean values.
* @throws InvalidParamException if the $ascending or $sortFlag parameters do not have * @throws InvalidParamException if the $ascending or $sortFlag parameters do not have
* correct number of elements as that of $key. * correct number of elements as that of $key.
*/ */
public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR) public static function multisort(&$array, $key, $ascending = true, $sortFlag = SORT_REGULAR, $caseSensitive = true)
{ {
$keys = is_array($key) ? $key : array($key); $keys = is_array($key) ? $key : array($key);
if (empty($keys) || empty($array)) { if (empty($keys) || empty($array)) {
...@@ -259,20 +261,30 @@ class ArrayHelper ...@@ -259,20 +261,30 @@ class ArrayHelper
if (is_scalar($sortFlag)) { if (is_scalar($sortFlag)) {
$sortFlag = array_fill(0, $n, $sortFlag); $sortFlag = array_fill(0, $n, $sortFlag);
} elseif (count($sortFlag) !== $n) { } elseif (count($sortFlag) !== $n) {
throw new InvalidParamException('The length of $ascending parameter must be the same as that of $keys.'); throw new InvalidParamException('The length of $sortFlag parameter must be the same as that of $keys.');
}
if (is_scalar($caseSensitive)) {
$caseSensitive = array_fill(0, $n, $caseSensitive);
} elseif (count($caseSensitive) !== $n) {
throw new InvalidParamException('The length of $caseSensitive parameter must be the same as that of $keys.');
} }
$args = array(); $args = array();
foreach ($keys as $i => $key) { foreach ($keys as $i => $key) {
$flag = $sortFlag[$i]; $flag = $sortFlag[$i];
if ($flag == (SORT_STRING | SORT_FLAG_CASE)) { $cs = $caseSensitive[$i];
$flag = SORT_STRING; if (!$cs && ($flag === SORT_STRING || $flag === SORT_NATURAL)) {
$column = array(); if (defined('SORT_FLAG_CASE')) {
foreach (static::getColumn($array, $key) as $k => $value) { $flag = $flag | SORT_FLAG_CASE;
$column[$k] = strtolower($value); $args[] = static::getColumn($array, $key);
} else {
$column = array();
foreach (static::getColumn($array, $key) as $k => $value) {
$column[$k] = mb_strtolower($value);
}
$args[] = $column;
} }
$args[] = $column;
} else { } else {
$args[] = static::getColumn($array, $key); $args[] = static::getColumn($array, $key);
} }
$args[] = $ascending[$i] ? SORT_ASC : SORT_DESC; $args[] = $ascending[$i] ? SORT_ASC : SORT_DESC;
$args[] = $flag; $args[] = $flag;
......
...@@ -40,11 +40,20 @@ class ArrayHelperTest extends \yii\test\TestCase ...@@ -40,11 +40,20 @@ class ArrayHelperTest extends \yii\test\TestCase
$array = array( $array = array(
array('name' => 'a', 'age' => 3), array('name' => 'a', 'age' => 3),
array('name' => 'b', 'age' => 2), array('name' => 'b', 'age' => 2),
array('name' => 'B', 'age' => 4),
array('name' => 'A', 'age' => 1), array('name' => 'A', 'age' => 1),
); );
ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING|SORT_FLAG_CASE, SORT_REGULAR));
ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR));
$this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]);
$this->assertEquals(array('name' => 'B', 'age' => 4), $array[1]);
$this->assertEquals(array('name' => 'a', 'age' => 3), $array[2]);
$this->assertEquals(array('name' => 'b', 'age' => 2), $array[3]);
ArrayHelper::multisort($array, array('name', 'age'), SORT_ASC, array(SORT_STRING, SORT_REGULAR), false);
$this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]); $this->assertEquals(array('name' => 'A', 'age' => 1), $array[0]);
$this->assertEquals(array('name' => 'a', 'age' => 3), $array[1]); $this->assertEquals(array('name' => 'a', 'age' => 3), $array[1]);
$this->assertEquals(array('name' => 'b', 'age' => 2), $array[2]); $this->assertEquals(array('name' => 'b', 'age' => 2), $array[2]);
$this->assertEquals(array('name' => 'B', 'age' => 4), $array[3]);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment