r103982 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r103981‎ | r103982 | r103983 >
Date:23:34, 22 November 2011
Author:danwe
Status:deferred
Tags:
Comment:
My new extension SimpleFarm v0.1rc, will be released soon.
Modified paths:
  • /trunk/extensions/SimpleFarm (added) (history)
  • /trunk/extensions/SimpleFarm/COPYING (added) (history)
  • /trunk/extensions/SimpleFarm/README (added) (history)
  • /trunk/extensions/SimpleFarm/RELEASE-NOTES (added) (history)
  • /trunk/extensions/SimpleFarm/SimpleFarm.i18n.php (added) (history)
  • /trunk/extensions/SimpleFarm/SimpleFarm.php (added) (history)
  • /trunk/extensions/SimpleFarm/SimpleFarm_Classes.php (added) (history)
  • /trunk/extensions/SimpleFarm/SimpleFarm_Settings.php (added) (history)
  • /trunk/extensions/SimpleFarm/maintenance (added) (history)
  • /trunk/extensions/SimpleFarm/maintenance/maintainFarm.php (added) (history)

Diff [purge]

Index: trunk/extensions/SimpleFarm/SimpleFarm_Classes.php
@@ -0,0 +1,551 @@
 2+<?php
 3+/**
 4+ * 'SimpleFarm' and 'SimpleFarmMember' classes of the 'Simple Farm' extension.
 5+ *
 6+ * @file SimpleFarm_Classes.php
 7+ * @ingroup SimpleFarm
 8+ *
 9+ * @author Daniel Werner < danweetz@web.de >
 10+*/
 11+
 12+/**
 13+ * Contains functions for 'Simple Farm' farm managment.
 14+ *
 15+ * @since 0.1
 16+ */
 17+class SimpleFarm {
 18+ /**
 19+ * If set to a farm member within '$egSimpleFarmMembers' array (see settings file) it meains that
 20+ * the wiki is not in maintenance mode right now.
 21+ */
 22+ const MAINTAIN_OFF = false;
 23+ /**
 24+ * Block simple browser acces to the wiki but allow accessing the wiki with 'maintain' url parameter
 25+ */
 26+ const MAINTAIN_SIMPLE = 1;
 27+ /**
 28+ * Block all alltemts to acces wiki except for command-line
 29+ */
 30+ const MAINTAIN_STRICT = 2;
 31+ /**
 32+ * Block all attempts to access wiki, even command-line
 33+ */
 34+ const MAINTAIN_TOTAL = 3;
 35+
 36+ private static $activeMember = null;
 37+ public static $maintenanceIsRunning = false;
 38+
 39+ /**
 40+ * Returns the defined main member of the wiki farm.
 41+ * If $wgSimpleFarmMainMemberDB has not been set yet, this will set $wgSimpleFarmMainMemberDB
 42+ * to the first member in $wgSimpleFarmMembers
 43+ * @return SimpleFarmMember or null if no match could be found
 44+ */
 45+ public static function getMainMember() {
 46+ global $egSimpleFarmMainMemberDB, $egSimpleFarmMembers;
 47+
 48+ // if variable was not set in config, fill it with first farm member or return null if none is defined:
 49+ if( $egSimpleFarmMainMemberDB === null ) {
 50+ if( (int)$egSimpleFarmMembers )
 51+ $egSimpleFarmMainMemberDB = $egSimpleFarmMembers[0]['db'];
 52+ else
 53+ return null;
 54+ }
 55+ return SimpleFarmMember::loadFromDatabaseName( $egSimpleFarmMainMemberDB );
 56+ }
 57+
 58+ /**
 59+ * Returns the SimpleFarmMember object selected to be loaded for this instance of the farm
 60+ * or the object that has already been loaded.
 61+ * If initialisation has not been kicked off yet, this will find the wiki which would be
 62+ * chosen by self::int(). The result of the function could change after self::intWiki()
 63+ * was called to initialise another wiki instead.
 64+ * $wgSimpleFarmWikiSelectEnvVarName should contain its final value when first calling this.
 65+ *
 66+ * @return SimpleFarmMember or null if no match was found
 67+ */
 68+ public static function getActiveMember() {
 69+ global $IP, $wgCommandLineMode;
 70+ global $egSimpleFarmMembers, $egSimpleFarmMainMemberDB, $egSimpleFarmWikiSelectEnvVarName;
 71+
 72+ // return last initialised farm member if available:
 73+ if( self::$activeMember !== null ) {
 74+ return self::$activeMember;
 75+ }
 76+
 77+ if( ! defined( 'SIMPLEFARM_ENVVAR' ) ) {
 78+ define( 'SIMPLEFARM_ENVVAR', $egSimpleFarmWikiSelectEnvVarName );
 79+ }
 80+ // in commandline mode we check for environment variable to stelect a wiki:
 81+ if( $wgCommandLineMode ) {
 82+ /*
 83+ * if we are in command-line mode but no wiki was selected
 84+ * and this is not just the initial wiki call to run maintenance
 85+ * on several wikis
 86+ */
 87+ $wikiEvn = getenv( SIMPLEFARM_ENVVAR );
 88+
 89+ if( $wikiEvn === false ) {
 90+ // running SimpleFarm maintenance script which will maintain all wikis:
 91+ if( self::$maintenanceIsRunning ) {
 92+ $wikiEvn = $egSimpleFarmMainMemberDB;
 93+ } else {
 94+ return null; // commandline-mode for specific wiki but no wiki was chosen!
 95+ }
 96+ }
 97+ return SimpleFarmMember::loadFromDatabaseName( $wikiEvn );
 98+ }
 99+ // farm member called via browser, find out which member via server name:
 100+ else {
 101+ // only interesting if redirect_url is set, otherwise unlikely to be used anyway
 102+ $currScriptPath = isset( $_SERVER['REDIRECT_URL'] ) ? $_SERVER['REDIRECT_URL'] : $_SERVER['SCRIPT_NAME'];
 103+ /*
 104+ * in case the script path was called directly and not some page within the directory,
 105+ * just make sure to add '.' behind the last '/' before getting the directory name
 106+ * '/bla/' returns '/', '/bla/.' returns '/bla' !
 107+ */
 108+ $currScriptPath = dirname( preg_replace( '%[\\/\\\]$%', '/.', $currScriptPath ) );
 109+
 110+ /*
 111+ * in case "<domain>/<uri>" without '/' after, the above will return '\' (windows)
 112+ * or '/' (unix). Take the whole requested URI then since it could be the scriptpath
 113+ * directory or just a file in the root dir...
 114+ */
 115+ if( preg_match( '%[\\/\\\]$%', $currScriptPath ) )
 116+ $currScriptPath = $_SERVER['REDIRECT_URL'];
 117+ /*
 118+ echo $currScriptPath . "<br/>";
 119+ echo "is_dir: " . is_dir( $_SERVER['DOCUMENT_ROOT'] . $_SERVER['REDIRECT_URL'] ) . "<br/>";
 120+ echo "<html><body><pre>";
 121+ print_r( $_SERVER );
 122+ echo "</pre></br>" . $currScriptPath . "<br/>" . preg_replace( '%[\\/\\\]$%', '/.', $_SERVER['REDIRECT_URL'] ) . "<br/>" . $_SERVER['REQUEST_URI'] . "</body></html>";
 123+ die( 1 );
 124+ */
 125+ // walk all farm members and see whether it fullfils criteria to be the loaded one right now:
 126+ foreach( self::getMembers() as $member ) {
 127+
 128+ switch( $member->getCfgMode() ) {
 129+
 130+ // configuration uses script path for this one to identify as selected:
 131+ case SimpleFarmMember::CFG_MODE_SCRIPTPATH:
 132+ if( $member->getScriptPath() === $currScriptPath ) {
 133+ return $member;
 134+ }
 135+ break;
 136+
 137+ // configuration uses a set of addresses to identifiy as selected:
 138+ case SimpleFarmMember::CFG_MODE_ADDRESS:
 139+ if( in_array( $_SERVER['HTTP_HOST'], $member->getAddresses(), true ) ) {
 140+ return $member;
 141+ }
 142+ break;
 143+
 144+ // if not set up properly:
 145+ case SimpleFarmMember::CFG_MODE_NONE:
 146+ continue;
 147+ }
 148+ }
 149+ return null; // no macht with configuration array!
 150+ }
 151+ }
 152+
 153+ /**
 154+ * Initialises the selected member wiki of the wiki farm. This is only possible
 155+ * once and must be done during localsettings configuration *
 156+ * This will also modify some global variables, see SimpleFarm::initWiki() for details
 157+ *
 158+ * @return boolean true
 159+ */
 160+ public static function init() {
 161+ // don't allow multiple calls!
 162+ if( self::$activeMember !== null )
 163+ return true; // for hook use!
 164+
 165+ global $egSimpleFarmMainMemberDB, $wgCommandLineMode;
 166+
 167+ // set some main member if not set in config and farm has members:
 168+ if( $egSimpleFarmMainMemberDB === null ) {
 169+ $egSimpleFarmMainMemberDB = self::getMainMember()->getDB();
 170+ }
 171+ // get selected member for this farm call:
 172+ $wiki = self::getActiveMember();
 173+
 174+ // if wiki is not in farm list:
 175+ if( $wiki === null ) {
 176+ if( $wgCommandLineMode ) {
 177+ self::dieEarly( 'Environment variable "' . SIMPLEFARM_ENVVAR . '" must be set to an existing farm member database name to select a wiki in command-line mode!' );
 178+ }
 179+ else {
 180+ // wiki not found, try to call user defined callback function and try return value:
 181+ // (can't use hook-system here since it propably isn't loaded at this sage!)
 182+ global $egSimpleFarmErrorNoMemberFoundCallback;
 183+
 184+ if( is_callable( $egSimpleFarmErrorNoMemberFoundCallback ) ) {
 185+ $wiki = call_user_func( $egSimpleFarmErrorNoMemberFoundCallback );
 186+ }
 187+
 188+ if( ! ( $wiki instanceof SimpleFarmMember ) ) {
 189+ header( $_SERVER["SERVER_PROTOCOL"] . " 404 Not Found" );
 190+ self::dieEarly( 'No wiki farm member found here!' );
 191+ }
 192+ }
 193+ }
 194+ self::initWiki( $wiki );
 195+ return true; // for hook use!
 196+ }
 197+
 198+ /**
 199+ * Function to set all setup options to load a specific wiki of the wiki farm.
 200+ * Should only be called while 'LocalSettings.php' is running and after
 201+ * SimpleFarm extension has been initialised.
 202+ *
 203+ * This will modify the following globals:
 204+ *
 205+ * $wgSitename = SimpleFarmMember::getName();
 206+ * $wgDBname = SimpleFarmMember::getDB();
 207+ * $wgScriptPath = SimpleFarmMember::getScriptPath();
 208+ * $wgLocalInterwiki = strtolower( $wgSitename );
 209+ * $wgUploadDirectory = "{$IP}/images/images_{$wgDBname}";
 210+ * $wgUploadPath = "{$wgScriptPath}/images/images_{$wgDBname}";
 211+ * $wgLogo = "{$wgScriptPath}/images/logo/{$wgDBname}.png";
 212+ * $wgFavicon = "{$wgScriptPath}/images/logo/{$wgDBname}.ico";
 213+ *
 214+ * @param $wiki SimpleFarmMember to initialise
 215+ */
 216+ public static function initWiki( SimpleFarmMember $wiki ) {
 217+ global $IP;
 218+ // globals to be configured:
 219+ global $wgScriptPath, $wgSitename, $wgLocalInterwiki, $wgDBname, $wgUploadDirectory, $wgUploadPath, $wgLogo, $wgFavicon;
 220+
 221+ $wgSitename = $wiki->getName();
 222+ $wgLocalInterwiki = strtolower( $wgSitename );
 223+
 224+ // check for maintain mode:
 225+ if( $wiki->isInMaintainMode() && ! $wiki->userIsMaintaining() )
 226+ self::dieEarly( "$wgSitename is in maintain mode currently! Please try again later." );
 227+
 228+ self::$activeMember = $wiki;
 229+
 230+ $wgScriptPath = $wiki->getScriptPath(); //in case of 'scriptpath' config and mod-rewrite, otherwise same value anyway
 231+ $wgDBname = $wiki->getDB();
 232+ $wgUploadDirectory = "{$IP}/images/images_{$wgDBname}";
 233+ $wgUploadPath = "{$wgScriptPath}/images/images_{$wgDBname}";
 234+ if( ! is_dir( $wgUploadDirectory ) )
 235+ mkdir( $wgUploadDirectory, 0777 );
 236+
 237+ $wgLogo = "{$wgScriptPath}/images/logo/{$wgDBname}.png";
 238+ $wgFavicon = "{$wgScriptPath}/images/logo/{$wgDBname}.ico";
 239+
 240+ /*
 241+ * it's no good loading an individual config file here since it wouldn't
 242+ * be in the global scope and all globals had to be defined as global first...
 243+ * Hacking around this is too dirty (reading all globals in local scope and then
 244+ * transferring local scope back to global scope).
 245+ *
 246+ * There is an easy way to allow custom config files in LocalSettings directly though:
 247+ *
 248+ * if( file_exists( "$IP/wikiconfigs/$wgDBname.php" ) ) {
 249+ * include( "$IP/wikiconfigs/$wgDBname.php" );
 250+ * }
 251+ */
 252+ return true;
 253+ }
 254+
 255+ /**
 256+ * Return an array with all members as SimpleFarmMember objects. The key of each array item
 257+ * is the database name of the wiki farm member.
 258+ *
 259+ * @return SimpleFarmMember[]
 260+ */
 261+ public static function getMembers() {
 262+ global $egSimpleFarmMembers;
 263+ $members = array();
 264+ foreach( $egSimpleFarmMembers as $member ) {
 265+ $members[ $member['db'] ] = new SimpleFarmMember( $member );
 266+ }
 267+ return $members;
 268+ }
 269+
 270+ /**
 271+ * Use instead of wfDie() because global functions are loaded after localsettings.php
 272+ * and in some cases this could happen during localsettings is still running!
 273+ *
 274+ * @param $dieMsg string message
 275+ */
 276+ private static function dieEarly( $dieMsg = '' ) {
 277+ echo $dieMsg;
 278+ die( 1 );
 279+ }
 280+}
 281+
 282+
 283+/**
 284+ * Represents a SimpleFarm member wiki.
 285+ *
 286+ * @since 0.1
 287+ */
 288+class SimpleFarmMember {
 289+
 290+ private $siteOpt;
 291+
 292+ const CFG_MODE_NONE = 0;
 293+ const CFG_MODE_ADDRESS = 1;
 294+ const CFG_MODE_SCRIPTPATH = 2;
 295+
 296+ public function __construct( $siteOptions ) {
 297+ $this->siteOpt = $siteOptions;
 298+ }
 299+
 300+ /**
 301+ * Load new SimpleFarmMember from its database name.
 302+ * If not successful null will be returned.
 303+ *
 304+ * @param $dbName string name of the database, case-insensitive
 305+ *
 306+ * @return SimpleFarmMember|null
 307+ */
 308+ public static function loadFromDatabaseName( $dbName ) {
 309+ global $egSimpleFarmMembers;
 310+
 311+ foreach( $egSimpleFarmMembers as $siteOpt ) {
 312+ if( strtolower( $siteOpt['db'] ) === strtolower( trim( $dbName ) ) )
 313+ return new SimpleFarmMember( $siteOpt );
 314+ }
 315+ return null;
 316+ }
 317+
 318+ /**
 319+ * Load new SimpleFarmMember from one of its addresses.
 320+ *
 321+ * @ToDo: More flexible and allowing other ways of forking farm members!
 322+ *
 323+ * @param $url String url or domain to datermine one of the registered server names/url for
 324+ * this wiki-farm member. For example 'www.farm1.wikifarm.org' @ToDo: or 'http://foo.org/wiki1'.
 325+ * Value is case-insensitive.
 326+ * @param $scriptPath String farm member script path as second criteria in addition to address
 327+ *
 328+ * @return SimpleFarmMember if not successful null will be returned
 329+ */
 330+ public static function loadFromAddress( $url, $scriptPath = null ) {
 331+ global $egSimpleFarmMembers, $egSimpleFarmIgnoredDomainPrefixes;
 332+
 333+ if( $scriptPath !== null )
 334+ $scriptPath = str_replace( "\\", "/", trim( $scriptPath ) );
 335+
 336+ // url to domain name. Trim url scheme,
 337+ $pref = implode( '|', $egSimpleFarmIgnoredDomainPrefixes ); // no escaping necessary
 338+ $url = str_replace( "\\", "/", strtolower( $url ) ); // for windows-style paths
 339+ $address = preg_replace( '%^(?:.*://)?(?:(?:' . $pref . ')\.)?%', '', $url );
 340+ $address = preg_replace( '%/.*%', '', $address );
 341+
 342+ $members = SimpleFarm::getMembers();
 343+ foreach( $members as $member ) {
 344+ // if url matches:
 345+ if( in_array( $address, $member->getAddresses() ) ) {
 346+ // if script path is required, then check for it too:
 347+ if( $scriptPath !== null ) {
 348+ if( trim( $scriptPath ) === $member->getScriptPath() )
 349+ return $member;
 350+ } else {
 351+ return $member;
 352+ }
 353+ }
 354+
 355+ }
 356+ return null;
 357+ }
 358+
 359+ /**
 360+ * Load new SimpleFarmMember from its 'scriptpath' config value.
 361+ *
 362+ * @param $scriptPath String configured script path of the farm member which should be returend.
 363+ *
 364+ * @return SimpleFarmMember if not successful null will be returned
 365+ */
 366+ public static function loadFromScriptPath( $scriptPath ) {
 367+ $members = SimpleFarm::getMembers();
 368+ foreach( $members as $member ) {
 369+ if( $scriptPath !== null ) {
 370+ if( trim( $scriptPath ) === $member->getScriptPath() )
 371+ return $member;
 372+ } else {
 373+ return $member;
 374+ }
 375+ }
 376+ }
 377+
 378+ /**
 379+ * Whether the wiki is set to maintaining mode right now.
 380+ * Returns the maintaining strictness.
 381+ *
 382+ * @return Integer
 383+ */
 384+ public function isInMaintainMode() {
 385+ if( empty( $this->siteOpt['maintain'] ) )
 386+ return SimpleFarm::MAINTAIN_OFF;
 387+ else
 388+ return $this->siteOpt['maintain'];
 389+ }
 390+
 391+ /**
 392+ * Returns whether the user is a maintainer or not. A maintainer is the current user
 393+ * if he accesses the wiki via command-line or if he has the 'maintainer' url parameter set.
 394+ *
 395+ * @param User $user the user we want to know whether he is a maintainer right now.
 396+ * If not set, the information will be returned for the current user.
 397+ * This will only work after 'LocalSettings.php' since $wgUser is undefined ealrier!
 398+ *
 399+ * @return Boolean
 400+ */
 401+ public function userIsMaintaining( User $user = null ) {
 402+ global $wgUser, $wgCommandLineMode;
 403+
 404+ // if $user is not the current user, he can't be maintaining anything right now
 405+ if( $user === null ) {
 406+ // $wgUser still null during localsettings.php config
 407+ $user = $wgUser;
 408+ }
 409+ if( $wgUser !== null && $user->getId() !== $wgUser->getId() ) {
 410+ return false;
 411+ }
 412+
 413+ // commandline usually is maintainer, so is the user if maintainer parameter is set in url
 414+ switch( $this->isInMaintainMode() ) {
 415+ // no break, step by step!
 416+ case SimpleFarm::MAINTAIN_SIMPLE:
 417+ if( isset( $_GET['maintainer'] ) || isset( $_GET['maintain'] ) )
 418+ return true;
 419+ // no break!
 420+
 421+ case SimpleFarm::MAINTAIN_STRICT:
 422+ if( $wgCommandLineMode )
 423+ return true;
 424+ // no break!
 425+
 426+ case SimpleFarm::MAINTAIN_TOTAL:
 427+ default:
 428+ return false;
 429+ }
 430+ }
 431+
 432+ /**
 433+ * Returns the Database name
 434+ *
 435+ * @return String
 436+ */
 437+ public function getDB() {
 438+ return $this->siteOpt['db'];
 439+ }
 440+
 441+ /**
 442+ * Returns the wiki name
 443+ *
 444+ * @return String
 445+ */
 446+ public function getName() {
 447+ global $egSimpleFarmMembers;
 448+ return $this->siteOpt['name'];
 449+ }
 450+
 451+ /**
 452+ * Returns all domains of the wiki (either from $wgSimpleFarmMembers or in case
 453+ * 'scriptpath' is used, from the server directly.
 454+ *
 455+ * @return String[] or null in case of command-line access and missing 'address'
 456+ * key in $wgSimpleFarmMembers config array.
 457+ */
 458+ public function getAddresses() {
 459+ // if addresses are not configured, return the server name:
 460+ if( isset( $this->siteOpt['addresses'] ) ) {
 461+ $addr = $this->siteOpt['addresses'];
 462+ }
 463+ elseif( isset( $_SERVER['HTTP_HOST'] ) ) {
 464+ return array( $_SERVER['HTTP_HOST'] );
 465+ }
 466+ else {
 467+ return null; // in case arr option is not set and we are in commandline-mode!
 468+ }
 469+
 470+ if( is_array( $addr ) ) {
 471+ return $addr;
 472+ }
 473+ else {
 474+ return array( $addr );
 475+ }
 476+ }
 477+
 478+ /**
 479+ * returns the configured script path if set.
 480+ * Otherwise the value of $wgScriptPath
 481+ *
 482+ * @return String
 483+ */
 484+ public function getScriptPath() {
 485+ if( isset( $this->siteOpt['scriptpath'] ) ) {
 486+ $scriptPath = $this->siteOpt['scriptpath'];
 487+ } else {
 488+ global $wgScriptPath;
 489+ $scriptPath = $wgScriptPath;
 490+ }
 491+ return str_replace( "\\", "/", trim( $scriptPath ) );
 492+ }
 493+
 494+ /**
 495+ * returns the config mode this farm member uses to be selected as active wiki.
 496+ *
 497+ * @return Integer flag self::CFG_MODE_SCRIPTPATH, self::CFG_MODE_ADDRESS or
 498+ * self::CFG_MODE_NONE if not set up properly.
 499+ */
 500+ public function getCfgMode() {
 501+ if( isset( $this->siteOpt['scriptpath'] ) )
 502+ return self::CFG_MODE_SCRIPTPATH;
 503+ elseif( isset( $this->siteOpt['addresses'] ) )
 504+ return self::CFG_MODE_ADDRESS; //address can be given even if 'scriptpath' is
 505+ else
 506+ return self::CFG_MODE_NONE;
 507+ }
 508+
 509+ /**
 510+ * Whether or not this member wiki has been declared the main member.
 511+ * The main member is important for maintenance reasons only.
 512+ *
 513+ * @return Boolean
 514+ */
 515+ public function isMainMember() {
 516+ return ( $this->getDB() === SimpleFarm::getMainMember()->getDB() );
 517+ }
 518+
 519+ /**
 520+ * Whether the farm member wiki is the wiki currently accessed in this run.
 521+ *
 522+ * @return Boolean
 523+ */
 524+ public function isActive() {
 525+ return ( $this->getDB() === SimpleFarm::getActiveMember()->getDB() );
 526+ }
 527+
 528+ /**
 529+ * Returns an value previously set for this object via $wgSimpleFarmMembers configuration.
 530+ *
 531+ * @param $name String name of the array key representing an option
 532+ * within the $wgSimpleFarmMembers sub-array for this object
 533+ * @param $default Mixed default value if config key $name was not set for farm member
 534+ *
 535+ * @return Mixed
 536+ */
 537+ public function getCfgOption( $name, $default = null ) {
 538+ if( array_key_exists( $name, $this->siteOpt ) )
 539+ return $this->siteOpt[ $name ];
 540+ else
 541+ return $default;
 542+ }
 543+
 544+ /**
 545+ * Same as SimpleFarmMember::getCfgOption
 546+ *
 547+ * @return Mixed
 548+ */
 549+ public function __invoke( $name, $default = null ) {
 550+ return $this->getCfgOption( $name, $default );
 551+ }
 552+}
