Issue #2151223 by damiankloip: Add a method to SortArray to sort by weight and title.

8.0.x
Nathaniel Catchpole 2014-01-06 12:40:52 +00:00
parent c84786171e
commit 281cda847e
3 changed files with 131 additions and 8 deletions

View File

@ -90,6 +90,34 @@ class SortArray {
return static::sortByKeyString($a, $b, '#title'); return static::sortByKeyString($a, $b, '#title');
} }
/**
* Sorts a structured array firstly by weight, then by title.
*
* @param array $a
* The first item to compare.
* @param array $b
* The second item to compare.
* @param string $weight_key
* (optional) The weight key to use. Defaults to 'weight'.
* @param string $title_key
* (optional) The title key to use. Defaults to 'title'.
*
* @return int
* The comparison result for uasort().
*/
public static function sortByWeightAndTitleKey($a, $b, $weight_key = 'weight', $title_key = 'title') {
$a = (array) $a;
$b = (array) $b;
$weight_cmp = static::sortByKeyInt($a, $b, $weight_key);
if ($weight_cmp === 0) {
return static::sortByKeyString($a, $b, $title_key);
}
return $weight_cmp;
}
/** /**
* Sorts a string array item by an arbitrary key. * Sorts a string array item by an arbitrary key.
* *

View File

@ -205,14 +205,7 @@ class Language {
* The array of language objects keyed by langcode. * The array of language objects keyed by langcode.
*/ */
public static function sort(&$languages) { public static function sort(&$languages) {
uasort($languages, function ($a, $b) { uasort($languages, 'Drupal\Component\Utility\SortArray::sortByWeightAndTitleKey');
$a_weight = isset($a->weight) ? $a->weight : 0;
$b_weight = isset($b->weight) ? $b->weight : 0;
if ($a_weight == $b_weight) {
return strnatcasecmp($a->name, $b->name);
}
return ($a_weight < $b_weight) ? -1 : 1;
});
} }
} }

View File

@ -323,4 +323,106 @@ class SortArrayTest extends UnitTestCase {
return $tests; return $tests;
} }
/**
* Tests SortArray::sortByWeightAndTitleKey() input against expected output.
*
* @dataProvider providerTestSortByWeightAndTitleKey
*
* @param array $a
* The first input item for comparison.
* @param array $b
* The second item for comparison.
* @param integer $expected
* The expected output from calling the method.
*/
public function testSortByWeightAndTitleKey($a, $b, $expected) {
$result = SortArray::sortByWeightAndTitleKey($a, $b);
$this->assertEquals($expected, $result);
}
/**
* Data provider for testSortByWeightAndTitleKey.
*
* @return array
* An array of test data.
*/
public function providerTestSortByWeightAndTitleKey() {
$stdclass_title_1 = new \stdClass();
$stdclass_title_1->title = 'a';
$stdclass_title_2 = new \stdClass();
$stdclass_title_2->title = 'b';
$stdclass_weight_1 = new \stdClass();
$stdclass_weight_1->weight = 1;
$stdclass_weight_2 = new \stdClass();
$stdclass_weight_2->weight = 2;
$stdclass_weight_3 = clone $stdclass_weight_1;
return array(
array(
array(),
array(),
0
),
array(
array('weight' => 1),
array('weight' => 2),
-1
),
array(
array('weight' => 2),
array('weight' => 1),
1
),
array(
array('title' => 'b', 'weight' => 1),
array('title' => 'a', 'weight' => 2),
-1
),
array(
array('title' => 'a', 'weight' => 2),
array('title' => 'b', 'weight' => 1),
1
),
array(
array('title' => 'a', 'weight' => 1),
array('title' => 'b', 'weight' => 1),
-1
),
array(
array('title' => 'b', 'weight' => 1),
array('title' => 'a', 'weight' => 1),
1
),
array(
array('title' => 'a'),
array('title' => 'b'),
-1
),
array(
array('title' => 'A'),
array('title' => 'a'),
0
),
array(
$stdclass_title_1,
$stdclass_title_2,
-1
),
array(
$stdclass_weight_1,
$stdclass_weight_2,
-1
),
array(
$stdclass_weight_1,
$stdclass_weight_3,
0
),
);
}
} }