diff --git a/core/lib/Drupal/Component/Utility/DiffArray.php b/core/lib/Drupal/Component/Utility/DiffArray.php new file mode 100644 index 0000000..5159cc9 --- /dev/null +++ b/core/lib/Drupal/Component/Utility/DiffArray.php @@ -0,0 +1,86 @@ + $value) { + if (!array_key_exists($key, $array2) || ((string) $array2[$key] !== (string) $value)) { + $difference[$key] = $value; + } + } + + return $difference; + } + + /** + * Recursively computes the difference of arrays with additional index check. + * + * This is a version of array_diff_assoc() that supports multidimensional + * arrays. + * + * @param array $array1 + * The array to compare from. + * @param array $array2 + * The array to compare to. + * + * @return array + * Returns an array containing all the values from array1 that are not present + * in array2. + */ + public static function diffAssocRecursive(array $array1, array $array2) { + $difference = array(); + + foreach ($array1 as $key => $value) { + if (is_array($value)) { + if (!array_key_exists($key, $array2) && !is_array($array2[$key])) { + $difference[$key] = $value; + } + else { + $new_diff = static::diffAssocRecursive($value, $array2[$key]); + if (!empty($new_diff)) { + $difference[$key] = $new_diff; + } + } + } + elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) { + $difference[$key] = $value; + } + } + + return $difference; + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php new file mode 100644 index 0000000..dffe30a --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php @@ -0,0 +1,89 @@ + 'DiffArray functionality', + 'description' => 'Tests the DiffArray helper class.', + 'group' => 'System', + ); + } + + function setUp() { + parent::setUp(); + + $this->array1 = array( + 'same' => 'yes', + 'different' => 'no', + 'array_empty_diff' => array(), + 'null' => NULL, + 'int_diff' => 1, + 'array_diff' => array('same' => 'same', 'array' => array('same' => 'same')), + 'new' => 'new', + ); + $this->array2 = array( + 'same' => 'yes', + 'different' => 'yes', + 'array_empty_diff' => array(), + 'null' => NULL, + 'int_diff' => '1', + 'array_diff' => array('same' => 'different', 'array' => array('same' => 'same')), + ); + } + + /** + * Tests DiffArray::diffAssoc(). + */ + public function testDiffAssoc() { + $expected = array( + 'different' => 'no', + 'new' => 'new', + ); + + $this->assertIdentical(DiffArray::diffAssoc($this->array1, $this->array2), $expected); + } + + /** + * Tests DiffArray::diffAssocRecursive(). + */ + public function testDiffAssocRecursive() { + $expected = array( + 'different' => 'no', + 'int_diff' => 1, + // The 'array' key should not be returned, as it's the same. + 'array_diff' => array('same' => 'same'), + 'new' => 'new', + ); + + $this->assertIdentical(DiffArray::diffAssocRecursive($this->array1, $this->array2), $expected); + } + +}