r39954 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r39953‎ | r39954 | r39955 >
Date:16:46, 25 August 2008
Author:ialex
Status:old
Tags:
Comment:
Tweaks for SiteConfiguration:
* Introduced SiteConfiguration::$siteParamsCallback, a callback function that returns an array of params to define custom parameters to replace and wiki tags so that they can be used at run time (e.g. for CentralAuth or SiteMatrix), can also override SiteConfiguration::siteFromDB(). See the documentation of that variable for further information. Backward compatibility is maintened for paramters passed to SiteConfiguration::get() and similar functions but the vaules returned by the callback function will override them.
* Added SiteConfiguration::arrayMerge() for merging arrays, written by Werdna. Warning: as array_merge(), it may change numeric keys, so don't use it for settings having namespaces index in keys.
* Removed SiteFromDB hook, deprecated by the callback function
* document a bit
Modified paths:
  • /trunk/phase3/docs/hooks.txt (modified) (history)
  • /trunk/phase3/includes/SiteConfiguration.php (modified) (history)

Diff [purge]

Index: trunk/phase3/docs/hooks.txt
@@ -1067,11 +1067,6 @@
10681068 $title: Title of the custom script/stylesheet page
10691069 $output: Current OutputPage object
10701070
1071 -'SiteFromDB': Customise the conversion of a database name to site information in SiteConfiguration
1072 -$db: The DB name being converted.
1073 -&$site: The site type (out).
1074 -&$lang: The "language" (subdomain)
1075 -
10761071 'SiteNoticeBefore': Before the sitenotice/anonnotice is composed
10771072 &$siteNotice: HTML returned as the sitenotice
10781073 Return true to allow the normal method of notice selection/rendering to work,
Index: trunk/phase3/includes/SiteConfiguration.php
@@ -8,21 +8,50 @@
99
1010 // Hide this pattern from Doxygen, which spazzes out at it
1111 /// @cond
12 -if (!defined('SITE_CONFIGURATION')) {
13 -define('SITE_CONFIGURATION', 1);
 12+if( !defined( 'SITE_CONFIGURATION' ) ){
 13+define( 'SITE_CONFIGURATION', 1 );
1414 /// @endcond
1515
1616 /**
1717 * This is a class used to hold configuration settings, particularly for multi-wiki sites.
18 - *
1918 */
2019 class SiteConfiguration {
21 - var $suffixes = array();
22 - var $wikis = array();
23 - var $settings = array();
24 - var $localVHosts = array();
2520
2621 /**
 22+ * Array of suffixes, for self::siteFromDB()
 23+ */
 24+ public $suffixes = array();
 25+
 26+ /**
 27+ * Array of wikis, should be the same as $wgLocalDatabases
 28+ */
 29+ public $wikis = array();
 30+
 31+ /**
 32+ * The whole array of settings
 33+ */
 34+ public $settings = array();
 35+
 36+ /**
 37+ * Array of domains that are local and can be handled by the same server
 38+ */
 39+ public $localVHosts = array();
 40+
 41+ /**
 42+ * A callback function that returns an array with the following keys (all
 43+ * optional):
 44+ * - suffix: site's suffix
 45+ * - lang: site's lang
 46+ * - tags: array of wiki tags
 47+ * - params: array of parameters to be replaced
 48+ * The function will receive the SiteConfiguration instance in the first
 49+ * argument and the wiki in the second one.
 50+ * if suffix and lang are passed they will be used for the return value of
 51+ * self::siteFromDB() and self::$suffixes will be ignored
 52+ */
 53+ public $siteParamsCallback = null;
 54+
 55+ /**
2756 * Retrieves a configuration setting for a given wiki.
2857 * @param $settingName String ID of the setting name to retrieve
2958 * @param $wiki String Wiki ID of the wiki in question.
@@ -31,72 +60,88 @@
3261 * @param $wikiTags Array The tags assigned to the wiki.
3362 * @return Mixed the value of the setting requested.
3463 */
35 - function get( $settingName, $wiki, $suffix, $params = array(), $wikiTags = array() ) {
36 - if ( array_key_exists( $settingName, $this->settings ) ) {
 64+ public function get( $settingName, $wiki, $suffix = null, $params = array(), $wikiTags = array() ) {
 65+ $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
 66+ return $this->getSetting( $settingName, $wiki, $params );
 67+ }
 68+
 69+ /**
 70+ * Really retrieves a configuration setting for a given wiki.
 71+ *
 72+ * @param $settingName String ID of the setting name to retrieve.
 73+ * @param $wiki String Wiki ID of the wiki in question.
 74+ * @param $params Array: array of parameters.
 75+ * @return Mixed the value of the setting requested.
 76+ */
 77+ protected function getSetting( $settingName, $wiki, /*array*/ $params ){
 78+ $retval = null;
 79+ if( array_key_exists( $settingName, $this->settings ) ) {
3780 $thisSetting =& $this->settings[$settingName];
3881 do {
3982 // Do individual wiki settings
40 - if ( array_key_exists( $wiki, $thisSetting ) ) {
 83+ if( array_key_exists( $wiki, $thisSetting ) ) {
4184 $retval = $thisSetting[$wiki];
4285 break;
43 - } elseif ( array_key_exists( "+$wiki", $thisSetting ) && is_array($thisSetting["+$wiki"]) ) {
 86+ } elseif( array_key_exists( "+$wiki", $thisSetting ) && is_array( $thisSetting["+$wiki"] ) ) {
4487 $retval = $thisSetting["+$wiki"];
4588 }
4689
4790 // Do tag settings
48 - foreach ( $wikiTags as $tag ) {
49 - if ( array_key_exists( $tag, $thisSetting ) ) {
50 - if ( isset($retval) && is_array($retval) && is_array($thisSetting[$tag]) ) {
51 - $retval = array_merge( $retval, $thisSetting[$tag] );
 91+ foreach( $params['tags'] as $tag ) {
 92+ if( array_key_exists( $tag, $thisSetting ) ) {
 93+ if ( isset( $retval ) && is_array( $retval ) && is_array( $thisSetting[$tag] ) ) {
 94+ $retval = self::arrayMerge( $retval, $thisSetting[$tag] );
5295 } else {
5396 $retval = $thisSetting[$tag];
5497 }
5598 break 2;
56 - } elseif ( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) {
57 - if (!isset($retval))
 99+ } elseif( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) {
 100+ if( !isset( $retval ) )
58101 $retval = array();
59 - $retval = array_merge( $retval, $thisSetting["+$tag"] );
 102+ $retval = self::arrayMerge( $retval, $thisSetting["+$tag"] );
60103 }
61104 }
62 -
63105 // Do suffix settings
64 - if ( array_key_exists( $suffix, $thisSetting ) ) {
65 - if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) {
66 - $retval = array_merge( $retval, $thisSetting[$suffix] );
67 - } else {
68 - $retval = $thisSetting[$suffix];
 106+ $suffix = $params['suffix'];
 107+ if( !is_null( $suffix ) ) {
 108+ if( array_key_exists( $suffix, $thisSetting ) ) {
 109+ if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) {
 110+ $retval = self::arrayMerge( $retval, $thisSetting[$suffix] );
 111+ } else {
 112+ $retval = $thisSetting[$suffix];
 113+ }
 114+ break;
 115+ } elseif( array_key_exists( "+$suffix", $thisSetting ) && is_array($thisSetting["+$suffix"]) ) {
 116+ if (!isset($retval))
 117+ $retval = array();
 118+ $retval = self::arrayMerge( $retval, $thisSetting["+$suffix"] );
69119 }
70 - break;
71 - } elseif ( array_key_exists( "+$suffix", $thisSetting ) && is_array($thisSetting["+$suffix"]) ) {
72 - if (!isset($retval))
73 - $retval = array();
74 - $retval = array_merge( $retval, $thisSetting["+$suffix"] );
75120 }
76121
77122 // Fall back to default.
78 - if ( array_key_exists( 'default', $thisSetting ) ) {
79 - if ( isset($retval) && is_array($retval) && is_array($thisSetting['default']) ) {
80 - $retval = array_merge( $retval, $thisSetting['default'] );
 123+ if( array_key_exists( 'default', $thisSetting ) ) {
 124+ if( is_array( $retval ) && is_array( $thisSetting['default'] ) ) {
 125+ $retval = self::arrayMerge( $retval, $thisSetting['default'] );
81126 } else {
82127 $retval = $thisSetting['default'];
83128 }
84129 break;
85130 }
86 - $retval = null;
87131 } while ( false );
88 - } else {
89 - $retval = NULL;
90132 }
91133
92 - if ( !is_null( $retval ) && count( $params ) ) {
93 - foreach ( $params as $key => $value ) {
 134+ if( !is_null( $retval ) && count( $params['params'] ) ) {
 135+ foreach ( $params['params'] as $key => $value ) {
94136 $retval = $this->doReplace( '$' . $key, $value, $retval );
95137 }
96138 }
97139 return $retval;
98140 }
99141
100 - /** Type-safe string replace; won't do replacements on non-strings */
 142+ /**
 143+ * Type-safe string replace; won't do replacements on non-strings
 144+ * private?
 145+ */
101146 function doReplace( $from, $to, $in ) {
102147 if( is_string( $in ) ) {
103148 return str_replace( $from, $to, $in );
@@ -118,19 +163,20 @@
119164 * @param $wikiTags Array The tags assigned to the wiki.
120165 * @return Array Array of settings requested.
121166 */
122 - function getAll( $wiki, $suffix, $params, $wikiTags = array() ) {
 167+ public function getAll( $wiki, $suffix = null, $params = array(), $wikiTags = array() ) {
 168+ $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
123169 $localSettings = array();
124 - foreach ( $this->settings as $varname => $stuff ) {
 170+ foreach( $this->settings as $varname => $stuff ) {
125171 $append = false;
126172 $var = $varname;
127173 if ( substr( $varname, 0, 1 ) == '+' ) {
128174 $append = true;
129175 $var = substr( $varname, 1 );
130176 }
131 -
132 - $value = $this->get( $varname, $wiki, $suffix, $params, $wikiTags );
133 - if ( $append && is_array($value) && is_array( $GLOBALS[$var] ) )
134 - $value = array_merge( $value, $GLOBALS[$var] );
 177+
 178+ $value = $this->getSetting( $varname, $wiki, $params );
 179+ if ( $append && is_array( $value ) && is_array( $GLOBALS[$var] ) )
 180+ $value = self::arrayMerge( $value, $GLOBALS[$var] );
135181 if ( !is_null( $value ) ) {
136182 $localSettings[$var] = $value;
137183 }
@@ -147,7 +193,7 @@
148194 * @param $wikiTags Array The tags assigned to the wiki.
149195 * @return bool The value of the setting requested.
150196 */
151 - function getBool( $setting, $wiki, $suffix, $wikiTags = array() ) {
 197+ public function getBool( $setting, $wiki, $suffix = null, $wikiTags = array() ) {
152198 return (bool)($this->get( $setting, $wiki, $suffix, array(), $wikiTags ) );
153199 }
154200
@@ -169,7 +215,7 @@
170216 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
171217 * @param $wikiTags Array The tags assigned to the wiki.
172218 */
173 - function extractVar( $setting, $wiki, $suffix, &$var, $params, $wikiTags = array() ) {
 219+ public function extractVar( $setting, $wiki, $suffix, &$var, $params = array(), $wikiTags = array() ) {
174220 $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
175221 if ( !is_null( $value ) ) {
176222 $var = $value;
@@ -184,13 +230,18 @@
185231 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
186232 * @param $wikiTags Array The tags assigned to the wiki.
187233 */
188 - function extractGlobal( $setting, $wiki, $suffix, $params, $wikiTags = array() ) {
189 - $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
 234+ public function extractGlobal( $setting, $wiki, $suffix = null, $params = array(), $wikiTags = array() ) {
 235+ $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
 236+ $this->extractGlobalSetting( $setting, $wiki, $params );
 237+ }
 238+
 239+ public function extractGlobalSetting( $setting, $wiki, $params ) {
 240+ $value = $this->getSetting( $setting, $wiki, $params );
190241 if ( !is_null( $value ) ) {
191242 if (substr($setting,0,1) == '+' && is_array($value)) {
192243 $setting = substr($setting,1);
193244 if ( is_array($GLOBALS[$setting]) ) {
194 - $GLOBALS[$setting] = array_merge( $GLOBALS[$setting], $value );
 245+ $GLOBALS[$setting] = self::arrayMerge( $GLOBALS[$setting], $value );
195246 } else {
196247 $GLOBALS[$setting] = $value;
197248 }
@@ -207,23 +258,93 @@
208259 * @param $params Array List of parameters. $.'key' is replaced by $value in all returned data.
209260 * @param $wikiTags Array The tags assigned to the wiki.
210261 */
211 - function extractAllGlobals( $wiki, $suffix, $params, $wikiTags = array() ) {
 262+ public function extractAllGlobals( $wiki, $suffix = null, $params = array(), $wikiTags = array() ) {
 263+ $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
212264 foreach ( $this->settings as $varName => $setting ) {
213 - $this->extractGlobal( $varName, $wiki, $suffix, $params, $wikiTags );
 265+ $this->extractGlobalSetting( $varName, $wiki, $params );
214266 }
215267 }
216268
217269 /**
 270+ * Return specific settings for $wiki
 271+ * See the documentation of self::$siteParamsCallback for more in-depth
 272+ * documentation about this function
 273+ *
 274+ * @param $wiki String
 275+ * @return array
 276+ */
 277+ protected function getWikiParams( $wiki ){
 278+ static $default = array(
 279+ 'suffix' => null,
 280+ 'lang' => null,
 281+ 'tags' => array(),
 282+ 'params' => array(),
 283+ );
 284+
 285+ if( !is_callable( $this->siteParamsCallback ) )
 286+ return $default;
 287+
 288+ $ret = call_user_func_array( $this->siteParamsCallback, array( $this, $wiki ) );
 289+ # Validate the returned value
 290+ if( !is_array( $ret ) )
 291+ return $default;
 292+
 293+ foreach( $default as $name => $def ){
 294+ if( !isset( $ret[$name] ) || ( is_array( $default[$name] ) && !is_array( $ret[$name] ) ) )
 295+ $ret[$name] = $default[$name];
 296+ }
 297+
 298+ return $ret;
 299+ }
 300+
 301+ /**
 302+ * Merge params beetween the ones passed to the function and the ones given
 303+ * by self::$siteParamsCallback for backward compatibility
 304+ * Values returned by self::getWikiParams() have the priority.
 305+ *
 306+ * @param $wiki String Wiki ID of the wiki in question.
 307+ * @param $suffix String The suffix of the wiki in question.
 308+ * @param $params Array List of parameters. $.'key' is replaced by $value in
 309+ * all returned data.
 310+ * @param $wikiTags Array The tags assigned to the wiki.
 311+ * @return array
 312+ */
 313+ protected function mergeParams( $wiki, $suffix, /*array*/ $params, /*array*/ $wikiTags ){
 314+ $ret = $this->getWikiParams( $wiki );
 315+
 316+ if( is_null( $ret['suffix'] ) )
 317+ $ret['suffix'] = $suffix;
 318+
 319+ $ret['tags'] = array_unique( array_merge( $ret['tags'], $wikiTags ) );
 320+
 321+ // Automatically fill that ones if needed
 322+ if( !isset( $ret['params']['lang'] ) && !is_null( $ret['lang'] ) )
 323+ $ret['params']['lang'] = $ret['lang'];
 324+ if( !isset( $ret['params']['site'] ) && !is_null( $ret['suffix'] ) )
 325+ $ret['params']['site'] = $ret['suffix'];
 326+
 327+ $ret['params'] += $params;
 328+ /*echo "$wiki<br/>\n";
 329+ var_dump( $ret );
 330+ echo "<br/>\n";
 331+ foreach( debug_backtrace() as $row )
 332+ echo "File: {$row['file']} Line: {$row['line']}<br/>\n";
 333+ echo "<br/>\n";*/
 334+ return $ret;
 335+ }
 336+
 337+ /**
218338 * Work out the site and language name from a database name
219339 * @param $db
220340 */
221 - function siteFromDB( $db ) {
222 - $site = NULL;
223 - $lang = NULL;
224 -
225 - // Only run hooks if they *can* be run.
226 - if (function_exists( 'wfRunHooks' ) && !wfRunHooks( 'SiteFromDB', array( $db, &$site, &$lang ) ) )
227 - return array( $site, $lang );
 341+ public function siteFromDB( $db ) {
 342+ // Allow override
 343+ $def = $this->getWikiParams( $db );
 344+ if( !is_null( $def['suffix'] ) && !is_null( $def['lang'] ) )
 345+ return array( $def['suffix'], $def['lang'] );
 346+
 347+ $site = null;
 348+ $lang = null;
228349 foreach ( $this->suffixes as $suffix ) {
229350 if ( $suffix === '' ) {
230351 $site = '';
@@ -239,9 +360,37 @@
240361 return array( $site, $lang );
241362 }
242363
243 - /** Returns true if the given vhost is handled locally. */
244 - function isLocalVHost( $vhost ) {
 364+ /**
 365+ * Returns true if the given vhost is handled locally.
 366+ * @param $vhost String
 367+ * @return bool
 368+ */
 369+ public function isLocalVHost( $vhost ) {
245370 return in_array( $vhost, $this->localVHosts );
246371 }
 372+
 373+ /**
 374+ * Merge multiple arrays together.
 375+ * On encountering duplicate keys, merge the two, but ONLY if they're arrays.
 376+ * PHP's array_merge_recursive() merges ANY duplicate values into arrays,
 377+ * which is not fun
 378+ */
 379+ static function arrayMerge( $array1/* ... */ ) {
 380+ $out = $array1;
 381+ for( $i=1; $i < func_num_args(); $i++ ) {
 382+ foreach( func_get_arg( $i ) as $key => $value ) {
 383+ if ( isset($out[$key]) && is_array($out[$key]) && is_array($value) ) {
 384+ $out[$key] = self::arrayMerge( $out[$key], $value );
 385+ } elseif ( !isset($out[$key]) || !$out[$key] && !is_numeric($key) ) {
 386+ // Values that evaluate to true given precedence, for the primary purpose of merging permissions arrays.
 387+ $out[$key] = $value;
 388+ } elseif ( is_numeric( $key ) ) {
 389+ $out[] = $value;
 390+ }
 391+ }
 392+ }
 393+
 394+ return $out;
 395+ }
247396 }
248397 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r39978Revert r39954, 39958 "Tweaks for SiteConfiguration:"...brion22:06, 25 August 2008
r40023Redo r39954, without regression this time. Sorry :(ialex15:10, 26 August 2008

Status & tagging log