? autocomplete.patch
? common.inc.patch
? mail_test.patch
? modules/simpletest/tests/mail_test.info
? modules/simpletest/tests/mail_test.module
? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1045
diff -u -p -r1.1045 common.inc
--- includes/common.inc	11 Nov 2009 00:48:56 -0000	1.1045
+++ includes/common.inc	12 Nov 2009 16:05:44 -0000
@@ -3062,7 +3062,7 @@ function base_path() {
  * which on normal pages is up through the preprocess step of theme('html').
  * Adding a link will overwrite a prior link with the exact same 'rel' and
  * 'href' attributes.
- * 
+ *
  * @param $attributes
  *   Associative array of element attributes including 'href' and 'rel'.
  * @param $header
@@ -3852,7 +3852,7 @@ function drupal_get_js($scope = 'header'
       case 'setting':
         $js_element = $element;
         $js_element['#value_prefix'] = $embed_prefix;
-        $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(call_user_func_array('array_merge_recursive', $item['data'])) . ");";
+        $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(call_user_func_array('array_merge_recursive_distinct', $item['data'])) . ");";
         $js_element['#value_suffix'] = $embed_suffix;
         $output .= theme('html_tag', array('element' => $js_element));
         break;
@@ -4950,7 +4950,7 @@ function drupal_render(&$elements) {
   if (isset($elements['#cache']) && $cached_output = drupal_render_cache_get($elements)) {
     return $cached_output;
   }
-  
+
   // If #markup is not empty, set #type. This allows to specify just #markup on
   // an element without setting #type.
   if (!empty($elements['#markup']) && !isset($elements['#type'])) {
@@ -6482,3 +6482,43 @@ function drupal_get_updaters() {
   }
   return $updaters;
 }
+
+/**
+ * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
+ * keys to arrays rather than overwriting the value in the first array with the duplicate
+ * value in the second array, as array_merge does. I.e., with array_merge_recursive,
+ * this happens (documented behavior):
+ *
+ * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
+ *     => array('key' => array('org value', 'new value'));
+ *
+ * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
+ * Matching keys' values in the second array overwrite those in the first array, as is the
+ * case with array_merge, i.e.:
+ *
+ * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
+ *     => array('key' => array('new value'));
+ *
+ * Parameters are passed by reference, though only for performance reasons. They're not
+ * altered by this function.
+ *
+ * @param array $array1
+ * @param array $array2
+ * @return array
+ * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
+ * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
+ */
+function array_merge_recursive_distinct(array &$array1, array &$array2)
+{
+  $merged = $array1;
+  foreach ($array2 as $key => &$value)
+  {
+    if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
+      $merged[$key] = array_merge_recursive_distinct($merged[$key], $value);
+    }
+    else {
+      $merged[$key] = $value;
+    }
+  }
+  return $merged;
+}
