MediaWiki  1.28.0
SiteConfiguration.php
Go to the documentation of this file.
1 <?php
123 
127  public $suffixes = [];
128 
132  public $wikis = [];
133 
137  public $settings = [];
138 
144  public $localVHosts = [];
145 
150  public $fullLoadCallback = null;
151 
153  public $fullLoadDone = false;
154 
169  public $siteParamsCallback = null;
170 
175  protected $cfgCache = [];
176 
186  public function get( $settingName, $wiki, $suffix = null, $params = [],
187  $wikiTags = []
188  ) {
189  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
190  return $this->getSetting( $settingName, $wiki, $params );
191  }
192 
201  protected function getSetting( $settingName, $wiki, array $params ) {
202  $retval = null;
203  if ( array_key_exists( $settingName, $this->settings ) ) {
204  $thisSetting =& $this->settings[$settingName];
205  do {
206  // Do individual wiki settings
207  if ( array_key_exists( $wiki, $thisSetting ) ) {
208  $retval = $thisSetting[$wiki];
209  break;
210  } elseif ( array_key_exists( "+$wiki", $thisSetting ) && is_array( $thisSetting["+$wiki"] ) ) {
211  $retval = $thisSetting["+$wiki"];
212  }
213 
214  // Do tag settings
215  foreach ( $params['tags'] as $tag ) {
216  if ( array_key_exists( $tag, $thisSetting ) ) {
217  if ( is_array( $retval ) && is_array( $thisSetting[$tag] ) ) {
218  $retval = self::arrayMerge( $retval, $thisSetting[$tag] );
219  } else {
220  $retval = $thisSetting[$tag];
221  }
222  break 2;
223  } elseif ( array_key_exists( "+$tag", $thisSetting ) && is_array( $thisSetting["+$tag"] ) ) {
224  if ( $retval === null ) {
225  $retval = [];
226  }
227  $retval = self::arrayMerge( $retval, $thisSetting["+$tag"] );
228  }
229  }
230  // Do suffix settings
231  $suffix = $params['suffix'];
232  if ( !is_null( $suffix ) ) {
233  if ( array_key_exists( $suffix, $thisSetting ) ) {
234  if ( is_array( $retval ) && is_array( $thisSetting[$suffix] ) ) {
235  $retval = self::arrayMerge( $retval, $thisSetting[$suffix] );
236  } else {
237  $retval = $thisSetting[$suffix];
238  }
239  break;
240  } elseif ( array_key_exists( "+$suffix", $thisSetting )
241  && is_array( $thisSetting["+$suffix"] )
242  ) {
243  if ( $retval === null ) {
244  $retval = [];
245  }
246  $retval = self::arrayMerge( $retval, $thisSetting["+$suffix"] );
247  }
248  }
249 
250  // Fall back to default.
251  if ( array_key_exists( 'default', $thisSetting ) ) {
252  if ( is_array( $retval ) && is_array( $thisSetting['default'] ) ) {
253  $retval = self::arrayMerge( $retval, $thisSetting['default'] );
254  } else {
255  $retval = $thisSetting['default'];
256  }
257  break;
258  }
259  } while ( false );
260  }
261 
262  if ( !is_null( $retval ) && count( $params['params'] ) ) {
263  foreach ( $params['params'] as $key => $value ) {
264  $retval = $this->doReplace( '$' . $key, $value, $retval );
265  }
266  }
267  return $retval;
268  }
269 
279  function doReplace( $from, $to, $in ) {
280  if ( is_string( $in ) ) {
281  return str_replace( $from, $to, $in );
282  } elseif ( is_array( $in ) ) {
283  foreach ( $in as $key => $val ) {
284  $in[$key] = $this->doReplace( $from, $to, $val );
285  }
286  return $in;
287  } else {
288  return $in;
289  }
290  }
291 
300  public function getAll( $wiki, $suffix = null, $params = [], $wikiTags = [] ) {
301  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
302  $localSettings = [];
303  foreach ( $this->settings as $varname => $stuff ) {
304  $append = false;
305  $var = $varname;
306  if ( substr( $varname, 0, 1 ) == '+' ) {
307  $append = true;
308  $var = substr( $varname, 1 );
309  }
310 
311  $value = $this->getSetting( $varname, $wiki, $params );
312  if ( $append && is_array( $value ) && is_array( $GLOBALS[$var] ) ) {
313  $value = self::arrayMerge( $value, $GLOBALS[$var] );
314  }
315  if ( !is_null( $value ) ) {
316  $localSettings[$var] = $value;
317  }
318  }
319  return $localSettings;
320  }
321 
330  public function getBool( $setting, $wiki, $suffix = null, $wikiTags = [] ) {
331  return (bool)$this->get( $setting, $wiki, $suffix, [], $wikiTags );
332  }
333 
339  function &getLocalDatabases() {
340  return $this->wikis;
341  }
342 
352  public function extractVar( $setting, $wiki, $suffix, &$var,
353  $params = [], $wikiTags = []
354  ) {
355  $value = $this->get( $setting, $wiki, $suffix, $params, $wikiTags );
356  if ( !is_null( $value ) ) {
357  $var = $value;
358  }
359  }
360 
369  public function extractGlobal( $setting, $wiki, $suffix = null,
370  $params = [], $wikiTags = []
371  ) {
372  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
373  $this->extractGlobalSetting( $setting, $wiki, $params );
374  }
375 
381  public function extractGlobalSetting( $setting, $wiki, $params ) {
382  $value = $this->getSetting( $setting, $wiki, $params );
383  if ( !is_null( $value ) ) {
384  if ( substr( $setting, 0, 1 ) == '+' && is_array( $value ) ) {
385  $setting = substr( $setting, 1 );
386  if ( is_array( $GLOBALS[$setting] ) ) {
387  $GLOBALS[$setting] = self::arrayMerge( $GLOBALS[$setting], $value );
388  } else {
389  $GLOBALS[$setting] = $value;
390  }
391  } else {
392  $GLOBALS[$setting] = $value;
393  }
394  }
395  }
396 
404  public function extractAllGlobals( $wiki, $suffix = null, $params = [],
405  $wikiTags = []
406  ) {
407  $params = $this->mergeParams( $wiki, $suffix, $params, $wikiTags );
408  foreach ( $this->settings as $varName => $setting ) {
409  $this->extractGlobalSetting( $varName, $wiki, $params );
410  }
411  }
412 
421  protected function getWikiParams( $wiki ) {
422  static $default = [
423  'suffix' => null,
424  'lang' => null,
425  'tags' => [],
426  'params' => [],
427  ];
428 
429  if ( !is_callable( $this->siteParamsCallback ) ) {
430  return $default;
431  }
432 
433  $ret = call_user_func_array( $this->siteParamsCallback, [ $this, $wiki ] );
434  # Validate the returned value
435  if ( !is_array( $ret ) ) {
436  return $default;
437  }
438 
439  foreach ( $default as $name => $def ) {
440  if ( !isset( $ret[$name] ) || ( is_array( $default[$name] ) && !is_array( $ret[$name] ) ) ) {
441  $ret[$name] = $default[$name];
442  }
443  }
444 
445  return $ret;
446  }
447 
460  protected function mergeParams( $wiki, $suffix, array $params, array $wikiTags ) {
461  $ret = $this->getWikiParams( $wiki );
462 
463  if ( is_null( $ret['suffix'] ) ) {
464  $ret['suffix'] = $suffix;
465  }
466 
467  $ret['tags'] = array_unique( array_merge( $ret['tags'], $wikiTags ) );
468 
469  $ret['params'] += $params;
470 
471  // Automatically fill that ones if needed
472  if ( !isset( $ret['params']['lang'] ) && !is_null( $ret['lang'] ) ) {
473  $ret['params']['lang'] = $ret['lang'];
474  }
475  if ( !isset( $ret['params']['site'] ) && !is_null( $ret['suffix'] ) ) {
476  $ret['params']['site'] = $ret['suffix'];
477  }
478 
479  return $ret;
480  }
481 
488  public function siteFromDB( $db ) {
489  // Allow override
490  $def = $this->getWikiParams( $db );
491  if ( !is_null( $def['suffix'] ) && !is_null( $def['lang'] ) ) {
492  return [ $def['suffix'], $def['lang'] ];
493  }
494 
495  $site = null;
496  $lang = null;
497  foreach ( $this->suffixes as $altSite => $suffix ) {
498  if ( $suffix === '' ) {
499  $site = '';
500  $lang = $db;
501  break;
502  } elseif ( substr( $db, -strlen( $suffix ) ) == $suffix ) {
503  $site = is_numeric( $altSite ) ? $suffix : $altSite;
504  $lang = substr( $db, 0, strlen( $db ) - strlen( $suffix ) );
505  break;
506  }
507  }
508  $lang = str_replace( '_', '-', $lang );
509  return [ $site, $lang ];
510  }
511 
523  public function getConfig( $wiki, $settings ) {
524  global $IP;
525 
526  $multi = is_array( $settings );
528  if ( $wiki === wfWikiID() ) { // $wiki is this wiki
529  $res = [];
530  foreach ( $settings as $name ) {
531  if ( !preg_match( '/^wg[A-Z]/', $name ) ) {
532  throw new MWException( "Variable '$name' does start with 'wg'." );
533  } elseif ( !isset( $GLOBALS[$name] ) ) {
534  throw new MWException( "Variable '$name' is not set." );
535  }
536  $res[$name] = $GLOBALS[$name];
537  }
538  } else { // $wiki is a foreign wiki
539  if ( isset( $this->cfgCache[$wiki] ) ) {
540  $res = array_intersect_key( $this->cfgCache[$wiki], array_flip( $settings ) );
541  if ( count( $res ) == count( $settings ) ) {
542  return $multi ? $res : current( $res ); // cache hit
543  }
544  } elseif ( !in_array( $wiki, $this->wikis ) ) {
545  throw new MWException( "No such wiki '$wiki'." );
546  } else {
547  $this->cfgCache[$wiki] = [];
548  }
549  $retVal = 1;
550  $cmd = wfShellWikiCmd(
551  "$IP/maintenance/getConfiguration.php",
552  [
553  '--wiki', $wiki,
554  '--settings', implode( ' ', $settings ),
555  '--format', 'PHP'
556  ]
557  );
558  // ulimit5.sh breaks this call
559  $data = trim( wfShellExec( $cmd, $retVal, [], [ 'memory' => 0 ] ) );
560  if ( $retVal != 0 || !strlen( $data ) ) {
561  throw new MWException( "Failed to run getConfiguration.php." );
562  }
563  $res = unserialize( $data );
564  if ( !is_array( $res ) ) {
565  throw new MWException( "Failed to unserialize configuration array." );
566  }
567  $this->cfgCache[$wiki] = $this->cfgCache[$wiki] + $res;
568  }
569 
570  return $multi ? $res : current( $res );
571  }
572 
583  static function arrayMerge( $array1/* ... */ ) {
584  $out = $array1;
585  $argsCount = func_num_args();
586  for ( $i = 1; $i < $argsCount; $i++ ) {
587  foreach ( func_get_arg( $i ) as $key => $value ) {
588  if ( isset( $out[$key] ) && is_array( $out[$key] ) && is_array( $value ) ) {
589  $out[$key] = self::arrayMerge( $out[$key], $value );
590  } elseif ( !isset( $out[$key] ) || !$out[$key] && !is_numeric( $key ) ) {
591  // Values that evaluate to true given precedence, for the
592  // primary purpose of merging permissions arrays.
593  $out[$key] = $value;
594  } elseif ( is_numeric( $key ) ) {
595  $out[] = $value;
596  }
597  }
598  }
599 
600  return $out;
601  }
602 
603  public function loadFullData() {
604  if ( $this->fullLoadCallback && !$this->fullLoadDone ) {
605  call_user_func( $this->fullLoadCallback, $this );
606  $this->fullLoadDone = true;
607  }
608  }
609 }
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:802
the array() calling protocol came about after MediaWiki 1.4rc1.
$fullLoadDone
Whether or not all data has been loaded.
$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:1936
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:1007
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.
& 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:300