Seb35 has uploaded a new change for review.

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

Change subject: [WIP] Improved early selection of a farm and a wiki, properly 
checked the existence of the wiki
......................................................................

[WIP] Improved early selection of a farm and a wiki, properly checked the 
existence of the wiki
---
M MediaWikiFarm.php
M src/MediaWikiFarm.php
2 files changed, 153 insertions(+), 45 deletions(-)


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

diff --git a/MediaWikiFarm.php b/MediaWikiFarm.php
index 11e950d..e30a048 100644
--- a/MediaWikiFarm.php
+++ b/MediaWikiFarm.php
@@ -29,7 +29,7 @@
 
 require_once "$IP/extensions/MediaWikiFarm/src/MediaWikiFarm.php";
 
-MediaWikiFarm::initialise();
+$wgMediaWikiFarm = MediaWikiFarm::initialise( $GLOBALS['_SERVER']['HTTP_HOST'] 
);
 
 
 
@@ -42,35 +42,37 @@
 # Select the configuration and export it
 //$farm->getConfig();
 
-function wvgGetWikiFromURL() {
-       
-       if( !preg_match( '/^([a-zA-Z0-9]+)-([a-zA-Z0-9]+)\.example.com$/', 
$GLOBALS['_SERVER']['HTTP_HOST'], $matches ) ) {
-               echo 'Error: unknown wiki.';
-               exit;
-       }
-       
-       return array( $matches[2], $matches[1] );
-}
+var_dump( $wgMediaWikiFarm );echo "\n\n<br /><br />";
 
-list( $wvgWiki, $wvgClient ) = wvgGetWikiFromURL();
+# Get client and wiki
 
-// Suffixes (clients): only the current client is saved to avoid any 
information leak to other clients, e.g. array( 'wikipedia' )
-$wgConf->suffixes = array( $wvgClient );
-if( !in_array( $wvgClient, Yaml::parse( file_get_contents( 
$wgMediaWikiFarmConfigDir . '/clients.yml' ) ) ) ) {
+$wvgClient = $wgMediaWikiFarm->variables['client'];
+$wvgWiki = $wgMediaWikiFarm->variables['wiki'];
+
+var_dump( $wvgClient );
+var_dump( $wvgWiki );
+echo "\n\n<br /><br />";
+
+
+# Check existence
+
+var_dump( $wgMediaWikiFarm->checkExistence() );
+echo "\n\n<br /><br />";
+
+if( !$wgMediaWikiFarm->checkExistence() ) {
+       
        echo 'Error: unknown wiki.';
        exit;
 }
 
+
+$wgConf->suffixes = array( $wvgClient );
+
 // Wikis: a simple list of the wikis for the requested client, e.g. array( 
'da', 'cv' )
-$wvgClientWikis = Yaml::parse( file_get_contents( 
$wgMediaWikiFarmConfigDir.'/'.$wvgClient.'/wikis.yml' ) );
+$wvgClientWikis = $wgMediaWikiFarm->readFile( 
$wgMediaWikiFarmConfigDir.'/'.$wvgClient.'/wikis.yml' );
 $wvgVersion = false;
 foreach( $wvgClientWikis as $wiki => $value ) {
        $wgConf->wikis[] = $wiki.'-'.$wvgClient;
-}
-
-if( !in_array( $wvgWiki.'-'.$wvgClient, $wgConf->wikis ) ) {
-       echo 'Error: unknown wiki.';
-       exit;
 }
 
 // Get version
@@ -81,6 +83,8 @@
        exit;
 }
 