\ No newline at end of file
Property changes on: trunk/extensions/SimpleFarm/SimpleFarm_Classes.php
___________________________________________________________________
Added: svn:eol-style
1553 + native
Index: trunk/extensions/SimpleFarm/maintenance/maintainFarm.php
@@ -0,0 +1,122 @@
 2+<?php
 3+/**
 4+ * Connect with one 'Simple Farm' farm member and start several maintenance
 5+ * scripts from there to maintain several farm members at the same time.
 6+ *
 7+ * @file maintainFarm.php
 8+ * @ingroup Maintenance
 9+ * @ingroup SimpleFarm
 10+ *
 11+ * @author Daniel Werner < danweetz@web.de >
 12+ */
 13+
 14+require_once dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php';
 15+require_once dirname( __FILE__ ) . '/../SimpleFarm_Classes.php';
 16+
 17+/**
 18+ * 'Simple Farm' maintenance handler
 19+ *
 20+ * @since 0.1
 21+ */
 22+class SimpleFarmerMaintenance extends Maintenance {
 23+
 24+ function __construct() {
 25+ SimpleFarm::$maintenanceIsRunning = true;
 26+ parent::__construct();
 27+
 28+ $this->mDescription = "'Simple Farm' farmer script for maintaining several farm members with just one command";
 29+ $this->addOption( 'farmexclude', 'comma-separated list of wikis to deselect for farming (by database name)' );
 30+ $this->addOption( 'farmonly', 'comma-separated list of wikis to select for doing some farming on (by database name)' );
 31+ $this->addOption( 'farmpreview', 'if set this will output all selected wikis for farming without running any further action' );
 32+ $this->addArg( 'command', 'the command-line command to execute for each selected farm member', false );
 33+ }
 34+
 35+ public function getDbType() {
 36+ return Maintenance::DB_NONE;
 37+ }
 38+
 39+ public function execute() {
 40+ global $egSimpleFarmWikiSelectEnvVarName;
 41+
 42+ $prfx = '~~ '; // prefix in front of each line to make an optical difference to passthru scripts
 43+
 44+ $selected = SimpleFarm::getMembers();
 45+ $totalMembers = count( $selected );
 46+
 47+ // farmexclude:
 48+ $excluded = preg_split( '/\s*,\s*/', trim( $this->getOption( 'farmexclude', '' ) ) );
 49+ $selected = array_diff_key( $selected, array_flip( $excluded ) );
 50+
 51+ // farmonly:
 52+ if( $this->getOption( 'farmonly' ) !== null ) {
 53+ $only = preg_split( '/\s*,\s*/', trim( $this->getOption( 'farmonly', '' ) ) );
 54+ $selected = array_intersect_key( $selected, array_flip( $only ) );
 55+ }
 56+
 57+ // information about how many are selected:
 58+ $selectedMembers = count( $selected );
 59+ if( $selectedMembers === 0 ) {
 60+ $this->output( "\n{$prfx}None of the $totalMembers farm members are selected!" );
 61+ }
 62+ elseif( $totalMembers === $selectedMembers ) {
 63+ $this->output( "\n{$prfx}All $totalMembers members of the farm are selected:" );
 64+ }
 65+ else {
 66+ $this->output( "\n{$prfx}The following $selectedMembers out of $totalMembers farm members are selected:" );
 67+ }
 68+
 69+ // print selected members:
 70+ $longest = 0;
 71+ foreach( $selected as $member ) {
 72+ if( ( $currLen = strlen( $member->getName() ) ) > $longest )
 73+ $longest = $currLen;
 74+ }
 75+
 76+ $i = 0;
 77+ foreach( $selected as $member ) {
 78+ $i++;
 79+ $this->output( "\n{$prfx}($i) Name: " . str_pad( "'{$member->getName()}'", $longest + 2, ' ', STR_PAD_RIGHT ) . " DB: '{$member->getDB()}'" );
 80+ }
 81+
 82+ // if we are in preview mode, just display what has been selected and end:
 83+ if( $this->getOption( 'farmpreview' ) !== null )
 84+ return; // no further action
 85+
 86+ // finally, run the script for each:
 87+ $script = $this->getArg( 0 );
 88+ if( $script === null ) {
 89+ $this->error( "\n{$prfx}No maintaining command has been set! Argument <command> required!", true );
 90+ }
 91+
 92+ $this->output( "\n\n{$prfx}Start maintaining selected 'Simple Farm' members:" );
 93+ $this->output( "\n{$prfx}Command: '{$script}'" );
 94+ $i = 0;
 95+ $failed = 0;
 96+
 97+ foreach( $selected as $member ) {
 98+ $i++;
 99+ $this->output( "\n\n{$prfx}({$i}/{$selectedMembers}) Running command for member '{$member->getName()}' ({$egSimpleFarmWikiSelectEnvVarName}={$member->getDB()})...\n\n" );
 100+ putenv( SIMPLEFARM_ENVVAR . "={$member->getDB()}" );
 101+ $fail = null;
 102+ passthru( $script, $fail );
 103+ if( $fail ) { // value other than 0 implies an error
 104+ $failed++;
 105+ }
 106+ }
 107+
 108+ $this->output( "\n\n{$prfx}Finished! All {$selectedMembers} selected 'Simple Farm' members have been maintained" );
 109+
 110+ // check whether we had any errors along the way:
 111+ if( $failed > 0 ) {
 112+ // send out some warning!
 113+ $this->output( "\n{$prfx}WARNING: {$failed} of the command executions have returned a value implying an error. See output above!\n" );
 114+ }
 115+ else {
 116+ // success!
 117+ $this->output( "\n{$prfx}Apparently, no error has occured during command executions :-)\n" );
 118+ }
 119+ }
 120+}
 121+
 122+$maintClass = 'SimpleFarmerMaintenance';
 123+require_once( RUN_MAINTENANCE_IF_MAIN );
