Seb35 has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/299359

Change subject: [WIP] A proper class in the directory src, where all the logic 
will go
......................................................................

[WIP] A proper class in the directory src, where all the logic will go
---
M MediaWikiFarm.php
A src/MediaWikiFarm.php
2 files changed, 467 insertions(+), 328 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MediaWikiFarm 
refs/changes/59/299359/1

diff --git a/MediaWikiFarm.php b/MediaWikiFarm.php
index a1b3a2d..11e950d 100644
--- a/MediaWikiFarm.php
+++ b/MediaWikiFarm.php
@@ -8,333 +8,29 @@
 }
 
 /**
- * This class computes the configuration of a specific wiki from a set of 
configuration files.
- * The configuration is composed of the list of authorised wikis and different 
configuration
- * files, possibly with different permissions. All files are written in YAML 
syntax.
+ * Configuration directory.
+ * 
+ * This parameter should be specified in your LocalSettings.php, before the 
require_once.
+ * The value must be a readable directory. It is recommended this directory is 
not readable
+ * from the Web.
  */
-class MediaWikiFarm {
-       
-       /**
-        * Get or compute the configuration (MediaWiki, skins, extensions) for 
a wiki.
-        * 
-        * You have to specify the wiki, the suffix, and the version and, as 
parameters, the configuration
-        * and code directories and the caching file. This function uses a 
caching mechanism to avoid
-        * recompute each time the configuration; it is rebuilt when origin 
configuration files are changed.
-        * 
-        * The params argument should have the following keys:
-        * - 'configDir' (string) Configuration directory where are the various 
configuration files
-        * - 'codeDir' (string) Code directory where MediaWiki code is
-        * - 'cacheFile' (string) Template filename of the caching file
-        * - 'generalYamlFilename' (string) Path for the general YAML file, 
relative to configDir
-        * - 'suffixedYamlFilename' (string) Path for the suffixed YAML file, 
relative to configDir
-        * - 'privateYamlFilename' (string) Path for the privale YAML file, 
relative to configDir
-        * In cacheFile and suffixedYamlFilename, the string '$suffix' will be 
replaced by the actual
-        * suffix, and in cacheFile, the strings '$wiki' and '$version' will be 
replaced by the actual
-        * wiki identifier and the version.
-        * 
-        * The returned array has the following format:
-        * array( 'general' => array( 'wgSitename' => 'Foo', ... ),
-        *        'skins' => array( '_loading' => 'wfLoadSkin'|'require_once',
-        *                          'wgFlowParsoidTimeout' => 100, ...
-        *                        ),
-        *        'extensions' => array( '_loading' => 
'wfLoadExtension'|'require_once',
-        *                               'wgFlowParsoidTimeout' => 100, ...
-        *                             )
-        *      )
-        * 
-        * @param string $wiki Name of the wiki.
-        * @param string $suffix Suffix of the wiki (main family type).
-        * @param string $version Version of the wiki.
-        * @param SiteConfiguration $wgConf SiteConfigurat object from 
MediaWiki.
-        * @param $array params Parameters for this configuration management.
-        * @return array Global parameter variables and loading mechanisms for 
skins and extensions.
-        */
-       static function getMediaWikiConfig( $myWiki, $mySuffix, $myVersion, 
&$wgConf, $params ) {
-               
-               $configDir = $params['configDir'];
-               $codeDir = $params['codeDir'];
-               $cacheFile = $params['cacheFile'];
-               $generalYamlFilename = $params['generalYamlFilename'];
-               $suffixedYamlFilename = $params['suffixedYamlFilename'];
-               $privateYamlFilename = $params['privateYamlFilename'];
-               
-               $cacheFile = preg_replace( array( '/\$wiki/', '/\$suffix/', 
'/\$version/' ),
-                                              array( $myWiki, $mySuffix, 
$myVersion ),
-                                              $cacheFile );
-               
-               $suffixedYamlFilename = preg_replace( '/\$suffix/', $mySuffix, 
$suffixedYamlFilename );
-               
-               $globals = false;
-               
-               if( @filemtime( $cacheFile ) >= max( filemtime( 
$configDir.$generalYamlFilename ),
-                                                        filemtime( 
$configDir.$suffixedYamlFilename ),
-                                                        filemtime( 
$configDir.$privateYamlFilename ) ) )
-               {       
-                       $cache = @file_get_contents( $cacheFile );
-                       if ( $cache !== false ) {
-                               $globals = unserialize( $cache );
-                       }
-               }
-               else {
-                       
-                       $globals = array();
-                       $globals['general'] = array();
-                       $globals['skins'] = array();
-                       $globals['extensions'] = array();
-                       
-                       // Load InitialiseSettings.yml (general)
-                       $generalSettings = Yaml::parse( file_get_contents( 
$configDir.$generalYamlFilename ) );
-                       foreach( $generalSettings as $setting => $value ) {
-                               
-                               $wgConf->settings[$setting]['default'] = $value;
-                       }
-                       
-                       // Load InitialiseSettings.yml (client)
-                       $suffixedSettings = Yaml::parse( file_get_contents( 
$configDir.$suffixedYamlFilename ) );
-                       foreach( $suffixedSettings as $setting => $values ) {
-                               
-                               foreach( $values as $wiki => $val ) {
-                                       
-                                       if( $wiki == 'default' ) 
$wgConf->settings[$setting][$mySuffix] = $val;
-                                       else 
$wgConf->settings[$setting][$wiki.'-'.$mySuffix] = $val;
-                               }
-                       }
-                       
-                       // Load PrivateSettings.yml (general)
-                       $privateSettings = Yaml::parse( file_get_contents( 
$configDir.$privateYamlFilename ) );
-                       foreach( $privateSettings as $setting => $value ) {
-                               
-                               foreach( $value as $suffix => $val ) {
-                                       
-                                       $wgConf->settings[$setting][$suffix] = 
$val;
-                               }
-                       }
-                       
-                       // Get specific configuration for this wiki
-                       // Do not use SiteConfiguration::extractAllGlobals or 
the configuration caching would become
-                       // ineffective and there would be inconsistencies in 
this process
-                       $globals['general'] = $wgConf->getAll( 
$myWiki.'-'.$mySuffix, $mySuffix );
-                       
-                       // For the permissions array, fix a small strangeness: 
when an existing default permission
-                       // is true, it is not possible to make it false in the 
specific configuration
-                       if( array_key_exists( '+wgGroupPermissions', 
$wgConf->settings ) )
-                               
-                               $globals['general']['wgGroupPermissions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgGroupPermissions', 
$myWiki.'-'.$mySuffix, $mySuffix ), $globals['general']['wgGroupPermissions'] );
-                       
-                       //if( array_key_exists( '+wgDefaultUserOptions', 
$wgConf->settings ) )
-                               //$globals['general']['wgDefaultUserOptions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgDefaultUserOptions', 
$myWiki.'-'.$mySuffix, $mySuffix ), $globals['general']['wgDefaultUserOptions'] 
);
-                       
-                       // Extract from the general configuration skin and 
extension configuration
-                       // Search for skin and extension activation
-                       $unsetPrefixes = array();
-                       foreach( $globals['general'] as $setting => $value ) {
-                               if( preg_match( '/^wgUseSkin(.+)$/', $setting, 
$matches ) && $value === true ) {
-                                       
-                                       $skin = $matches[1];
-                                       if( is_dir( 
$codeDir.'/'.$myVersion.'/skins/'.$skin ) ) {
-                                               
-                                               $globals['skins'][$skin] = 
array();
-                                               if( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/skin.json' ) ) {
-                                                       
$globals['skins'][$skin]['_loading'] = 'wfLoadSkin';
-                                               }
-                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/'.$skin.'.php' ) ) {
-                                                       
$globals['skins'][$skin]['_loading'] = 'require_once';
-                                               }
-                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/composer.json' ) ) {
-                                                       
$globals['skins'][$skin]['_loading'] = 'composer';
-                                               }
-                                               else {echo ' 
(unknown)';$unsetPrefixes[] = $skin;}
-                                       }
-                                       else $unsetPrefixes[] = $skin;
-                                       
-                                       unset( $globals['general'][$setting] );
-                               }
-                               elseif( preg_match( '/^wgUseExtension(.+)$/', 
$setting, $matches ) && $value === true ) {
-                                       
-                                       $extension = $matches[1];
-                                       if( is_dir( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension ) ) {
-                                               
-                                               
$globals['extensions'][$extension] = array();
-                                               if( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/extension.json' ) && 
$extension !== 'VisualEditor' ) {
-                                                       
$globals['extensions'][$extension]['_loading'] = 'wfLoadExtension';
-                                               }
-                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/'.$extension.'.php' ) ) {
-                                                       
$globals['extensions'][$extension]['_loading'] = 'require_once';
-                                               }
-                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/composer.json' ) ) {
-                                                       
$globals['extensions'][$extension]['_loading'] = 'composer';
-                                               }
-                                               else $unsetPrefixes[] = 
$extension;
-                                       }
-                                       else $unsetPrefixes[] = $extension;
-                                       
-                                       unset( $globals['general'][$setting] );
-                               }
-                               elseif( preg_match( 
'/^wgUse(?:Skin|Extension|LocalExtension)(.+)$/', $setting, $matches ) && 
$value !== true ) {
-                                       
-                                       $unsetPrefixes[] = $matches[1];
-                                       unset( $globals['general'][$setting] );
-                               }
-                       }
-                       
-                       // Extract from the general configuration skin and 
extension configuration
-                       $skins = array_keys( $globals['skins'] );
-                       $extensions = array_keys( $globals['extensions'] );
-                       foreach( $globals['general'] as $setting => $value ) {
-                               
-                               $found = false;
-                               foreach( $extensions as $extension ) {
-                                       if( preg_match( 
'/^wg'.preg_quote($extension,'/').'/', $setting ) ) {
-                                               
$globals['extensions'][$extension][$setting] = $value;
-                                               unset( $setting );
-                                               $found = true;
-                                               break;
-                                       }
-                               }
-                               if( !$found ) {
-                                       foreach( $skins as $skin ) {
-                                               if( preg_match( 
'/^wg'.preg_quote($skin,'/').'/', $setting ) ) {
-                                                       
$globals['skins'][$skin][$setting] = $value;
-                                                       unset( $setting );
-                                                       $found = true;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               if( !$found ) {
-                                       foreach( $unsetPrefixes as $prefix ) {
-                                               if( preg_match( 
'/^wg'.preg_quote($prefix,'/').'/', $setting ) ) {
-                                                       unset( $setting );
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       // Save this configuration in a serialised file
-                       @mkdir( dirname( $cacheFile ) );
-                       $tmpFile = tempnam( dirname( $cacheFile ), basename( 
$cacheFile ).'.tmp' );
-                       chmod( $tmpFile, 0640 );
-                       if( $tmpFile && file_put_contents( $tmpFile, serialize( 
$globals ) ) ) {
-                               rename( $tmpFile, $cacheFile );
-                       }
-               }
-               
-               return $globals;
-       }
-       
-       /**
-        * This function loads MediaWiki configuration (parameters).
-        * 
-        * @param array $extensions Subarray of general parameters (c.f. 
MediaWikiFarm:getMediaWikiConfig).
-        */
-       static function loadMediaWikiConfig( $settings ) {
-               
-               // Set general parameters as global variables
-               foreach( $settings as $setting => $value ) {
-                       
-                       $GLOBALS[$setting] = $value;
-               }
-       }
-       
-       /**
-        * This function load the skins configuration (wfLoadSkin loading 
mechanism and parameters).
-        * 
-        * WARNING: it doesn’t load the skins with the require_once mechanism 
(it is not possible in a
-        *          function because variables would inherit the non-global 
scope);
-        *          such skins must be loaded before calling this function.
-        * 
-        * @param array $extensions Subarray of skins parameters (c.f. 
MediaWikiFarm::getMediaWikiConfig).
-        */
-       static function loadSkinsConfig( $skins ) {
-               
-               // Load skins with the wfLoadSkin mechanism
-               foreach( $skins as $skin => $value ) {
-                       
-                       if( $value['_loading'] == 'wfLoadSkin' )
-                       
-                               wfLoadSkin( $skin );
-                       
-                       unset( $skins[$skin]['_loading'] );
-               }
-               
-               // Set skin parameters as global variables
-               foreach( $skins as $skin => $settings ) {
-                       
-                       foreach( $settings as $setting => $value )
-                               
-                               $GLOBALS[$setting] = $value;
-               }
-       }
-       
-       /**
-        * This function load the skins configuration (wfLoadSkin loading 
mechanism and parameters).
-        * 
-        * WARNING: it doesn’t load the skins with the require_once mechanism 
(it is not possible in a
-        *          function because variables would inherit the non-global 
scope);
-        *          such skins must be loaded before calling this function.
-        * 
-        * @param array $extensions Subarray of extensions parameters (c.f. 
MediaWikiFarm::getMediaWikiConfig).
-        */
-       static function loadExtensionsConfig( $extensions ) {
-               
-               // Load extensions with the wfLoadExtension mechanism
-               foreach( $extensions as $extension => $value ) {
-                       
-                       if( $value['_loading'] == 'wfLoadExtension' )
-                               
-                               wfLoadExtension( $extension );
-                       
-                       unset( $extensions[$extension]['_loading'] );
-               }
-               
-               // Set extension parameters as global variables
-               foreach( $extensions as $extension => $settings ) {
-                       
-                       foreach( $settings as $setting => $value )
-                               
-                               $GLOBALS[$setting] = $value;
-               }
-       }
-       
-       /**
-        * 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
-        * This function is almost the same as SiteConfiguration::arrayMerge, 
with the
-        * difference an existing scalar value has precedence EVEN if evaluated 
to false,
-        * in order to override permissions array with removed rights.
-        *
-        * @param array $array1.
-        *
-        * @return array
-        */
-       static function arrayMerge( $array1/* ... */ ) {
-               $out = $array1;
-               $argsCount = func_num_args();
-               for ( $i = 1; $i < $argsCount; $i++ ) {
-                       foreach ( func_get_arg( $i ) as $key => $value ) {
-                               if ( isset( $out[$key] ) && is_array( 
$out[$key] ) && is_array( $value ) ) {
-                                       $out[$key] = MediaWikiFarm::arrayMerge( 
$out[$key], $value );
-                               } elseif ( !isset( $out[$key] ) && !is_numeric( 
$key ) ) {
-                                       // Values that evaluate to true given 
precedence, for the
-                                       // primary purpose of merging 
permissions arrays.
-                                       $out[$key] = $value;
-                               } elseif ( is_numeric( $key ) ) {
-                                       $out[] = $value;
-                               }
-                       }
-               }
-               
-               return $out;
-       }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 $wgMediaWikiFarmConfigDir = '/etc/mediawiki';
-$wgMediaWikiFarmCodeDir = '/srv/www/mediawiki';
+
+$wgMediaWikiFarmConfigDir = '/srv/www/mediawiki-farm/config';
+
+
+
+
+/**
+ * Code.
+ * 
+ * Please do not remove the following lines.
+ */
+
+require_once "$IP/extensions/MediaWikiFarm/src/MediaWikiFarm.php";
+
+MediaWikiFarm::initialise();
+
 
 
 # Create a MediaWiki farm
@@ -348,7 +44,7 @@
 
 function wvgGetWikiFromURL() {
        
-       if( !preg_match( '/^([a-zA-Z0-9]+)-([a-zA-Z0-9]+)\.example\.com$/', 
$GLOBALS['_SERVER']['SERVER_NAME'], $matches ) ) {
+       if( !preg_match( '/^([a-zA-Z0-9]+)-([a-zA-Z0-9]+)\.example.com$/', 
$GLOBALS['_SERVER']['HTTP_HOST'], $matches ) ) {
                echo 'Error: unknown wiki.';
                exit;
        }
@@ -387,8 +83,7 @@
 
 // Obtain the global configuration
 $wvgGlobals = MediaWikiFarm::getMediaWikiConfig( $wvgWiki, $wvgClient, 
$wvgVersion, $wgConf,
-                                                 array( 'configDir' => 
$wgMediaWikiFarmConfigDir,
-                                                        'codeDir' => 
$wgMediaWikiFarmCodeDir,
+                                                 array( 'codeDir' => 
$wgMediaWikiFarmCodeDir,
                                                         'cacheFile' => 
'/tmp/mw-cache/conf-$version-$wiki-$suffix',
                                                         'generalYamlFilename' 
=> '/InitialiseSettings.yml',
                                                         'suffixedYamlFilename' 
=> '/$suffix/InitialiseSettings.yml',
diff --git a/src/MediaWikiFarm.php b/src/MediaWikiFarm.php
new file mode 100644
index 0000000..9d77152
--- /dev/null
+++ b/src/MediaWikiFarm.php
@@ -0,0 +1,444 @@
+<?php
+
+/**
+ * This class computes the configuration of a specific wiki from a set of 
configuration files.
+ * The configuration is composed of the list of authorised wikis and different 
configuration
+ * files, possibly with different permissions. All files are written in YAML 
syntax.
+ */
+class MediaWikiFarm {
+       
+       /* 
+        * Properties
+        * ---------- */
+       
+       /** @var MediaWikiFarm|null [private] Singleton. */
+       public static $self = null;
+       
+       /** @var string|null [private] Farm configuration directory. */
+       public $configDir = null;
+       
+       /** @var array [private] Farm configuration file. */
+       public $config = array();
+       
+       /** @var bool [private] This object cannot be used because of an 
emergency error. */
+       public $unusable = false;
+       
+       
+       
+       /* 
+        * Public Methods
+        * -------------- */
+       
+       /**
+        * Initialise the unique object of type MediaWikiFarm.
+        * 
+        * @return MediaWikiFarm Singleton.
+        */
+       static function initialise() {
+               
+               global $wgMediaWikiFarmConfigDir;
+               
+               if( self::$self == null )
+                       self::$self = new self( 
$GLOBALS['_SERVER']['HTTP_HOST'], $wgMediaWikiFarmConfigDir );
+               
+               return self::$self;
+       }
+       
+       
+       
+       /*
+        * Private Methods
+        * --------------- */
+       
+       /**
+        * Construct a MediaWiki farm.
+        * 
+        * @param string $host Requested host.
+        * @param string|null $configDir Configuration directory; if null or 
not a string, the default value is used (/etc/mediawiki).
+        */
+       private function __construct( $host, $configDir = null ) {
+               
+               $this->configDir = isset( $configDir ) && is_string( $configDir 
) ? $configDir : '/etc/mediawiki';
+               
+               $config = array();
+               if( is_file( $this->configDir . '/farms.yml' ) ) {
+                       
+                       try {
+                               
+                               $config = \Symphony\Component\Yaml\Yaml::parse( 
file_get_contents( $this->configDir . '/farms.yml' ) );
+                       }
+                       catch( \Symfony\Component\Yaml\Exception\ParseException 
$e ) {
+                               
+                               $this->unusable = true;
+                       }
+               }
+               else if( is_file( $this->configDir . '/farms.php' ) )
+                       $config = require $this->configDir . '/farms.php';
+               
+               else
+                       $this->unusable = true;
+               
+               # Now select the right configuration amoung all farms
+               if( !$this->unusable )
+                       $this->unusable = !$this->selectFarm( $config );
+       }
+       
+       /**
+        * Select the farm.
+        * 
+        * @param array $configs All farm configurations.
+        * @param string $host Requested host.
+        * return bool One of the farm has been selected.
+        */
+       private function selectFarm( $configs, $host ) {
+               
+               foreach( $configs as $regex => $config ) {
+                       
+                       if( preg_match( '/' . $regex . '/', $matches ) ) {
+                               
+                               $this->config = $config;
+                               $this->variables = $matches;
+                               return true;
+                       }
+               }
+               
+               return false;
+       }
+       
+       /**
+        * Get or compute the configuration (MediaWiki, skins, extensions) for 
a wiki.
+        * 
+        * You have to specify the wiki, the suffix, and the version and, as 
parameters, the configuration
+        * and code directories and the caching file. This function uses a 
caching mechanism to avoid
+        * recompute each time the configuration; it is rebuilt when origin 
configuration files are changed.
+        * 
+        * The params argument should have the following keys:
+        * - 'configDir' (string) Configuration directory where are the various 
configuration files
+        * - 'codeDir' (string) Code directory where MediaWiki code is
+        * - 'cacheFile' (string) Template filename of the caching file
+        * - 'generalYamlFilename' (string) Path for the general YAML file, 
relative to configDir
+        * - 'suffixedYamlFilename' (string) Path for the suffixed YAML file, 
relative to configDir
+        * - 'privateYamlFilename' (string) Path for the privale YAML file, 
relative to configDir
+        * In cacheFile and suffixedYamlFilename, the string '$suffix' will be 
replaced by the actual
+        * suffix, and in cacheFile, the strings '$wiki' and '$version' will be 
replaced by the actual
+        * wiki identifier and the version.
+        * 
+        * The returned array has the following format:
+        * array( 'general' => array( 'wgSitename' => 'Foo', ... ),
+        *        'skins' => array( '_loading' => 'wfLoadSkin'|'require_once',
+        *                          'wgFlowParsoidTimeout' => 100, ...
+        *                        ),
+        *        'extensions' => array( '_loading' => 
'wfLoadExtension'|'require_once',
+        *                               'wgFlowParsoidTimeout' => 100, ...
+        *                             )
+        *      )
+        * 
+        * @param string $wiki Name of the wiki.
+        * @param string $suffix Suffix of the wiki (main family type).
+        * @param string $version Version of the wiki.
+        * @param SiteConfiguration $wgConf SiteConfigurat object from 
MediaWiki.
+        * @param $array params Parameters for this configuration management.
+        * @return array Global parameter variables and loading mechanisms for 
skins and extensions.
+        */
+       static function getMediaWikiConfig( $myWiki, $mySuffix, $myVersion, 
&$wgConf, $params ) {
+               
+               $codeDir = $params['codeDir'];
+               $cacheFile = $params['cacheFile'];
+               $generalYamlFilename = $params['generalYamlFilename'];
+               $suffixedYamlFilename = $params['suffixedYamlFilename'];
+               $privateYamlFilename = $params['privateYamlFilename'];
+               
+               $cacheFile = preg_replace( array( '/\$wiki/', '/\$suffix/', 
'/\$version/' ),
+                                              array( $myWiki, $mySuffix, 
$myVersion ),
+                                              $cacheFile );
+               
+               $suffixedYamlFilename = preg_replace( '/\$suffix/', $mySuffix, 
$suffixedYamlFilename );
+               
+               $globals = false;
+               
+               if( @filemtime( $cacheFile ) >= max( filemtime( 
$this->configDir.$generalYamlFilename ),
+                                                        filemtime( 
$this->configDir.$suffixedYamlFilename ),
+                                                        filemtime( 
$this->configDir.$privateYamlFilename ) ) )
+               {       
+                       $cache = @file_get_contents( $cacheFile );
+                       if ( $cache !== false ) {
+                               $globals = unserialize( $cache );
+                       }
+               }
+               else {
+                       
+                       $globals = array();
+                       $globals['general'] = array();
+                       $globals['skins'] = array();
+                       $globals['extensions'] = array();
+                       
+                       // Load InitialiseSettings.yml (general)
+                       $generalSettings = Yaml::parse( file_get_contents( 
$this->configDir.$generalYamlFilename ) );
+                       foreach( $generalSettings as $setting => $value ) {
+                               
+                               $wgConf->settings[$setting]['default'] = $value;
+                       }
+                       
+                       // Load InitialiseSettings.yml (client)
+                       $suffixedSettings = Yaml::parse( file_get_contents( 
$this->configDir.$suffixedYamlFilename ) );
+                       foreach( $suffixedSettings as $setting => $values ) {
+                               
+                               foreach( $values as $wiki => $val ) {
+                                       
+                                       if( $wiki == 'default' ) 
$wgConf->settings[$setting][$mySuffix] = $val;
+                                       else 
$wgConf->settings[$setting][$wiki.'-'.$mySuffix] = $val;
+                               }
+                       }
+                       
+                       // Load PrivateSettings.yml (general)
+                       $privateSettings = Yaml::parse( file_get_contents( 
$this->configDir.$privateYamlFilename ) );
+                       foreach( $privateSettings as $setting => $value ) {
+                               
+                               foreach( $value as $suffix => $val ) {
+                                       
+                                       $wgConf->settings[$setting][$suffix] = 
$val;
+                               }
+                       }
+                       
+                       // Get specific configuration for this wiki
+                       // Do not use SiteConfiguration::extractAllGlobals or 
the configuration caching would become
+                       // ineffective and there would be inconsistencies in 
this process
+                       $globals['general'] = $wgConf->getAll( 
$myWiki.'-'.$mySuffix, $mySuffix );
+                       
+                       // For the permissions array, fix a small strangeness: 
when an existing default permission
+                       // is true, it is not possible to make it false in the 
specific configuration
+                       if( array_key_exists( '+wgGroupPermissions', 
$wgConf->settings ) )
+                               
+                               $globals['general']['wgGroupPermissions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgGroupPermissions', 
$myWiki.'-'.$mySuffix, $mySuffix ), $globals['general']['wgGroupPermissions'] );
+                       
+                       //if( array_key_exists( '+wgDefaultUserOptions', 
$wgConf->settings ) )
+                               //$globals['general']['wgDefaultUserOptions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgDefaultUserOptions', 
$myWiki.'-'.$mySuffix, $mySuffix ), $globals['general']['wgDefaultUserOptions'] 
);
+                       
+                       // Extract from the general configuration skin and 
extension configuration
+                       // Search for skin and extension activation
+                       $unsetPrefixes = array();
+                       foreach( $globals['general'] as $setting => $value ) {
+                               if( preg_match( '/^wgUseSkin(.+)$/', $setting, 
$matches ) && $value === true ) {
+                                       
+                                       $skin = $matches[1];
+                                       if( is_dir( 
$codeDir.'/'.$myVersion.'/skins/'.$skin ) ) {
+                                               
+                                               $globals['skins'][$skin] = 
array();
+                                               if( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/skin.json' ) ) {
+                                                       
$globals['skins'][$skin]['_loading'] = 'wfLoadSkin';
+                                               }
+                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/'.$skin.'.php' ) ) {
+                                                       
$globals['skins'][$skin]['_loading'] = 'require_once';
+                                               }
+                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/skins/'.$skin.'/composer.json' ) ) {
+                                                       
$globals['skins'][$skin]['_loading'] = 'composer';
+                                               }
+                                               else {echo ' 
(unknown)';$unsetPrefixes[] = $skin;}
+                                       }
+                                       else $unsetPrefixes[] = $skin;
+                                       
+                                       unset( $globals['general'][$setting] );
+                               }
+                               elseif( preg_match( '/^wgUseExtension(.+)$/', 
$setting, $matches ) && $value === true ) {
+                                       
+                                       $extension = $matches[1];
+                                       if( is_dir( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension ) ) {
+                                               
+                                               
$globals['extensions'][$extension] = array();
+                                               if( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/extension.json' ) && 
$extension !== 'VisualEditor' ) {
+                                                       
$globals['extensions'][$extension]['_loading'] = 'wfLoadExtension';
+                                               }
+                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/'.$extension.'.php' ) ) {
+                                                       
$globals['extensions'][$extension]['_loading'] = 'require_once';
+                                               }
+                                               elseif( is_file( 
$codeDir.'/'.$myVersion.'/extensions/'.$extension.'/composer.json' ) ) {
+                                                       
$globals['extensions'][$extension]['_loading'] = 'composer';
+                                               }
+                                               else $unsetPrefixes[] = 
$extension;
+                                       }
+                                       else $unsetPrefixes[] = $extension;
+                                       
+                                       unset( $globals['general'][$setting] );
+                               }
+                               elseif( preg_match( 
'/^wgUse(?:Skin|Extension|LocalExtension)(.+)$/', $setting, $matches ) && 
$value !== true ) {
+                                       
+                                       $unsetPrefixes[] = $matches[1];
+                                       unset( $globals['general'][$setting] );
+                               }
+                       }
+                       
+                       // Extract from the general configuration skin and 
extension configuration
+                       $skins = array_keys( $globals['skins'] );
+                       $extensions = array_keys( $globals['extensions'] );
+                       foreach( $globals['general'] as $setting => $value ) {
+                               
+                               $found = false;
+                               foreach( $extensions as $extension ) {
+                                       if( preg_match( 
'/^wg'.preg_quote($extension,'/').'/', $setting ) ) {
+                                               
$globals['extensions'][$extension][$setting] = $value;
+                                               unset( $setting );
+                                               $found = true;
+                                               break;
+                                       }
+                               }
+                               if( !$found ) {
+                                       foreach( $skins as $skin ) {
+                                               if( preg_match( 
'/^wg'.preg_quote($skin,'/').'/', $setting ) ) {
+                                                       
$globals['skins'][$skin][$setting] = $value;
+                                                       unset( $setting );
+                                                       $found = true;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               if( !$found ) {
+                                       foreach( $unsetPrefixes as $prefix ) {
+                                               if( preg_match( 
'/^wg'.preg_quote($prefix,'/').'/', $setting ) ) {
+                                                       unset( $setting );
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       // Save this configuration in a serialised file
+                       @mkdir( dirname( $cacheFile ) );
+                       $tmpFile = tempnam( dirname( $cacheFile ), basename( 
$cacheFile ).'.tmp' );
+                       chmod( $tmpFile, 0640 );
+                       if( $tmpFile && file_put_contents( $tmpFile, serialize( 
$globals ) ) ) {
+                               rename( $tmpFile, $cacheFile );
+                       }
+               }
+               
+               return $globals;
+       }
+       
+       /**
+        * This function loads MediaWiki configuration (parameters).
+        * 
+        * @param array $extensions Subarray of general parameters (c.f. 
MediaWikiFarm:getMediaWikiConfig).
+        */
+       static function loadMediaWikiConfig( $settings ) {
+               
+               // Set general parameters as global variables
+               foreach( $settings as $setting => $value ) {
+                       
+                       $GLOBALS[$setting] = $value;
+               }
+       }
+       
+       /**
+        * This function load the skins configuration (wfLoadSkin loading 
mechanism and parameters).
+        * 
+        * WARNING: it doesn’t load the skins with the require_once mechanism 
(it is not possible in
+        * a function because variables would inherit the non-global scope); 
such skins must be loaded
+        * before calling this function.
+        * 
+        * @param array $extensions Subarray of skins parameters (c.f. 
MediaWikiFarm::getMediaWikiConfig).
+        */
+       static function loadSkinsConfig( $skins ) {
+               
+               // Load skins with the wfLoadSkin mechanism
+               foreach( $skins as $skin => $value ) {
+                       
+                       if( $value['_loading'] == 'wfLoadSkin' )
+                       
+                               wfLoadSkin( $skin );
+                       
+                       unset( $skins[$skin]['_loading'] );
+               }
+               
+               // Set skin parameters as global variables
+               foreach( $skins as $skin => $settings ) {
+                       
+                       foreach( $settings as $setting => $value )
+                               
+                               $GLOBALS[$setting] = $value;
+               }
+       }
+       
+       /**
+        * This function load the skins configuration (wfLoadSkin loading 
mechanism and parameters).
+        * 
+        * WARNING: it doesn’t load the skins with the require_once mechanism 
(it is not possible in
+        * a function because variables would inherit the non-global scope); 
such skins must be loaded
+        * before calling this function.
+        * 
+        * @param array $extensions Subarray of extensions parameters (c.f. 
MediaWikiFarm::getMediaWikiConfig).
+        */
+       static function loadExtensionsConfig( $extensions ) {
+               
+               // Load extensions with the wfLoadExtension mechanism
+               foreach( $extensions as $extension => $value ) {
+                       
+                       if( $value['_loading'] == 'wfLoadExtension' )
+                               
+                               wfLoadExtension( $extension );
+                       
+                       unset( $extensions[$extension]['_loading'] );
+               }
+               
+               // Set extension parameters as global variables
+               foreach( $extensions as $extension => $settings ) {
+                       
+                       foreach( $settings as $setting => $value )
+                               
+                               $GLOBALS[$setting] = $value;
+               }
+       }
+       
+       /**
+        * 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
+        * This function is almost the same as SiteConfiguration::arrayMerge, 
with the
+        * difference an existing scalar value has precedence EVEN if evaluated 
to false,
+        * in order to override permissions array with removed rights.
+        *
+        * @param array $array1.
+        *
+        * @return array
+        */
+       static function arrayMerge( $array1/* ... */ ) {
+               $out = $array1;
+               $argsCount = func_num_args();
+               for ( $i = 1; $i < $argsCount; $i++ ) {
+                       foreach ( func_get_arg( $i ) as $key => $value ) {
+                               if ( isset( $out[$key] ) && is_array( 
$out[$key] ) && is_array( $value ) ) {
+                                       $out[$key] = MediaWikiFarm::arrayMerge( 
$out[$key], $value );
+                               } elseif ( !isset( $out[$key] ) && !is_numeric( 
$key ) ) {
+                                       // Values that evaluate to true given 
precedence, for the
+                                       // primary purpose of merging 
permissions arrays.
+                                       $out[$key] = $value;
+                               } elseif ( is_numeric( $key ) ) {
+                                       $out[] = $value;
+                               }
+                       }
+               }
+               
+               return $out;
+       }
+}
+
+
+// Load skins with the require_once mechanism
+function MediaWikiFarm_loadSkinsConfig( $skins ) {
+       
+       foreach( $skins as $skin => $value ) {
+               
+               if( $value['_loading'] == 'require_once' )
+                       require_once "$IP/skins/$skin/$skin.php";
+       }
+}
+
+// Load extensions with the require_once mechanism
+function MediaWikiFarm_loadExtensionsConfig( $extensions ) {
+       
+       foreach( $extensions as $extension => $value ) {
+               
+               if( $value['_loading'] == 'require_once' )
+                       require_once "$IP/extensions/$extension/$extension.php";
+       }
+}
+

-- 
To view, visit https://gerrit.wikimedia.org/r/299359
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I178eeb8d2843b7fe78a75f8f7be79591a15269b0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MediaWikiFarm
Gerrit-Branch: master
Gerrit-Owner: Seb35 <seb35wikipe...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to