MediaWiki  1.27.1
SiteConfiguration.php
Go to the documentation of this file.
1 <?php
118 
122  public $suffixes = [];
123 
127  public $wikis = [];
128 
132  public $settings = [];
133 
139  public $localVHosts = [];
140 
145  public $fullLoadCallback = null;
146 
148  public $fullLoadDone = false;
149 
164  public $siteParamsCallback = null;
165 
170  protected $cfgCache = [];
171 
181  public function get( $settingName, $wiki, $suffix = null, $params = [],
182  $wikiTags = []
183  ) {
184  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
185  return $this->getSetting( $settingName, $wiki, $params );
186  }
187 
196  protected function getSetting( $settingName, $wiki, array $params ) {
197  $retval = null;
198  if ( array_key_exists( $settingName, $this->settings ) ) {
199  $thisSetting =& $this->settings[$settingName];
200  do {
201  // Do individual wiki settings
202  if ( array_key_exists( $wiki, $thisSetting ) ) {
203  $retval = $thisSetting[$wiki];
204  break;
205  } elseif ( array_key_exists( "+$wiki", $thisSetting ) && is_array( $thisSetting["+$wiki"] ) ) {
206  $retval = $thisSetting["+$wiki"];
207  }
208 
209  // Do tag settings
210  foreach ( $params['tags'] as $tag ) {
211  if ( array_key_exists( $tag, $thisSetting ) ) {
212  if ( is_array( $retval ) && is_array( $thisSetting[$tag] ) ) {
213  $retval = self::arrayMerge( $retval, $thisSetting[$tag] );
214  } else {
215  $retval = $thisSetting[$tag];
216  }
217  break 2;
218  } elseif ( array_key_exists( "+$tag", $thisSetting ) && is_array( $thisSetting["+$tag"] ) ) {
219  if ( $retval === null ) {
220  $retval = [];
221  }
222  $retval = self::arrayMerge( $retval, $thisSetting["+$tag"] );
223  }
224  }
225  // Do suffix settings
226  $suffix = $params['suffix'];
227  if ( !is_null( $suffix ) ) {
228  if ( array_key_exists( $suffix, $thisSetting ) ) {
229  if ( is_array( $retval ) && is_array( $thisSetting[$suffix] ) ) {
230  $retval = self::arrayMerge( $retval, $thisSetting[$suffix] );
231  } else {
232  $retval = $thisSetting[$suffix];
233  }
234  break;
235  } elseif ( array_key_exists( "+$suffix", $thisSetting )
236  && is_array( $thisSetting["+$suffix"] )
237  ) {
238  if ( $retval === null ) {
239  $retval = [];
240  }
241  $retval = self::arrayMerge( $retval, $thisSetting["+$suffix"] );
242  }
243  }
244 
245  // Fall back to default.
246  if ( array_key_exists( 'default', $thisSetting ) ) {
247  if ( is_array( $retval ) && is_array( $thisSetting['default'] ) ) {
248  $retval = self::arrayMerge( $retval, $thisSetting['default'] );
249  } else {
250  $retval = $thisSetting['default'];
251  }
252  break;
253  }
254  } while ( false );
255  }
256 
257  if ( !is_null( $retval ) && count( $params['params'] ) ) {
258  foreach ( $params['params'] as $key => $value ) {
259  $retval = $this->doReplace( '$' . $key, $value, $retval );
260  }
261  }
262  return $retval;
263  }
264 
274  function doReplace( $from, $to, $in ) {
275  if ( is_string( $in ) ) {
276  return str_replace( $from, $to, $in );
277  } elseif ( is_array( $in ) ) {
278  foreach ( $in as $key => $val ) {
279  $in[$key] = $this->doReplace( $from, $to, $val );
280  }
281  return $in;
282  } else {
283  return $in;
284  }
285  }
286 
295  public function getAll( $wiki, $suffix = null, $params = [], $wikiTags = [] ) {
296  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
297  $localSettings = [];
298  foreach ( $this->settings as $varname => $stuff ) {
299  $append = false;
300  $var = $varname;
301  if ( substr( $varname, 0, 1 ) == '+' ) {
302  $append = true;
303  $var = substr( $varname, 1 );
304  }
305 
306  $value = $this->getSetting( $varname, $wiki, $params );
307  if ( $append && is_array( $value ) && is_array( $GLOBALS[$var] ) ) {
308  $value = self::arrayMerge( $value, $GLOBALS[$var] );
309  }
310  if ( !is_null( $value ) ) {
311  $localSettings[$var] = $value;
312  }
313  }
314  return $localSettings;
315  }
316 
325  public function getBool( $setting, $wiki, $suffix = null, $wikiTags = [] ) {
326  return (bool)$this->get( $setting, $wiki, $suffix, [], $wikiTags );
327  }
328 
334  function &getLocalDatabases() {
335  return $this->wikis;
336  }
337 
347  public function extractVar( $setting, $wiki, $suffix, &$var,
348  $params = [], $wikiTags = []
349  ) {
350  $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
351  if ( !is_null( $value ) ) {
352  $var = $value;
353  }
354  }
355 
364  public function extractGlobal( $setting, $wiki, $suffix = null,
365  $params = [], $wikiTags = []
366  ) {
367  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
368  $this->extractGlobalSetting( $setting, $wiki, $params );
369  }
370 
376  public function extractGlobalSetting( $setting, $wiki, $params ) {
377  $value = $this->getSetting( $setting, $wiki, $params );
378  if ( !is_null( $value ) ) {
379  if ( substr( $setting, 0, 1 ) == '+' && is_array( $value ) ) {
380  $setting = substr( $setting, 1 );
381  if ( is_array( $GLOBALS[$setting] ) ) {
382  $GLOBALS[$setting] = self::arrayMerge( $GLOBALS[$setting], $value );
383  } else {
384  $GLOBALS[$setting] = $value;
385  }
386  } else {
387  $GLOBALS[$setting] = $value;
388  }
389  }
390  }
391 
399  public function extractAllGlobals( $wiki, $suffix = null, $params = [],
400  $wikiTags = []
401  ) {
402  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
403  foreach ( $this->settings as $varName => $setting ) {
404  $this->extractGlobalSetting( $varName, $wiki, $params );
405  }
406  }
407 
416  protected function getWikiParams( $wiki ) {
417  static $default = [
418  'suffix' => null,
419  'lang' => null,
420  'tags' => [],
421  'params' => [],
422  ];
423 
424  if ( !is_callable( $this->siteParamsCallback ) ) {
425  return $default;
426  }
427 
428  $ret = call_user_func_array( $this->siteParamsCallback, [ $this, $wiki ] );
429  # Validate the returned value
430  if ( !is_array( $ret ) ) {
431  return $default;
432  }
433 
434  foreach ( $default as $name => $def ) {
435  if ( !isset( $ret[$name] ) || ( is_array( $default[$name] ) && !is_array( $ret[$name] ) ) ) {
436  $ret[$name] = $default[$name];
437  }
438  }
439 
440  return $ret;
441  }
442 
455  protected function mergeParams( $wiki, $suffix, array $params, array $wikiTags ) {
456  $ret = $this->getWikiParams( $wiki );
457 
458  if ( is_null( $ret['suffix'] ) ) {
459  $ret['suffix'] = $suffix;
460  }
461 
462  $ret['tags'] = array_unique( array_merge( $ret['tags'], $wikiTags ) );
463 
464  $ret['params'] += $params;
465 
466  // Automatically fill that ones if needed
467  if ( !isset( $ret['params']['lang'] ) && !is_null( $ret['lang'] ) ) {
468  $ret['params']['lang'] = $ret['lang'];
469  }
470  if ( !isset( $ret['params']['site'] ) && !is_null( $ret['suffix'] ) ) {
471  $ret['params']['site'] = $ret['suffix'];
472  }
473 
474  return $ret;
475  }
476 
483  public function siteFromDB( $db ) {
484  // Allow override
485  $def = $this->getWikiParams( $db );
486  if ( !is_null( $def['suffix'] ) && !is_null( $def['lang'] ) ) {
487  return [ $def['suffix'], $def['lang'] ];
488  }
489 
490  $site = null;
491  $lang = null;
492  foreach ( $this->suffixes as $altSite => $suffix ) {
493  if ( $suffix === '' ) {
494  $site = '';
495  $lang = $db;
496  break;
497  } elseif ( substr( $db, -strlen( $suffix ) ) == $suffix ) {
498  $site = is_numeric( $altSite ) ? $suffix : $altSite;
499  $lang = substr( $db, 0, strlen( $db ) - strlen( $suffix ) );
500  break;
501  }
502  }
503  $lang = str_replace( '_', '-', $lang );
504  return [ $site, $lang ];
505  }
506 
518  public function getConfig( $wiki, $settings ) {
519  global $IP;
520 
521  $multi = is_array( $settings );
523  if ( $wiki === wfWikiID() ) { // $wiki is this wiki
524  $res = [];
525  foreach ( $settings as $name ) {
526  if ( !preg_match( '/^wg[A-Z]/', $name ) ) {
527  throw new MWException( "Variable '$name' does start with 'wg'." );
528  } elseif ( !isset( $GLOBALS[$name] ) ) {
529  throw new MWException( "Variable '$name' is not set." );
530  }
531  $res[$name] = $GLOBALS[$name];
532  }
533  } else { // $wiki is a foreign wiki
534  if ( isset( $this->cfgCache[$wiki] ) ) {
535  $res = array_intersect_key( $this->cfgCache[$wiki], array_flip( $settings ) );
536  if ( count( $res ) == count( $settings ) ) {
537  return $multi ? $res : current( $res ); // cache hit
538  }
539  } elseif ( !in_array( $wiki, $this->wikis ) ) {
540  throw new MWException( "No such wiki '$wiki'." );
541  } else {
542  $this->cfgCache[$wiki] = [];
543  }
544  $retVal = 1;
545  $cmd = wfShellWikiCmd(
546  "$IP/maintenance/getConfiguration.php",
547  [
548  '--wiki', $wiki,
549  '--settings', implode( ' ', $settings ),
550  '--format', 'PHP'
551  ]
552  );
553  // ulimit5.sh breaks this call
554  $data = trim( wfShellExec( $cmd, $retVal, [], [ 'memory' => 0 ] ) );
555  if ( $retVal != 0 || !strlen( $data ) ) {
556  throw new MWException( "Failed to run getConfiguration.php." );
557  }
558  $res = unserialize( $data );
559  if ( !is_array( $res ) ) {
560  throw new MWException( "Failed to unserialize configuration array." );
561  }
562  $this->cfgCache[$wiki] = $this->cfgCache[$wiki] + $res;
563  }
564 
565  return $multi ? $res : current( $res );
566  }
567 
575  public function isLocalVHost( $vhost ) {
576  return in_array( $vhost, $this->localVHosts );
577  }
578 
589  static function arrayMerge( $array1/* ... */ ) {
590  $out = $array1;
591  $argsCount = func_num_args();
592  for ( $i = 1; $i < $argsCount; $i++ ) {
593  foreach ( func_get_arg( $i ) as $key => $value ) {
594  if ( isset( $out[$key] ) && is_array( $out[$key] ) && is_array( $value ) ) {
595  $out[$key] = self::arrayMerge( $out[$key], $value );
596  } elseif ( !isset( $out[$key] ) || !$out[$key] && !is_numeric( $key ) ) {
597  // Values that evaluate to true given precedence, for the
598  // primary purpose of merging permissions arrays.
599  $out[$key] = $value;
600  } elseif ( is_numeric( $key ) ) {
601  $out[] = $value;
602  }
603  }
604  }
605 
606  return $out;
607  }
608 
609  public function loadFullData() {
610  if ( $this->fullLoadCallback && !$this->fullLoadDone ) {
611  call_user_func( $this->fullLoadCallback, $this );
612  $this->fullLoadDone = true;
613  }
614  }
615 }
extractGlobalSetting($setting, $wiki, $params)
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:762
the array() calling protocol came about after MediaWiki 1.4rc1.
$fullLoadDone
Whether or not all data has been loaded.
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2321
$IP
Definition: WebStart.php:58
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Definition: hooks.txt:1798
if(!isset($args[0])) $lang
$value
getBool($setting, $wiki, $suffix=null, $wikiTags=[])
Retrieves a configuration setting for a given wiki, forced to a boolean.
wfShellExec($cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
getSetting($settingName, $wiki, array $params)
Really retrieves a configuration setting for a given wiki.
extractVar($setting, $wiki, $suffix, &$var, $params=[], $wikiTags=[])
Retrieves the value of a given setting, and places it in a variable passed by reference.
mergeParams($wiki, $suffix, array $params, array $wikiTags)
Merge params between the ones passed to the function and the ones given by self::$siteParamsCallback ...
unserialize($serialized)
Definition: ApiMessage.php:102
$GLOBALS['IP']
wfShellWikiCmd($script, array $parameters=[], array $options=[])
Generate a shell-escaped command line string to run a MediaWiki cli script.
array $cfgCache
Configuration cache for getConfig()
$res
Definition: database.txt:21
static arrayMerge($array1)
Merge multiple arrays together.
extractGlobal($setting, $wiki, $suffix=null, $params=[], $wikiTags=[])
Retrieves the value of a given setting, and places it in its corresponding global variable...
$params
string array $siteParamsCallback
A callback function that returns an array with the following keys (all optional): ...
doReplace($from, $to, $in)
Type-safe string replace; won't do replacements on non-strings private?
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books $tag
Definition: hooks.txt:965
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
$localVHosts
Array of domains that are local and can be handled by the same server.
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration settings
Definition: globals.txt:25
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
$from
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
getWikiParams($wiki)
Return specific settings for $wiki See the documentation of self::$siteParamsCallback for more in-dep...
getAll($wiki, $suffix=null, $params=[], $wikiTags=[])
Gets all settings for a wiki.
extractAllGlobals($wiki, $suffix=null, $params=[], $wikiTags=[])
Retrieves the values of all settings, and places them in their corresponding global variables...
string array $fullLoadCallback
Optional callback to load full configuration data.
isLocalVHost($vhost)
Returns true if the given vhost is handled locally.
& getLocalDatabases()
Retrieves an array of local databases.
$settings
The whole array of settings.
$wikis
Array of wikis, should be the same as $wgLocalDatabases.
siteFromDB($db)
Work out the site and language name from a database name.
This is a class for holding configuration settings, particularly for multi-wiki sites.
getConfig($wiki, $settings)
Get the resolved (post-setup) configuration of a potentially foreign wiki.
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account incomplete not yet checked for validity & $retval
Definition: hooks.txt:242
$suffixes
Array of suffixes, for self::siteFromDB()
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310