Property changes on: trunk/extensions/SimpleFarm/maintenance/maintainFarm.php
___________________________________________________________________
Added: svn:eol-style
1124 + native
Index: trunk/extensions/SimpleFarm/SimpleFarm.i18n.php
@@ -0,0 +1,27 @@
 2+<?php
 3+
 4+/**
 5+ * Internationalization file of the 'Simple Farm' extension.
 6+ *
 7+ * @since 0.1
 8+ *
 9+ * @file SimpleFarm.i18n.php
 10+ * @ingroup SimpleFarm
 11+ * @author Daniel Werner < danweetz@web.de >
 12+ */
 13+
 14+$messages = array();
 15+
 16+/** English
 17+ * @author Daniel Werner
 18+ */
 19+$messages['en'] = array(
 20+ 'parserfun-desc' => 'Simple, yet powerfull wiki farm extension without any fancy configuration pages.',
 21+);
 22+
 23+/** German (Deutsch)
 24+ * @author Daniel Werner
 25+ */
 26+$messages['de'] = array(
 27+ 'parserfun-desc' => 'Einfache, jedoch trotzdem mächtige Wiki-Farm-Erweiterung ohne großartige Konfigurations-Seiten.',
 28+);
Property changes on: trunk/extensions/SimpleFarm/SimpleFarm.i18n.php
___________________________________________________________________
Added: svn:eol-style
129 + native
Index: trunk/extensions/SimpleFarm/SimpleFarm.php
@@ -0,0 +1,78 @@
 2+<?php
 3+/**
 4+ * A simple farm extension which allows to direct different urls to different wikis which
 5+ * are all using the same MediaWiki base installation and LocalSettings.php
 6+ * Also comes with a useful maintenance script allowing to maintain several farm members
 7+ * with just one command-line command.
 8+ *
 9+ * Documentation: http://www.mediawiki.org/wiki/Extension:Simple_Farm
 10+ * Support: http://www.mediawiki.org/wiki/Extension_talk:Simple_Farm
 11+ * Source code: http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/SubpageFun
 12+ *
 13+ * @version: 0.1rc
 14+ * @license: ISC license
 15+ * @author: Daniel Werner < danweetz@web.de >
 16+ *
 17+ * @file SimpleFarm.php
 18+ * @ingroup SimpleFarm
 19+ */
 20+
 21+$wgExtensionCredits['other'][] = array(
 22+ 'path' => __FILE__,
 23+ 'name' => 'Simple Farm',
 24+ 'descriptionmsg' => 'simplefarm-desc',
 25+ 'version' => ExtSimpleFarm::VERSION,
 26+ 'author' => '[http://www.mediawiki.org/wiki/User:Danwe Daniel Werner]',
 27+ 'url' => 'http://www.mediawiki.org/wiki/Extension:SimpleFarm',
 28+);
 29+
 30+// language file for extension description:
 31+$wgExtensionMessagesFiles['SimpleFarm'] = ExtSimpleFarm::getDir() . '/SimpleFarm.i18n.php';
 32+/*
 33+ * We don't use $wgExtensionMessagesFiles for more messages since most of this extension happens during
 34+ * localsettings.php , so we can't even be sure the global wiki functions we need for it are available
 35+ * already... This means we output error messages if no wiki farm member was found in English always!
 36+ */
 37+
 38+// load default settings:
 39+require ExtSimpleFarm::getDir() . '/SimpleFarm_Settings.php';
 40+
 41+// include required classes (not in this file because of maintenance script implications):
 42+require_once ExtSimpleFarm::getDir() . '/SimpleFarm_Classes.php';
 43+
 44+/*
 45+ * It's no good, at that stage it is too late to set some global variables like $wgScriptPath
 46+ * because some others depend on it and being set at the beginning of setup.php after default
 47+ * settings and LocalSettings are loaded.
 48+ * That's also why we can't rely on global functions including hook an message system!
 49+ */
 50+// make sure to initialise farm if not manually in 'LocalSettings.php':
 51+// $wgHooks['ParserFirstCallInit'][] = 'SimpleFarm::init';
 52+
 53+/**
 54+ * 'Ext...' class representing the 'Simple Farm' extension.
 55+ */
 56+class ExtSimpleFarm {
 57+
 58+ /**
 59+ * Version of the 'Simple Farm' extension.
 60+ *
 61+ * @since 0.1
 62+ */
 63+ const VERSION = '0.1rc';
 64+
 65+ /**
 66+ * Returns the extensions base installation directory.
 67+ *
 68+ * @since 0.1
 69+ *
 70+ * @return boolean
 71+ */
 72+ public static function getDir() {
 73+ static $dir = null;
 74+ if( $dir === null ) {
 75+ $dir = dirname( __FILE__ );
 76+ }
 77+ return $dir;
 78+ }
 79+}