+exit;
+
 // Obtain the global configuration
 $wvgGlobals = MediaWikiFarm::getMediaWikiConfig( $wvgWiki, $wvgClient, 
$wvgVersion, $wgConf,
                                                  array( 'codeDir' => 
$wgMediaWikiFarmCodeDir,
diff --git a/src/MediaWikiFarm.php b/src/MediaWikiFarm.php
index 9d77152..202a31d 100644
--- a/src/MediaWikiFarm.php
+++ b/src/MediaWikiFarm.php
@@ -1,4 +1,9 @@
 <?php
+/**
+ * Class MediaWikiFarm.
+ */
+
+require_once __DIR__ . '/../vendor/autoload.php';
 
 /**
  * This class computes the configuration of a specific wiki from a set of 
configuration files.
@@ -32,16 +37,57 @@
        /**
         * Initialise the unique object of type MediaWikiFarm.
         * 
+        * @param string 
         * @return MediaWikiFarm Singleton.
         */
-       static function initialise() {
+       static function initialise( $host ) {
                
                global $wgMediaWikiFarmConfigDir;
                
                if( self::$self == null )
-                       self::$self = new self( 
$GLOBALS['_SERVER']['HTTP_HOST'], $wgMediaWikiFarmConfigDir );
+                       self::$self = new self( $host, 
$wgMediaWikiFarmConfigDir );
+               
+               var_dump( self::$self->config );
                
                return self::$self;
+       }
+       
+       /**
+        * 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.
+        * 
+        * @return bool The wiki exists.
+        */
+       function checkExistence() {
+               
+               $keys = array();
+               $values = array();
+               
+               foreach( $this->config['variables'] as $variable ) {
+                       
+                       $key = $variable['variable'];
+                       if( !array_key_exists( $key, $this->variables ) )
+                               return false;
+                       
+                       $value = $this->variables[$key];
+                       $keys[] = '/\$' . preg_quote( $key, '/' ) . '/';
+                       $values[] = $value;
+                       
+                       $choices = $this->readFile( preg_replace( $keys, 
$values, $this->configDir.'/'.$variable['file'] ) );
+                       if( $choices === false )
+                               return false;
+                       
+                       $isNumeric = array_keys( $choices ) === range( 0, 
count( $choices ) - 1 );
+                       if( $isNumeric && !in_array( $value, $choices ) )
+                               return false;
+                       
+                       if( !$isNumeric && !array_key_exists( $value, $choices 
) )
+                               return false;
+               }
+               
+               return true;
        }
        
        
@@ -58,29 +104,21 @@
         */
        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
+               # Check parameters
+               if( !isset( $host ) || !is_string( $host ) || (isset( 
$configDir ) && !is_string( $configDir )) )
                        $this->unusable = true;
+               
+               # Get parameters
+               $this->configDir = is_string( $configDir ) ? $configDir : 
'/etc/mediawiki';
+               
+               # Read the farm configuration
+               if( $configs = $this->readFile( $this->configDir . '/farms.yml' 
) );
+               else if( $configs = $this->readFile( $this->configDir . 
'/farms.php' ) );
+               else $this->unusable = true;
                
                # Now select the right configuration amoung all farms
                if( !$this->unusable )
-                       $this->unusable = !$this->selectFarm( $config );
+                       $this->unusable = !$this->selectFarm( $configs, $host );
        }
        
        /**
@@ -92,15 +130,71 @@
         */
        private function selectFarm( $configs, $host ) {
                
+               # Check parameters
+               if( !isset( $configs ) || !is_array( $configs ) )
+                       return false;
+               
+               if( !isset( $host ) || !is_string( $host ) )
+                       return false;
+               
+               # For each proposed farm, check if the host matches
                foreach( $configs as $regex => $config ) {
                        
-                       if( preg_match( '/' . $regex . '/', $matches ) ) {
+                       if( preg_match( '/' . $regex . '/', $host, $matches ) ) 
{
                                
+                               # Get the selected configuration
                                $this->config = $config;
-                               $this->variables = $matches;
+                               $this->variables = array();
+                               
+                               # Initialise variables from the host
+                               foreach( $this->config['variables'] as 
$variable ) {
+                                       
+                                       if( array_key_exists( 
$variable['variable'], $matches ) )
+                                               
$this->variables[$variable['variable']] = $matches[$variable['variable']];
+                               }
+                               
                                return true;
                        }
                }
+               
+               return false;
+       }
+       
+       /**
+        * Read a file either in PHP, YAML, or dblist, and returns the 
interpreted array.
+        * 
+        * The choice between the format depends on the extension: php, yml, 
dblist.
+        * 
+        * @param string $filename Name of the requested file.
+        * @return array|false The interpreted array in case of success, else 
false.
+        */
+       function readFile( $filename ) {
+               
+               # Check parameter
+               if( !is_string( $filename ) || !is_file( $filename ) )
+                       return false;
+               
+               # Detect the format
+               # 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 == 'yml' ) {
+                       
+                       try {
+                               
+                               return \Symfony\Component\Yaml\Yaml::parse( 
file_get_contents( $filename ) );
+                       }
+                       catch( \Symfony\Component\Yaml\Exception\ParseException 
$e ) {
+                               
+                               return false;
+                       }
+               }
+               
+               if( $format == 'dblist' )
+                       return explode( "\n", file_get_contents( $filename ) );
                
                return false;
        }
@@ -422,7 +516,12 @@
 }
 
 
-// Load skins with the require_once mechanism
+/**
+ * Load skins with the require_once mechanism.
+ * 
+ * @param array $skins List of skins to be loaded.
+ * @return void
+ */
 function MediaWikiFarm_loadSkinsConfig( $skins ) {
        
        foreach( $skins as $skin => $value ) {
@@ -432,7 +531,12 @@
        }
 }
 
-// Load extensions with the require_once mechanism
+/**
+ * Load extensions with the require_once mechanism.
+ * 
+ * @param array $extensions List of extensions to be loaded.
+ * @return void
+ */
 function MediaWikiFarm_loadExtensionsConfig( $extensions ) {
        
        foreach( $extensions as $extension => $value ) {

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

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