Skip to content

Commit

Permalink
Issue #2149: Add direction to backdrop_sort().
Browse files Browse the repository at this point in the history
  • Loading branch information
docwilmot authored and quicksketch committed Jan 15, 2018
1 parent 13dd4a0 commit 3802735
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 9 deletions.
26 changes: 17 additions & 9 deletions core/includes/common.inc
Expand Up @@ -7010,20 +7010,24 @@ function element_info_property($type, $property_name, $default = NULL) {
* An array of keys to sort by. Values must be PHP sorting type flags,
* either SORT_NUMERIC or SORT_STRING, and default to SORT_NUMERIC if an
* unindexed array is passed in.
* @param string $dir
* The sort direction. Values must be either SORT_ASC or SORT_DESC.
*
* Example usage:
* @code
* // Sort by a single numeric key:
* backdrop_sort($my_array, array('weight' => SORT_NUMERIC));
*
* // Short-hand sort by a numeric key:
* // Shorthand sort by a numeric key:
* backdrop_sort($my_array, array('weight'));
*
* // Sort by numeric and string keys.
* backdrop_sort($my_array, array('weight' => SORT_NUMERIC, 'title' => SORT_STRING));
* @endcode
*
* @since 1.9.0 The $dir parameter was added.
*/
function backdrop_sort(array &$array, array $keys = array('weight')) {
function backdrop_sort(array &$array, array $keys = array('weight'), $dir = SORT_ASC) {
// Ensure all keys have a sort value.
$new_keys = array();
foreach ($keys as $index => $sort) {
Expand Down Expand Up @@ -7051,7 +7055,7 @@ function backdrop_sort(array &$array, array $keys = array('weight')) {
$key_sort = reset($keys);

if ($key_sort === SORT_STRING) {
uasort($array, function($a, $b) use ($key) {
uasort($array, function($a, $b) use ($key, $dir) {
if (!is_array($a) || !is_array($b)) {
return 0;
}
Expand All @@ -7061,11 +7065,12 @@ function backdrop_sort(array &$array, array $keys = array('weight')) {
if (!isset($b[$key])) {
$b[$key] = '';
}
return strnatcasecmp($a[$key], $b[$key]);
$cmp = strnatcasecmp($a[$key], $b[$key]);
return ($dir == SORT_DESC) ? -$cmp : $cmp;
});
}
else {
uasort($array, function($a, $b) use ($key) {
uasort($array, function($a, $b) use ($key, $dir) {
if (!is_array($a) || !is_array($b)) {
return 0;
}
Expand All @@ -7076,7 +7081,8 @@ function backdrop_sort(array &$array, array $keys = array('weight')) {
$b[$key] = 0;
}
if ($a[$key] != $b[$key]) {
return $a[$key] < $b[$key] ? -1 : 1;
$cmp = $a[$key] < $b[$key] ? -1 : 1;
return ($dir == SORT_DESC) ? -$cmp : $cmp;
}
// Equal values, return 0.
return 0;
Expand All @@ -7086,7 +7092,7 @@ function backdrop_sort(array &$array, array $keys = array('weight')) {
// If doing a multiple-key comparison, use a recursive callback.
else {
$keys_map = array_keys($keys);
$recursive_callback = function ($a, $b, $key_index = 0) use ($keys, $keys_map, &$recursive_callback) {
$recursive_callback = function ($a, $b, $key_index = 0) use ($keys, $keys_map, $dir, &$recursive_callback) {
$key = $keys_map[$key_index];
if (!is_array($a) || !is_array($b)) {
return 0;
Expand All @@ -7104,12 +7110,14 @@ function backdrop_sort(array &$array, array $keys = array('weight')) {
}
}
else {
$cmp = 0;
if ($keys[$key] === SORT_STRING) {
return strnatcasecmp($a[$key], $b[$key]);
$cmp = strnatcasecmp($a[$key], $b[$key]);
}
else {
return ($a[$key] < $b[$key]) ? -1 : 1;
$cmp = ($a[$key] < $b[$key]) ? -1 : 1;
}
return ($dir == SORT_DESC) ? -$cmp : $cmp;
}
return 0;
};
Expand Down
111 changes: 111 additions & 0 deletions core/modules/simpletest/tests/common.test
Expand Up @@ -3093,6 +3093,117 @@ class CommonBackdropAddFeedTestCase extends BackdropWebTestCase {
}
}

/**
* Test that backdrop_sort() works correctly.
*/
class CommonBackdropSortUnitTest extends BackdropUnitTestCase {

/**
* Array to use for testing.
*
* @var array
*/
protected $test_array;

function setUp() {
parent::setUp();

$this->test_array = array(
'breadcrumb' => array(
'info' => 'Breadcrumb',
'weight' => 4,
'description' => 'The current page breadcrumb trail.',
'render last' => TRUE,
),
'main-menu' => array(
'info' => 'Primary navigation',
'weight' => 2,
'description' => 'A hierarchical list of links for the Primary navigation.',
),
'recent' => array(
'info' => 'Recent content',
'weight' => 3,
'description' => 'A list of recently published content.',
),
'content' => array(
'info' => 'Content block',
'weight' => 1,
'description' => 'Displays a node in a block.',
'class' => 'NodeBlock',
),
'form' => array(
'info' => 'Search form',
'weight' => -2,
'description' => 'The search form for searching site content.',
),
'custom_block' => array(
'info' => 'Add a custom block',
'weight' => -1,
'description' => 'A basic block for adding custom text.',
'class' => 'BlockText',
),
);
}

/**
* Tests backdrop_sort().
*/
public function testBackdropSort() {
$expected = array(
'form',
'custom_block',
'content',
'main-menu',
'recent',
'breadcrumb',
);

// Sort by a single numeric key.
backdrop_sort($this->test_array, array('weight' => SORT_NUMERIC));
$this->assertIdentical(array_keys($this->test_array), $expected);

// Sort by direction.
backdrop_sort($this->test_array, array('weight' => SORT_NUMERIC), SORT_DESC);
$this->assertIdentical(array_keys($this->test_array), array_reverse($expected));

$expected = array(
'custom_block',
'main-menu',
'recent',
'content',
'breadcrumb',
'form',
);

// Sort by a single string key.
backdrop_sort($this->test_array, array('description' => SORT_STRING));
$this->assertIdentical(array_keys($this->test_array), $expected);

// Sort by direction.
backdrop_sort($this->test_array, array('description' => SORT_STRING), SORT_DESC);
$this->assertIdentical(array_keys($this->test_array), array_reverse($expected));

$expected = array(
'form',
'custom_block',
'content',
'main-menu',
'recent',
'breadcrumb',
);

// Sort by numeric and string keys.
backdrop_sort($this->test_array, array('weight' => SORT_NUMERIC, 'info' => SORT_STRING));
$this->assertIdentical(array_keys($this->test_array), $expected);

// Sort by direction.
backdrop_sort($this->test_array, array('weight' => SORT_NUMERIC, 'info' => SORT_STRING), SORT_DESC);
$this->assertIdentical(array_keys($this->test_array), array_reverse($expected));

}

}

/**
* Test array diff functions.
*/
Expand Down
6 changes: 6 additions & 0 deletions core/modules/simpletest/tests/simpletest.tests.info
Expand Up @@ -382,6 +382,12 @@ description = Make sure that backdrop_add_feed() works correctly with various co
group = Common
file = common.test

[CommonBackdropSortUnitTest]
name = backdrop_sort() tests
description = Test that backdrop_sort() works correctly.
group = Common
file = common.test

[ArrayDiffUnitTest]
name = Array differences
description = Performs tests on backdrop_array_diff_assoc_recursive().
Expand Down

1 comment on commit 3802735

@backdrop-ci
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.