diff --git a/includes/derivatives.inc b/includes/derivatives.inc index 9b44b9af..085a1ec6 100644 --- a/includes/derivatives.inc +++ b/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); } diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 7fd95f9b..78a2577e 100644 --- a/includes/ingest.form.inc +++ b/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; } diff --git a/includes/utilities.inc b/includes/utilities.inc index dcbaab02..13f97d21 100644 --- a/includes/utilities.inc +++ b/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]); + } +} diff --git a/islandora.info b/islandora.info index 55c50359..1e84ce16 100644 --- a/islandora.info +++ b/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 diff --git a/tests/utilities.test b/tests/utilities.test new file mode 100644 index 00000000..4bbaf3be --- /dev/null +++ b/tests/utilities.test @@ -0,0 +1,131 @@ + '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.'); + } +}