\ No newline at end of file
Property changes on: trunk/extensions/SimpleFarm/SimpleFarm.php
___________________________________________________________________
Added: svn:eol-style
180 + native
Index: trunk/extensions/SimpleFarm/SimpleFarm_Settings.php
@@ -0,0 +1,95 @@
 2+<?php
 3+/**
 4+ * File defining the settings for the 'Simple Farm' extension.
 5+ * More info can be found at http://www.mediawiki.org/wiki/Extension:Simple_Farm#Configuration
 6+ *
 7+ * NOTICE:
 8+ * =======
 9+ * Changing one of these settings can be done by copying and placing
 10+ * it in LocalSettings.php, AFTER the inclusion of 'Simple Farm'.
 11+ *
 12+ * @file SimpleFarm_Settings.php
 13+ * @ingroup SimpleFarm
 14+ * @since 0.1
 15+ *
 16+ * @author Daniel Werner < danweetz@web.de >
 17+ */
 18+
 19+/**
 20+ * Config var to define members of the wiki farm. The following associative Array keys are obligatory:
 21+ * db - String database name
 22+ * name - String Wiki name, for $wgSitename
 23+ * AND:
 24+ * (
 25+ * addresses - String|String[] one or more server names associated with the wiki. Can be used for
 26+ * sub-domain based farm members like 'farm1.mw.org', 'farm2.mw.org'... , 'farmX.mw.org'
 27+ * If this method is chosen, $wgScriptPath must be set in 'LocalSettings.php'.
 28+ * Even if this method is not chosen, this should contain one address anyway.
 29+ * AND/OR:
 30+ * scriptpath - String (Virtual) script path to the particular wiki directory. Can be used for mod-rewrite
 31+ * based wiki farm setup. This will set the $wgScriptPath variable. There should be a
 32+ * '.htaccess' file in the parent directory of the farm to redirect all paths to the farm
 33+ * directory. Example: 'mw.org/farm1', 'mw.org/farm2'... , 'mw.org/farmX', for the first
 34+ * one the value would be '/farm1', for the second '/farm2' and so on.
 35+ * )
 36+ *
 37+ * The following keys are optional:
 38+ * maintain - Flag whether or not wiki is in maintaining mode right now (optional)
 39+ * The following flags are allowed:
 40+ * - SimpleFarm::MAINTAIN_OFF / false
 41+ * - SimpleFarm::MAINTAIN_SIMPLE
 42+ * - SimpleFarm::MAINTAIN_STRICT
 43+ * - SimpleFarm::MAINTAIN_TOTAL
 44+ *
 45+ * Furthermore, it is possible to add custom keys with additional information for each farm member. These information
 46+ * can be accessed later via $simpleFarmMember->getCfgOption() or $simpleFarmMember() (object-function only in PHP 5.3+)
 47+ *
 48+ * @var Array[]
 49+ */
 50+$egSimpleFarmMembers = array();
 51+
 52+/**
 53+ * Config var database of one of $wgSimpleFarmMembers wikis.
 54+ * If null, it will be set when SimpleFarm::init() was called. The default value is the first key
 55+ * of $wgSimpleFarmMembers then.
 56+ * This main member is important for maintenance since the generic maintenance script will connect
 57+ * to the main member first to have full basic MediaWiki maintenance support.
 58+ *
 59+ * @var String
 60+ */
 61+$egSimpleFarmMainMemberDB = null;
 62+
 63+/**
 64+ * allowed sub-domain prefixes that should be ignored when set in front of the
 65+ * allowed addresses per farm member.
 66+ *
 67+ * @var String[]
 68+ */
 69+$egSimpleFarmIgnoredDomainPrefixes = array( 'www' );
 70+
 71+/**
 72+ * Name of the environment variable used to select a wiki via command-line access.
 73+ * The value will be put into constant 'SIMPLEFARM_ENVVAR' before final initialisation.
 74+ *
 75+ * @var Strings
 76+ */
 77+$egSimpleFarmWikiSelectEnvVarName = 'WIKI';
 78+
 79+/**
 80+ * Callback to call a specific function in case no wiki has been found from the requested
 81+ * address (not in case of command-line acces though!).
 82+ * If the return value of this function is of type SimpleFarmMember, this wiki will be loaded.
 83+ * Otherwise the default message will be shown.
 84+ * Possible value to load the default wiki if no wiki was found would be the callback
 85+ * string 'SimpleFarm::getMainMember'.
 86+ *
 87+ * @var Callback
 88+ */
 89+$egSimpleFarmErrorNoMemberFoundCallback = null;
 90+
 91+/**
 92+ * @ToDo: More hook-like callback functions, perhaps collected into array $wgSimpleFarmCallbacks
 93+ * since we can't use MW hook system which is not loaded when farm is being initialized
 94+ * during localsettings.
 95+ * Example: $wgSimpleFarmCallbacks['NoMemberFound']
 96+ */
