Browse Source

Define new function islandora_sort_ordered

This function can replace calls to uasort with drupal_sort_weight. This
function will return a consistant sort order between PHP5 and PHP7 for
elements of the same weight by preserving the order of elements with the
same weight.

Under both PHP5 and PHP7 the order of elements with the same weight are
not guarenteed, and in practice the order of elements returned is
different between PHP5 and PHP7. This could cause some issues where the
order is changed depending on PHP version. This function gives us the
option of a consistant sort order.

This pull request also defines some new unit tests for the new function.
pull/665/head
Jonathan Green 8 years ago
parent
commit
60b848b922
  1. 2
      includes/derivatives.inc
  2. 4
      includes/ingest.form.inc
  3. 38
      includes/utilities.inc
  4. 1
      islandora.info
  5. 131
      tests/utilities.test

2
includes/derivatives.inc

@ -306,6 +306,6 @@ function islandora_get_derivative_list(AbstractObject $object, &$options) {
drupal_alter($hook, $derivatives, $object, $ds_modified_params);
}
uasort($derivatives, 'drupal_sort_weight');
islandora_sort_ordered($derivatives, array('weight'));
return islandora_filter_derivatives($derivatives, $options, $object);
}

4
includes/ingest.form.inc

@ -882,8 +882,6 @@ function islandora_ingest_form_load_include(array &$form_state) {
*
* Sorted by weight expected range between -50 to 50.
*
* The sort order is undefined for steps which have the same weight.
*
* @param array $form_state
* The Drupal form state.
*
@ -917,7 +915,7 @@ function islandora_ingest_form_get_steps(array &$form_state) {
foreach ($steps as $key => &$step) {
$step['id'] = $key;
}
uasort($steps, 'drupal_sort_weight');
islandora_sort_ordered($steps, array('weight'));
return $steps;
}

38
includes/utilities.inc

@ -966,3 +966,41 @@ function islandora_build_datastream_edit_registry(AbstractDatastream $datastream
drupal_alter(ISLANDORA_EDIT_DATASTREAM_REGISTRY_HOOK, $edit_registry, $context);
return $edit_registry;
}
/**
* Sorts a structured array by a user selectable element.
*
* This function will preserve the order of elements in the array with the
* same weight.
*
* @param array $array
* The array to be sorted.
* @param array $sort_keys
* An array containing the keys to sort the array by.
*/
function islandora_sort_ordered(&$array, $sort_keys) {
$array_temp = array();
foreach ($array as $key => $value) {
$weight = $value;
foreach ($sort_keys as $sort_key) {
if (is_array($weight) && isset($weight[$sort_key])) {
$weight = $weight[$sort_key];
}
else {
$weight = 0;
break;
}
}
$array_temp[$weight][$key] = $value;
unset($array[$key]);
}
ksort($array_temp);
foreach ($array_temp as $key => $value) {
$array += $value;
unset($array_temp[$key]);
}
}

1
islandora.info

@ -27,4 +27,5 @@ files[] = tests/datastream_versions.test
files[] = tests/datastream_cache.test
files[] = tests/derivatives.test
files[] = tests/datastream_validator_tests.test
files[] = tests/utilities.test
php = 5.3

131
tests/utilities.test

@ -0,0 +1,131 @@
<?php
/**
* @file
* Unit tests for the functions in the includes/utilities.inc file.
*/
/**
* Tests for drupal_sort_weight_ordered().
*/
class IslandoraSortOrderedTestCase extends DrupalUnitTestCase {
/**
* Return info about the tests.
*/
public static function getInfo() {
return array(
'name' => 'islandora_sort_ordered()',
'description' => 'Performs unit tests on islandora_sort_oredered().',
'group' => 'Islandora',
);
}
/**
* Test sort order when sorting by weight.
*/
public function testIslandoraSortOrderedSorting() {
module_load_include('inc', 'islandora', 'includes/utilities');
// The order of children with same weight should be preserved.
$element_mixed_weight = array(
'child5' => array('weight' => 10),
'child3' => array('weight' => -10),
'child1' => array(),
'child4' => array('weight' => 10),
'child2' => array(),
'child6' => array('weight' => 10),
'child9' => array(),
'child8' => array('weight' => 10),
'child7' => array(),
);
$expected = array(
'child3' => array('weight' => -10),
'child1' => array(),
'child2' => array(),
'child9' => array(),
'child7' => array(),
'child5' => array('weight' => 10),
'child4' => array('weight' => 10),
'child6' => array('weight' => 10),
'child8' => array('weight' => 10),
);
islandora_sort_ordered($element_mixed_weight, array('weight'));
$this->assertEqual($expected, $element_mixed_weight, 'Order of elements with the same weight is preserved.');
}
/**
* Make sure numeric keys are preserved.
*/
public function testIslandoraSortPreserveNumeric() {
module_load_include('inc', 'islandora', 'includes/utilities');
// The order of children with same weight should be preserved.
$element_mixed_weight = array(
5 => array('weight' => 10),
3 => array('weight' => -10),
1 => array(),
4 => array('weight' => 10),
2 => array(),
6 => array('weight' => 10),
9 => array(),
8 => array('weight' => 10),
7 => array(),
);
$expected = array(
3 => array('weight' => -10),
1 => array(),
2 => array(),
9 => array(),
7 => array(),
5 => array('weight' => 10),
4 => array('weight' => 10),
6 => array('weight' => 10),
8 => array('weight' => 10),
);
islandora_sort_ordered($element_mixed_weight, array('weight'));
$this->assertEqual($expected, $element_mixed_weight, 'Numeric keys are preserved while sorting.');
}
/**
* Test sort order when sorting by a key in a multidimensional array.
*/
public function testIslandoraSortOrderedMulti() {
module_load_include('inc', 'islandora', 'includes/utilities');
// The order of children with same weight should be preserved.
$element_mixed_weight = array(
'child5' => array('foo' => array('bar' => 10)),
'child3' => array('foo' => array('bar' => -10)),
'child1' => array('foo' => 6),
'child4' => array('foo' => array('bar' => 10)),
'child2' => array(),
'child6' => array('foo' => array('bar' => 10)),
'child9' => array(array('woot')),
'child8' => array('foo' => array('bar' => 10)),
'child7' => array(),
);
$expected = array(
'child3' => array('foo' => array('bar' => -10)),
'child1' => array('foo' => 6),
'child2' => array(),
'child9' => array(array('woot')),
'child7' => array(),
'child5' => array('foo' => array('bar' => 10)),
'child4' => array('foo' => array('bar' => 10)),
'child6' => array('foo' => array('bar' => 10)),
'child8' => array('foo' => array('bar' => 10)),
);
islandora_sort_ordered($element_mixed_weight, array('foo', 'bar'));
$this->assertEqual($expected, $element_mixed_weight, 'Sorting by multidimensional array works.');
}
}
Loading…
Cancel
Save