From: Andrew Garrett Date: Wed, 20 Aug 2008 14:08:50 +0000 (+0000) Subject: Use a nice fancy deep-merge function for merging arrays in SiteConfiguration (newly... X-Git-Tag: 1.31.0-rc.0~45774 X-Git-Url: https://git.cyclocoop.org/%27.%24link.%27?a=commitdiff_plain;h=4b5d8c21a8dec3faea76c189dd61cc7951520ed1;p=lhc%2Fweb%2Fwiklou.git Use a nice fancy deep-merge function for merging arrays in SiteConfiguration (newly written), and move the merging of config options and globals deeper into get(), so we don't need to duplicate the same functionality in the entry points. --- diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index dabe06d53b..25327e6f19 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2242,6 +2242,28 @@ function wfArrayMerge( $array1/* ... */ ) { return $out; } +/** + * Merge multiple arrays together. + * On encountering duplicate keys, merge the two, but ONLY if they're arrays. + * PHP's array_merge_recursive() merges ANY duplicate values into arrays, + * which is not fun + */ +function wfArrayDeepMerge( $array1/* ... */ ) { + $out = $array1; + for( $i=1; $i< func_num_args(); $i++ ) { + foreach( func_get_arg( $i ) as $key => $value ) { + if ( isset($out[$key]) && is_array($out[$key]) && is_array($value) ) { + $out[$key] = wfArrayDeepMerge( $out[$key], $value ); + } elseif ( !isset($out[$key] || !$out[$key] ) { + // Values that evaluate to true given precedence, for the primary purpose of merging permissions arrays. + $out[$key] = $value; + } + } + } + + return $out; +} + /** * Make a URL index, appropriate for the el_index field of externallinks. */ diff --git a/includes/SiteConfiguration.php b/includes/SiteConfiguration.php index 9d091097f1..49291e2040 100644 --- a/includes/SiteConfiguration.php +++ b/includes/SiteConfiguration.php @@ -32,6 +32,13 @@ class SiteConfiguration { * @return Mixed the value of the setting requested. */ function get( $settingName, $wiki, $suffix, $params = array(), $wikiTags = array() ) { + $append = false; + $var = $settingName; + if ( substr( $varname, 0, 1 ) == '+' ) { + $append = true; + $var = substr( $settingName, 1 ); + } + if ( array_key_exists( $settingName, $this->settings ) ) { $thisSetting =& $this->settings[$settingName]; do { @@ -47,7 +54,7 @@ class SiteConfiguration { foreach ( $wikiTags as $tag ) { if ( array_key_exists( $tag, $thisSetting ) ) { if ( isset($retval) && is_array($retval) && is_array($thisSetting[$tag]) ) { - $retval = array_merge( $retval, $thisSetting[$tag] ); + $retval = wfArrayDeepMerge( $retval, $thisSetting[$tag] ); } else { $retval = $thisSetting[$tag]; } @@ -55,14 +62,14 @@ class SiteConfiguration { } elseif ( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) { if (!isset($retval)) $retval = array(); - $retval = array_merge( $retval, $thisSetting["+$tag"] ); + $retval = wfArrayDeepMerge( $retval, $thisSetting["+$tag"] ); } } // Do suffix settings if ( array_key_exists( $suffix, $thisSetting ) ) { if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) { - $retval = array_merge( $retval, $thisSetting[$suffix] ); + $retval = wfArrayDeepMerge( $retval, $thisSetting[$suffix] ); } else { $retval = $thisSetting[$suffix]; } @@ -70,13 +77,13 @@ class SiteConfiguration { } elseif ( array_key_exists( "+$suffix", $thisSetting ) && is_array($thisSetting["+$suffix"]) ) { if (!isset($retval)) $retval = array(); - $retval = array_merge( $retval, $thisSetting["+$suffix"] ); + $retval = wfArrayDeepMerge( $retval, $thisSetting["+$suffix"] ); } // Fall back to default. if ( array_key_exists( 'default', $thisSetting ) ) { if ( isset($retval) && is_array($retval) && is_array($thisSetting['default']) ) { - $retval = array_merge( $retval, $thisSetting['default'] ); + $retval = wfArrayDeepMerge( $retval, $thisSetting['default'] ); } else { $retval = $thisSetting['default']; } @@ -93,6 +100,10 @@ class SiteConfiguration { $retval = $this->doReplace( '$' . $key, $value, $retval ); } } + + if ( $append && is_array($value) && is_array( $GLOBALS[$var] ) ) + $value = wfArrayDeepMerge( $value, $GLOBALS[$var] ); + return $retval; } @@ -121,16 +132,8 @@ class SiteConfiguration { function getAll( $wiki, $suffix, $params, $wikiTags = array() ) { $localSettings = array(); foreach ( $this->settings as $varname => $stuff ) { - $append = false; - $var = $varname; - if ( substr( $varname, 0, 1 ) == '+' ) { - $append = true; - $var = substr( $varname, 1 ); - } - $value = $this->get( $varname, $wiki, $suffix, $params, $wikiTags ); - if ( $append && is_array($value) && is_array( $GLOBALS[$var] ) ) - $value = array_merge( $value, $GLOBALS[$var] ); + if ( !is_null( $value ) ) { $localSettings[$var] = $value; } @@ -187,16 +190,7 @@ class SiteConfiguration { function extractGlobal( $setting, $wiki, $suffix, $params, $wikiTags = array() ) { $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags ); if ( !is_null( $value ) ) { - if (substr($setting,0,1) == '+' && is_array($value)) { - $setting = substr($setting,1); - if ( is_array($GLOBALS[$setting]) ) { - $GLOBALS[$setting] = array_merge( $GLOBALS[$setting], $value ); - } else { - $GLOBALS[$setting] = $value; - } - } else { - $GLOBALS[$setting] = $value; - } + $GLOBALS[$setting] = $value; } }