\ No newline at end of file
Property changes on: trunk/extensions/SimpleFarm/SimpleFarm_Settings.php
___________________________________________________________________
Added: svn:eol-style
197 + native
Index: trunk/extensions/SimpleFarm/RELEASE-NOTES
@@ -0,0 +1,7 @@
 2+ Changelog:
 3+ ==========
 4+ * (trunk) -- Version 0.1 (initial release)
 5+ - Automatic forwarding to one of several farm member wikis which are all using
 6+ the same physical MediaWiki installation.
 7+ - Maintenance script allowing to maintain several wikis at the same time.
 8+ - Object oriented classes, representing the farm itself as well as its members.
\ No newline at end of file
Property changes on: trunk/extensions/SimpleFarm/RELEASE-NOTES
___________________________________________________________________
Added: svn:eol-style
19 + native
Index: trunk/extensions/SimpleFarm/COPYING
@@ -0,0 +1,13 @@
 2+Copyright (c) 2011 by Daniel Werner < danweetz@web.de >
 3+
 4+Permission to use, copy, modify, and/or distribute this software for any
 5+purpose with or without fee is hereby granted, provided that the above
 6+copyright notice and this permission notice appear in all copies.
 7+
 8+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 9+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
Property changes on: trunk/extensions/SimpleFarm/COPYING
___________________________________________________________________
Added: svn:eol-style
115 + native
Index: trunk/extensions/SimpleFarm/README
@@ -0,0 +1,37 @@
 2+== About ==
 3+
 4+'Simple Farm' is a simple MediaWiki farm extension by Daniel Werner. It
 5+automatically forwards to the wiki that should be accessed by either a
 6+virtual script path (using a tiny bit of mod-rewrite) or by using sub-domains.
 7+It is also possible to have members of the same farm using either of these
 8+methods, not all members have to use the same.
 9+Furthermore, 'Simple Farm' comes with a maintenance script which allows to
 10+maintain several farm members at the same time, e.g. doing database update
 11+for all or certain farm members by executing just one command.
 12+
 13+* Website: http://www.mediawiki.org/wiki/Extension:Simple_Farm
 14+* License: ISC license
 15+* Author: Daniel Werner < danweetz@web.de >
 16+
 17+
 18+== Installation ==
 19+
 20+Once you have downloaded the code, place the 'SimpleFarm' directory within your
 21+MediaWiki 'extensions' directory. Then add the following code to your
 22+[[Manual:LocalSettings.php|LocalSettings.php]] file:
 23+
 24+ # Simple Farm
 25+ require_once( "$IP/extensions/SimpleFarm/SimpleFarm.php" );
 26+ /* ... SimpleFarm configuration ... */
 27+ SimpleFarm::init();
 28+ /* ... chosen member settings ... */
 29+
 30+Please see http://www.mediawiki.org/wiki/Extension:Simple_Farm#Configuration for details.
 31+
 32+
 33+== Contributing ==
 34+
 35+If you have bug reports or requests, please add them to the 'Simple Farm' Talk page [0].
 36+You can also send them to Daniel Werner < danweetz@web.de >
 37+
 38+[0] http://www.mediawiki.org/w/index.php?title=Extension_talk:Simple_Farm
Property changes on: trunk/extensions/SimpleFarm/README
___________________________________________________________________
Added: svn:eol-style
139 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r105175r103982: Consistency tweaks in preparation for adding extension to translatew...raymond14:05, 5 December 2011
r105176r103982: Adding extension to translatewiki.netraymond14:06, 5 December 2011
r105179r103982: fix typorobin14:28, 5 December 2011

Status & tagging log