Seb35 has uploaded a new change for review.

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

Change subject: Improved management of identifiers/variables, I think it is 
ready for this part
......................................................................

Improved management of identifiers/variables, I think it is ready for this part
---
M config/farms.php
M config/farms.yml
M src/MediaWikiFarm.php
M src/main.php
4 files changed, 246 insertions(+), 120 deletions(-)


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

diff --git a/config/farms.php b/config/farms.php
index 4a196fc..e7ff326 100644
--- a/config/farms.php
+++ b/config/farms.php
@@ -3,7 +3,7 @@
 return array(
        
        # Configuration similar to the Wikimedia farm
-       '(?<lang>[a-z]+)\.(?<family>[a-z]+)\.org' => array(
+       '(?<lang>[a-z-]+)\.(?<family>[a-z]+)\.org' => array(
                
                'variables' => array(
                
@@ -11,11 +11,11 @@
                        ),
                        array( 'variable' => 'lang',
                               'file'     => 'org/$family.dblist',
-                              'type'     => 'language',
                        ),
                ),
                'suffix' => '$family',
                'wikiID' => '$lang$family',
+               'versions' => 'wikiversions.yml',
                'data' => '/srv/data/org/$family/$lang',
                'cache' => '/tmp/mw-cache/org-$version-$family-$lang',
                'config' => array(
diff --git a/config/farms.yml b/config/farms.yml
index 6e733b9..e53442c 100644
--- a/config/farms.yml
+++ b/config/farms.yml
@@ -1,5 +1,5 @@
 # Configuration similar to the Wikimedia farm
-'(?<lang>[a-z]+)\.(?<family>[a-z]+)\.org':
+'(?<lang>[a-z-]+)\.(?<family>[a-z]+)\.org':
     
     variables:
         
@@ -7,10 +7,10 @@
         
         - variable: 'lang'
           file: 'org/$family.dblist'
-          type: 'language'
     
     suffix: '$family'
     wikiID: '$lang$family'
+    versions: 'wikiversions.yml'
     data: '/srv/data/org/$family/$lang'
     cache: '/tmp/mw-cache/org-$version-$family-$lang'
     config:
diff --git a/src/MediaWikiFarm.php b/src/MediaWikiFarm.php
index fecaaf0..0c1cbbf 100644
--- a/src/MediaWikiFarm.php
+++ b/src/MediaWikiFarm.php
@@ -41,7 +41,7 @@
        /** @var array [private] Variables inside the host. */
        public $variables = array();
        
-       /** @var array [private] Selected MediaWiki version. */
+       /** @var array Selected wiki. */
        public $wiki = array();
        
        
@@ -69,99 +69,143 @@
        /**
         * Check the existence of the wiki, given variables values and files 
listing existing wikis.
         * 
-        * A wiki exists if all variables are defined in the URL and all values 
are found in the
-        * corresponding listing file. Files can be in PHP, YAML, or dblist.
+        * A wiki exists if:
+        *   - variables with a file attached are defined, and
+        *   - a wikiID can be computed, and
+        *   - a version is found and does exist, and
+        *   - the various properties of the wiki are defined.
         * 
-        * @return bool The wiki exists.
+        * @return bool The wiki does exist.
         */
        function checkExistence() {
-               
-               global $IP, $wgVersion;
                
                if( $this->unusable )
                        return false;
                
-               $keys = array();
-               $values = array();
-               $version = null;
-               
-               # For each variable, in the given order, check if the variable 
exists, check if the
-               # wiki exists in the corresponding listing file, and get the 
version if available
-               foreach( $this->config['variables'] as $variable ) {
-                       
-                       $key = $variable['variable'];
-                       
-                       # If the variable doesn’t exist, continue
-                       if( !array_key_exists( $key, $this->variables ) )
-                               continue;
-                       
-                       # Possibly the variables up to this one can be 
placeholders in filenames
-                       $value = $this->variables[$key];
-                       $keys[] = '/\$' . preg_quote( $key, '/' ) . '/';
-                       $values[] = $value;
-                       
-                       # If every values are correct, continue
-                       if( !array_key_exists( 'file', $variable ) )
-                               continue;
-                       
-                       # Really check if the variable is in the listing file
-                       $choices = $this->readFile( $this->configDir . '/' . 
preg_replace( $keys, $values, $variable['file'] ) );
-                       if( $choices === false )
-                               return false;
-                       
-                       # Check if the array is a simple list of wiki 
identifiers without version information…
-                       if( array_keys( $choices ) === range( 0, count( 
$choices ) - 1 ) ) {
-                               if( !in_array( $value, $choices ) )
-                                       return false;
-                       
-                       # …or a dictionary with wiki identifiers and 
corresponding version information
-                       } else {
-                               
-                               if( !array_key_exists( $value, $choices ) )
-                                       return false;
-                               
-                               if( isset( $this->codeDir ) && is_dir( 
$this->codeDir . '/' . ((string) $choices[$value]) ) && is_file( $this->codeDir 
. '/' . ((string) $choices[$value]) . '/includes/DefaultSettings.php' ) )
-                                       $version = (string) $choices[$value];
-                       }
-               }
-               
-               # When the wiki is found, replace all variables in other 
configuration files
-               $this->wiki = $this->config;
-               if( is_string( $version ) )
-                       $this->wiki['code'] = $this->codeDir . '/' . $version;
-               else
-                       $this->wiki['code'] = $IP;
-               
-               if( !$version ) $version = $wgVersion;
-               $this->variables['version'] = $version;
-               $this->wiki['version'] = $version;
-               
-               if( !array_key_exists( 'wikiID', $this->wiki ) || !is_string( 
$this->wiki['wikiID'] ) || !$this->wiki['wikiID'] ) {
-                       $this->unusable = true;
+               # Replace variables in the host name and possibly retrieve the 
version
+               if( ($version = $this->replaceHostVariables()) === false )
                        return false;
-               }
+               
+               # Set wikiID, the unique identifier of the wiki
+               if( !$this->setWikiID() )
+                       return false;
+               
+               # Set the version of the wiki
+               if( !$this->setVersion( $version ) )
+                       return false;
+               
+               # Set other properties of the wiki
+               if( !$this->setWikiProperties() )
+                       return false;
+               
+               $this->setWgConf();
+               
                return true;
        }
        
        /**
-        * Computation of the properties, which could depend on the suffix, 
wikiID, or other variables.
+        * Computation of the suffix and wikiID.
         * 
         * This function is the central point to get the unique identifier of 
the wiki, wikiID.
         * 
-        * @return void
+        * @return bool The wikiID and suffix were set, and the wiki could 
exist.
         */
        function setWikiID() {
                
-               global $wgConf;
-               
                if( $this->unusable )
-                       return;
+                       return false;
+               
+               $this->wiki = $this->config;
+               $this->wiki['version'] = null;
+               $this->wiki['globals'] = null;
                
                $this->setWikiProperty( 'suffix', false, true, true );
                $this->variables['suffix'] = $this->wiki['suffix'];
                
                $this->setWikiProperty( 'wikiID', false, false, true );
                $this->variables['wikiID'] = $this->wiki['wikiID'];
+               
+               if( !array_key_exists( 'wikiID', $this->wiki ) ) {
+                       $this->unusable = true;
+                       return false;
+               }
+               
+               if( !$this->wiki['wikiID'] )
+                       return false;
+               
+               return true;
+       }
+       
+       /**
+        * Setting of the version, either from the input if already got, either 
from a file.
+        * 
+        * @param string|null $version If a string, this is the version already 
got, just set it.
+        * @return bool The version was set, and the wiki could exist.
+        */
+       function setVersion( $version = null ) {
+               
+               global $IP, $wgVersion;
+               
+               if( $this->unusable )
+                       return false;
+               
+               $this->setWikiProperty( 'versions' );
+               
+               # In the case multiversion is configured and version is already 
known
+               if( is_string( $version ) && is_string( $this->codeDir ) && 
is_file( $this->codeDir . '/' . $version . '/includes/DefaultSettings.php' ) )
+                       $this->wiki['code'] = $this->codeDir . '/' . $version;
+               
+               # In the case multiversion is configured, but version is not 
known as of now
+               else if( is_null( $version ) && is_string( $this->codeDir ) ) {
+                       
+                       $versions = $this->readFile( $this->config['versions'] 
);
+                       
+                       if( !$versions ) {
+                               $this->unusable = true;
+                               return false;
+                       }
+                       
+                       if( array_key_exists( $this->wiki['wikiID'], $versions 
) && is_file( $this->codeDir . '/' . $versions[$this->wiki['wikiID']] . 
'/includes/DefaultSettings.php' ) )
+                               $version = $versions[$this->wiki['wikiID']];
+                       
+                       else if( $this->wiki['suffix'] && array_key_exists( 
$this->wiki['suffix'], $versions ) && is_file( $this->codeDir . '/' . 
$versions[$this->wiki['suffix']] . '/includes/DefaultSettings.php' ) )
+                               $version = $versions[$this->wiki['suffix']];
+                       
+                       else if( array_key_exists( 'default', $versions ) && 
is_file( $this->codeDir . '/' . $versions['default'] . 
'/includes/DefaultSettings.php' ) )
+                               $version = $versions['default'];
+                       
+                       else return false;
+                       
+                       $this->wiki['code'] = $this->codeDir . '/' . $version;
+               }
+               
+               # In the case no multiversion is configured
+               else if( is_null( $this->codeDir ) ) {
+                       
+                       $version = $wgVersion;
+                       $this->wiki['code'] = $IP;
+               }
+               else {
+                       $this->unusable = true;
+                       return false;
+               }
+               
+               # Set the version in the wiki configuration and as a variable 
to be used later
+               $this->variables['version'] = $version;
+               $this->wiki['version'] = $version;
+               
+               return true;
+       }
+       
+       /**
+        * Computation of the properties, which could depend on the suffix, 
wikiID, or other variables.
+        * 
+        * @return bool The wiki properties were set, and the wiki could exist.
+        */
+       function setWikiProperties() {
+               
+               if( $this->unusable )
+                       return false;
                
                $this->setWikiProperty( 'data', false );
                $this->setWikiProperty( 'cache', false );
@@ -176,6 +220,13 @@
                        $this->setWikiPropertyValue( $variable['post-config'], 
true );
                        $this->setWikiPropertyValue( $variable['exec-config'], 
true );
                }
+               
+               return true;
+       }
+       
+       function setWgConf() {
+               
+               global $wgConf;
                
                // TODO Still hacky: before setting parameters in stone in 
farms.yml, various configurations should be reviewed to select accordingly the 
rights management modelisation
                $wgConf->suffixes = array( $this->wiki['suffix'] );
@@ -270,6 +321,58 @@
                return false;
        }
        
+       /**
+        * Replacement of the variables in the host name.
+        * 
+        * @return string|null|false If an existing version is found in files, 
returns a string; if no version is found, returns null; if the host is missing 
in existence files, returns false; if an existence file is missing or badly 
formatted, return false and turns this object into a unusable state.
+        */
+       private function replaceHostVariables() {
+               
+               $version = null;
+               
+               # For each variable, in the given order, check if the variable 
exists, check if the
+               # wiki exists in the corresponding listing file, and get the 
version if available
+               foreach( $this->config['variables'] as $variable ) {
+                       
+                       $key = $variable['variable'];
+                       
+                       # If the variable doesn’t exist, continue
+                       if( !array_key_exists( $key, $this->variables ) )
+                               continue;
+                       $value = $this->variables[$key];
+                       
+                       # If every values are correct, continue
+                       if( !array_key_exists( 'file', $variable ) )
+                               continue;
+                       $filename = $variable['file'];
+                       
+                       # Really check if the variable is in the listing file
+                       $this->setWikiPropertyValue( $filename, false, false, 
true );
+                       $choices = $this->readFile( $this->configDir . '/' . 
$filename );
+                       if( $choices === false ) {
+                               $this->unusable = true;
+                               return false;
+                       }
+                       
+                       # Check if the array is a simple list of wiki 
identifiers without version information…
+                       if( array_keys( $choices ) === range( 0, count( 
$choices ) - 1 ) ) {
+                               if( !in_array( $value, $choices ) )
+                                       return false;
+                       
+                       # …or a dictionary with wiki identifiers and 
corresponding version information
+                       } else {
+                               
+                               if( !array_key_exists( $value, $choices ) )
+                                       return false;
+                               
+                               if( isset( $this->codeDir ) && is_dir( 
$this->codeDir . '/' . ((string) $choices[$value]) ) && is_file( $this->codeDir 
. '/' . ((string) $choices[$value]) . '/includes/DefaultSettings.php' ) )
+                                       $version = (string) $choices[$value];
+                       }
+               }
+               
+               return $version;
+       }
+       
        
        
        /*
@@ -294,14 +397,25 @@
                # Note the regex must be greedy to correctly select double 
extensions
                $format = preg_replace( '/^.*\.([a-z]+)$/', '$1', $filename );
                
-               if( $format == 'php' )
-                       return require $filename;
+               if( $format == 'php' ) {
+                       
+                       $array = require $filename;
+                       
+                       if( !is_array( $array ) )
+                               return false;
+                       
+                       return $array;
+               }
                
                if( $format == 'yml' ) {
                        
                        try {
                                
-                               return \Symfony\Component\Yaml\Yaml::parse( 
file_get_contents( $filename ) );
+                               $array = \Symfony\Component\Yaml\Yaml::parse( 
file_get_contents( $filename ) );
+                               if( !is_array( $array ) )
+                                       return false;
+                               
+                               return $array;
                        }
                        catch( \Symfony\Component\Yaml\Exception\ParseException 
$e ) {
                                
@@ -309,8 +423,15 @@
                        }
                }
                
-               if( $format == 'dblist' )
-                       return explode( "\n", file_get_contents( $filename ) );
+               if( $format == 'dblist' ) {
+                       
+                       $content = file_get_contents( $filename );
+                       
+                       if( !$content )
+                               return array();
+                       
+                       return explode( "\n", $content );
+               }
                
                return false;
        }
@@ -322,6 +443,7 @@
         * @param bool $toArray Change a string to an array with the string.
         * @param bool $create Create the property the empty string if 
non-existent.
         * @param bool $reset Empty the variables internal cache after 
operation.
+        * @return void
         */
        private function setWikiProperty( $name, $toArray = false, $create = 
false, $reset = false ) {
                
@@ -337,10 +459,11 @@
        /**
         * Set a wiki property and replace placeholders (value version).
         * 
-        * @param string $value Value of the property.
+        * @param string|null $value Value of the property.
         * @param bool $toArray Change a string to an array with the string.
         * @param bool $create Create the property the empty string if 
non-existent.
         * @param bool $reset Empty the variables internal cache after 
operation.
+        * @return void
         */
        private function setWikiPropertyValue( &$value, $toArray = false, 
$create = false, $reset = false ) {
                
@@ -356,11 +479,15 @@
                
                if( is_null( $value ) )
                        return;
-               
-               if( is_string( $value ) ) {
+               else if( is_string( $value ) ) {
                        
                        if( $toArray ) $value = array( $value );
                        else $value = preg_replace( $rkeys, $rvalues, $value );
+               }
+               else {
+                       
+                       $this->unusable = true;
+                       return;
                }
                
                if( $toArray ) {
@@ -406,10 +533,15 @@
         * @param SiteConfiguration $wgConf SiteConfigurat object from 
MediaWiki.
         * @return array Global parameter variables and loading mechanisms for 
skins and extensions.
         */
-       function getMediaWikiConfig( $myWiki, $mySuffix, &$wgConf ) {
+       function getMediaWikiConfig() {
+               
+               global $wgConf;
                
                if( $this->unusable )
                        return false;
+               
+               $myWiki = $this->wiki['wikiID'];
+               $mySuffix = $this->wiki['suffix'];
                
                $codeDir = $this->wiki['code'];
                $cacheFile = $this->wiki['cache'];
@@ -417,6 +549,7 @@
                $suffixedYamlFilename = 
'/'.$this->wiki['variables'][0]['config'][0];
                $privateYamlFilename = '/'.$this->wiki['post-config'][0];
                
+               //var_dump($wgConf);
                //var_dump($codeDir);
                //var_dump($myWiki);
                //var_dump($mySuffix);
@@ -428,8 +561,9 @@
                $globals = false;
                
                if( @filemtime( $cacheFile ) >= max( filemtime( 
$this->configDir.$generalYamlFilename ),
-                                                        filemtime( 
$this->configDir.$suffixedYamlFilename ),
-                                                        filemtime( 
$this->configDir.$privateYamlFilename ) ) )
+                                                    filemtime( 
$this->configDir.$suffixedYamlFilename ),
+                                                    filemtime( 
$this->configDir.$privateYamlFilename ) )
+                   && is_string( $cacheFile ) )
                {       
                        $cache = @file_get_contents( $cacheFile );
                        if ( $cache !== false ) {
@@ -478,16 +612,16 @@
                        // 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 );
+                       $globals['general'] = $wgConf->getAll( $myWiki, 
$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'] );
+                               $globals['general']['wgGroupPermissions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgGroupPermissions', $myWiki, 
$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'] 
);
+                               //$globals['general']['wgDefaultUserOptions'] = 
MediaWikiFarm::arrayMerge( $wgConf->get( '+wgDefaultUserOptions', $myWiki, 
$mySuffix ), $globals['general']['wgDefaultUserOptions'] );
                        
                        // Extract from the general configuration skin and 
extension configuration
                        // Search for skin and extension activation
@@ -581,11 +715,13 @@
                        $globals['extensions']['MediaWikiFarm']['_loading'] = 
'wfLoadExtension';
                        
                        // 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 );
+                       if( is_string( $cacheFile ) ) {
+                               @mkdir( dirname( $cacheFile ) );
+                               $tmpFile = tempnam( dirname( $cacheFile ), 
basename( $cacheFile ).'.tmp' );
+                               chmod( $tmpFile, 0640 );
+                               if( $tmpFile && file_put_contents( $tmpFile, 
serialize( $globals ) ) ) {
+                                       rename( $tmpFile, $cacheFile );
+                               }
                        }
                }
                
@@ -604,6 +740,14 @@
                if( $this->unusable )
                        return false;
                
+               if( !is_array( $this->wiki ) && array_key_exists( 'globals', 
$this->wiki ) ) {
+                       $this->unusable = true;
+                       return;
+               }
+               
+               if( !is_array( $this->wiki['globals'] ) )
+                       $this->getMediaWikiConfig();
+               
                // Set general parameters as global variables
                foreach( $this->wiki['globals']['general'] as $setting => 
$value ) {
                        
diff --git a/src/main.php b/src/main.php
index 2182132..48b8081 100644
--- a/src/main.php
+++ b/src/main.php
@@ -28,35 +28,17 @@
 
 
 /*
- * Set the wiki set
- */
-
-
-$wgMediaWikiFarm->setWikiID();
-
-$wvgClient = $wgMediaWikiFarm->variables['client'];
-$wvgWiki = $wgMediaWikiFarm->variables['wiki'];
-
-$wgConf->suffixes = array( $wvgClient );
-
-// Wikis: a simple list of the wikis for the requested client, e.g. array( 
'da', 'cv' )
-$wvgClientWikis = $wgMediaWikiFarm->readFile( 
$wgMediaWikiFarmConfigDir.'/'.$wvgClient.'/wikis.yml' );
-foreach( $wvgClientWikis as $wiki => $value ) {
-       $wgConf->wikis[] = $wiki.'-'.$wvgClient;
-}
-
-// Get the global configuration
-$wvgGlobals = $wgMediaWikiFarm->getMediaWikiConfig( $wvgWiki, $wvgClient, 
$wgConf );
-
-
-/*
  * MediaWiki
  */
 
 // Load general MediaWiki configuration
 $wgMediaWikiFarm->loadMediaWikiConfig();
 
+
 // Set system parameters
+$wvgClient = $wgMediaWikiFarm->variables['client'];
+$wvgWiki = $wgMediaWikiFarm->variables['wiki'];
+
 $wgUploadDirectory = 
'/srv/www/mediawiki-farm/data/'.$wvgClient.'/'.$wvgWiki.'/images';
 $wgCacheDirectory = 
'/srv/www/mediawiki-farm/data/'.$wvgClient.'/'.$wvgWiki.'/cache';
 
@@ -65,14 +47,14 @@
  * Skins
  */
 
-// Load skins with the require_once mechanism
-foreach( $wvgGlobals['skins'] as $skin => $value ) {
+# Load skins with the require_once mechanism
+foreach( $wgMediaWikiFarm->wiki['globals']['skins'] as $skin => $value ) {
        
        if( $value['_loading'] == 'require_once' )
                require_once "$IP/skins/$skin/$skin.php";
 }
 
-// Load skin configuration
+# Load skins with the wfLoadSkin mechanism
 $wgMediaWikiFarm->loadSkinsConfig();
 
 
@@ -80,14 +62,14 @@
  * Extensions
  */
 
-// Load extensions with the require_once mechanism
-foreach( $wvgGlobals['extensions'] as $extension => $value ) {
+# Load extensions with the require_once mechanism
+foreach( $wgMediaWikiFarm->wiki['globals']['extensions'] as $extension => 
$value ) {
        
        if( $value['_loading'] == 'require_once' )
                require_once "$IP/extensions/$extension/$extension.php";
 }
 
-// Load extension configuration
+# Load extensions with the wfLoadExtension mechanism
 $wgMediaWikiFarm->loadExtensionsConfig();
 
 // L’éditeur visuel cherchant toujours à se faire remarquer par les sysadmins, 
la

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3137976a4e259bf2871b7f3d6d9436aef3047816
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