r51723 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r51722‎ | r51723 | r51724 >
Date:02:31, 11 June 2009
Author:demon
Status:deferred
Tags:
Comment:
eol-style
Modified paths:
  • /branches/maintenance-work/docs/maintenance.txt (modified) (history)
  • /branches/maintenance-work/maintenance/Maintenance.php (modified) (history)
  • /branches/maintenance-work/maintenance/doMaintenance.php (modified) (history)

Diff [purge]

Index: branches/maintenance-work/maintenance/doMaintenance.php
@@ -1,47 +1,47 @@
2 -<?php
3 -/**
4 - * We want to make this whole thing as seamless as possible to the
5 - * end-user. Unfortunately, we can't do _all_ of the work in the class
6 - * because A) included files are not in global scope, but in the scope
7 - * of their caller, and B) MediaWiki has way too many globals. So instead
8 - * we'll kinda fake it, and do the requires() inline. <3 PHP
9 - */
10 -
11 -// Get an object to start us off
12 -$maintenance = new $maintClass();
13 -
14 -// Basic sanity checks and such
15 -$maintenance->setup();
16 -
17 -# Setup the profiler
18 -if ( file_exists( "$IP/StartProfiler.php" ) ) {
19 - require_once( "$IP/StartProfiler.php" );
20 -} else {
21 - require_once( "$IP/includes/ProfilerStub.php" );
22 -}
23 -
24 -// Load settings, using wikimedia-mode if needed
25 -if( file_exists( dirname(__FILE__).'/wikimedia-mode' ) ) {
26 - # TODO FIXME! Wikimedia-specific stuff needs to go away to an ext
27 - # Maybe a hook?
28 - global $cluster;
29 - $wgWikiFarm = true;
30 - $cluster = 'pmtma';
31 - require_once( "$IP/includes/AutoLoader.php" );
32 - require_once( "$IP/includes/SiteConfiguration.php" );
33 - require( "$IP/wgConf.php" );
34 - $maintenance->loadWikimediaSettings();
35 - require( $IP.'/includes/Defines.php' );
36 - require( $IP.'/CommonSettings.php' );
37 -} else {
38 - require_once( "$IP/includes/AutoLoader.php" );
39 - require_once( "$IP/includes/Defines.php" );
40 - require_once( $maintenance->loadSettings() );
41 -}
42 -// Some last includes
43 -require_once( "$IP/includes/Setup.php" );
44 -require_once( "$IP/install-utils.inc" );
45 -
46 -$wgTitle = null; # Much much faster startup than creating a title object
47 -
48 -$maintenance->execute();
 2+<?php
 3+/**
 4+ * We want to make this whole thing as seamless as possible to the
 5+ * end-user. Unfortunately, we can't do _all_ of the work in the class
 6+ * because A) included files are not in global scope, but in the scope
 7+ * of their caller, and B) MediaWiki has way too many globals. So instead
 8+ * we'll kinda fake it, and do the requires() inline. <3 PHP
 9+ */
 10+
 11+// Get an object to start us off
 12+$maintenance = new $maintClass();
 13+
 14+// Basic sanity checks and such
 15+$maintenance->setup();
 16+
 17+# Setup the profiler
 18+if ( file_exists( "$IP/StartProfiler.php" ) ) {
 19+ require_once( "$IP/StartProfiler.php" );
 20+} else {
 21+ require_once( "$IP/includes/ProfilerStub.php" );
 22+}
 23+
 24+// Load settings, using wikimedia-mode if needed
 25+if( file_exists( dirname(__FILE__).'/wikimedia-mode' ) ) {
 26+ # TODO FIXME! Wikimedia-specific stuff needs to go away to an ext
 27+ # Maybe a hook?
 28+ global $cluster;
 29+ $wgWikiFarm = true;
 30+ $cluster = 'pmtma';
 31+ require_once( "$IP/includes/AutoLoader.php" );
 32+ require_once( "$IP/includes/SiteConfiguration.php" );
 33+ require( "$IP/wgConf.php" );
 34+ $maintenance->loadWikimediaSettings();
 35+ require( $IP.'/includes/Defines.php' );
 36+ require( $IP.'/CommonSettings.php' );
 37+} else {
 38+ require_once( "$IP/includes/AutoLoader.php" );
 39+ require_once( "$IP/includes/Defines.php" );
 40+ require_once( $maintenance->loadSettings() );
 41+}
 42+// Some last includes
 43+require_once( "$IP/includes/Setup.php" );
 44+require_once( "$IP/install-utils.inc" );
 45+
 46+$wgTitle = null; # Much much faster startup than creating a title object
 47+
 48+$maintenance->execute();
Property changes on: branches/maintenance-work/maintenance/doMaintenance.php
___________________________________________________________________
Name: svn:eol-style
4949 + native
Index: branches/maintenance-work/maintenance/Maintenance.php
@@ -1,410 +1,410 @@
2 -<?php
3 -
4 -/**
5 - * Abstract maintenance class for quickly writing and churning out
6 - * maintenance scripts with minimal effort. All that _must_ be defined
7 - * is the execute() method. See docs/maintenance.txt for more info
8 - * and a quick demo of how to use it.
9 - *
10 - * @author Chad Horohoe <chad@anyonecanedit.org>
11 - * @since 1.16
12 - * @ingroup Maintenance
13 - */
14 -abstract class Maintenance {
15 -
16 - // This is the desired params
17 - protected $mParams = array();
18 -
19 - // This is the list of options that were actually passed
20 - protected $mOptions = array();
21 -
22 - // This is the list of arguments that were actually passed
23 - protected $mArgs = array();
24 -
25 - // Name of the script currently running
26 - protected $mSelf;
27 -
28 - // Special vars for params that are always used
29 - private $mQuiet = false;
30 - private $mDbUser, $mDbPass;
31 -
32 - // A description of the script, children should change this
33 - protected $mDescription = '';
34 -
35 - /**
36 - * Default constructor. Children should call this if implementing
37 - * their own constructors
38 - */
39 - public function __construct() {
40 - $this->addDefaultParams();
41 - }
42 -
43 - /**
44 - * Do the actual work. All child classes will need to implement this
45 - */
46 - abstract protected function execute();
47 -
48 - /**
49 - * Add a parameter to the script. Will be displayed on --help
50 - * with the associated description
51 - *
52 - * @param $name String The name of the param (help, version, etc)
53 - * @param $description String The description of the param to show on --help
54 - * @param $required boolean Is the param required?
55 - */
56 - protected function addParam( $name, $description, $required = false ) {
57 - $this->mParams[ $name ] = array( 'desc' => $description, 'require' => $required );
58 - }
59 -
60 - /**
61 - * Return input from stdin.
62 - * @param $length int The number of bytes to read
63 - * @return mixed
64 - */
65 - protected function getStdin( $len = 255 ) {
66 - $f = fopen( 'php://stdin', 'r' );
67 - $input = fgets( $fr, $len );
68 - fclose ( $fr );
69 - return rtrim( $input );
70 - }
71 -
72 - /**
73 - * Throw some output to the user. Scripts can call this with no fears,
74 - * as we handle all --quiet stuff here
75 - * @param $out String The text to show to the user
76 - */
77 - protected function output( $out ) {
78 - if( $this->mQuiet ) {
79 - return;
80 - }
81 - $f = fopen( 'php://stdout', 'w' );
82 - fwrite( $f, $out );
83 - fclose( $f );
84 - }
85 -
86 - /**
87 - * Throw an error to the user. Doesn't respect --quiet, so don't use
88 - * this for non-error output
89 - * @param $err String The error to display
90 - * @param $die boolean If true, go ahead and die out.
91 - */
92 - protected function error( $err, $die = false ) {
93 - $f = fopen( 'php://stderr', 'w' );
94 - fwrite( $f, $err );
95 - fclose( $f );
96 - if( $die ) die();
97 - }
98 -
99 - /**
100 - * Does the script need DB access? Override this and return true,
101 - * if needed
102 - * @return boolean
103 - */
104 - protected function needsDB() {
105 - return false;
106 - }
107 -
108 - /**
109 - * Add the default parameters to the scripts
110 - */
111 - private function addDefaultParams() {
112 - $this->addParam( 'help', "Display this help message" );
113 - $this->addParam( 'quiet', "Whether to supress non-error output" );
114 - $this->addParam( 'conf', "Location of LocalSettings.php, if not default" );
115 - $this->addParam( 'wiki', "For specifying the wiki ID" );
116 - if( $this->needsDB() ) {
117 - $this->addParam( 'dbuser', "The DB user to use for this script" );
118 - $this->addParam( 'dbpass', "The password to use for this script" );
119 - }
120 - }
121 -
122 - /**
123 - * Do some sanity checking
124 - */
125 - public function setup() {
126 - global $IP, $wgCommandLineMode, $wgUseNormalUser, $wgRequestTime;
127 -
128 - # Abort if called from a web server
129 - if ( isset( $_SERVER ) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
130 - $this->error( "This script must be run from the command line\n", true );
131 - }
132 -
133 - # Make sure we can handle script parameters
134 - if( !ini_get( 'register_argc_argv' ) ) {
135 - $this->error( "Cannot get command line arguments, register_argc_argv is set to false", true );
136 - }
137 -
138 - # Make sure we're on PHP5 or better
139 - if( version_compare( PHP_VERSION, '5.0.0' ) < 0 ) {
140 - $this->error( "Sorry! This version of MediaWiki requires PHP 5; you are running " .
141 - PHP_VERSION . ".\n\n" .
142 - "If you are sure you already have PHP 5 installed, it may be installed\n" .
143 - "in a different path from PHP 4. Check with your system administrator.\n", true );
144 - }
145 -
146 - if( version_compare( phpversion(), '5.2.4' ) >= 0 ) {
147 - // Send PHP warnings and errors to stderr instead of stdout.
148 - // This aids in diagnosing problems, while keeping messages
149 - // out of redirected output.
150 - if( ini_get( 'display_errors' ) ) {
151 - ini_set( 'display_errors', 'stderr' );
152 - }
153 -
154 - // Don't touch the setting on earlier versions of PHP,
155 - // as setting it would disable output if you'd wanted it.
156 -
157 - // Note that exceptions are also sent to stderr when
158 - // command-line mode is on, regardless of PHP version.
159 - }
160 -
161 - # Set the memory limit
162 - ini_set( 'memory_limit', -1 );
163 -
164 - $wgRequestTime = microtime(true);
165 -
166 - # Define us as being in Mediawiki
167 - define( 'MEDIAWIKI', true );
168 -
169 - # Setup $IP, using MW_INSTALL_PATH if it exists
170 - $IP = strval( getenv('MW_INSTALL_PATH') ) !== ''
171 - ? getenv('MW_INSTALL_PATH')
172 - : realpath( dirname( __FILE__ ) . '/..' );
173 -
174 - $wgCommandLineMode = true;
175 - # Turn off output buffering if it's on
176 - @ob_end_flush();
177 -
178 - if (!isset( $wgUseNormalUser ) ) {
179 - $wgUseNormalUser = false;
180 - }
181 -
182 - $this->loadArgs();
183 - $this->maybeHelp();
184 - }
185 -
186 - /**
187 - * Process command line arguments
188 - * $mOptions becomes an array with keys set to the option names
189 - * $mArgs becomes a zero-based array containing the non-option arguments
190 - */
191 - private function loadArgs() {
192 - global $argv;
193 - $this->mSelf = array_shift( $argv );
194 -
195 - $options = array();
196 - $args = array();
197 -
198 - # Parse arguments
199 - for( $arg = reset( $argv ); $arg !== false; $arg = next( $argv ) ) {
200 - if ( $arg == '--' ) {
201 - # End of options, remainder should be considered arguments
202 - $arg = next( $argv );
203 - while( $arg !== false ) {
204 - $args[] = $arg;
205 - $arg = next( $argv );
206 - }
207 - break;
208 - } elseif ( substr( $arg, 0, 2 ) == '--' ) {
209 - # Long options
210 - $option = substr( $arg, 2 );
211 - if ( isset( $this->mParams[$option] ) ) {
212 - $param = next( $argv );
213 - if ( $param === false ) {
214 - $this->error( "$arg needs a value after it\n", true );
215 - }
216 - $options[$option] = $param;
217 - } else {
218 - $bits = explode( '=', $option, 2 );
219 - if( count( $bits ) > 1 ) {
220 - $option = $bits[0];
221 - $param = $bits[1];
222 - } else {
223 - $param = 1;
224 - }
225 - $options[$option] = $param;
226 - }
227 - } elseif ( substr( $arg, 0, 1 ) == '-' ) {
228 - # Short options
229 - for ( $p=1; $p<strlen( $arg ); $p++ ) {
230 - $option = $arg{$p};
231 - if ( isset( $this->mParams[$option] ) ) {
232 - $param = next( $argv );
233 - if ( $param === false ) {
234 - $this->error( "$arg needs a value after it\n", true );
235 - }
236 - $options[$option] = $param;
237 - } else {
238 - $options[$option] = 1;
239 - }
240 - }
241 - } else {
242 - $args[] = $arg;
243 - }
244 - }
245 -
246 - # These vars get special treatment
247 - if( isset( $options['dbuser'] ) )
248 - $this->mDbUser = $options['dbuser'];
249 - if( isset( $options['dbpass'] ) )
250 - $this->mDbPass = $options['dbpass'];
251 - if( isset( $options['quiet'] ) )
252 - $this->mQuiet = true;
253 -
254 - # Check to make sure we've got all the required ones
255 - foreach( $this->mParams as $opt => $info ) {
256 - if( $info['required'] && !isset( $this->mOptions[$opt] ) ) {
257 - $this->error( "Param $opt required.\n", true );
258 - }
259 - }
260 -
261 - $this->mOptions = $options;
262 - $this->mArgs = $args;
263 - }
264 -
265 - /**
266 - * Maybe show the help.
267 - */
268 - private function maybeHelp() {
269 - if( isset( $this->mOptions['help'] ) ) {
270 - $this->mQuiet = false;
271 - if( $this->mDescription ) {
272 - $this->output( $this->mDescription . "\n" );
273 - }
274 - $this->output( "\nUsage: php " . $this->mSelf . " [--" .
275 - implode( array_keys( $this->mParams ), "|--" ) . "]\n" );
276 - foreach( $params as $par => $desc ) {
277 - $this->output( "\t$par : $desc\n" );
278 - }
279 - }
280 - }
281 -
282 - /**
283 - * Handle some last-minute setup here.
284 - */
285 - private function finalSetup() {
286 - global $wgCommandLineMode, $wgUseNormalUser, $wgShowSQLErrors;
287 - global $wgTitle, $wgProfiling, $IP, $wgDBadminuser, $wgDBadminpassword;
288 - global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
289 -
290 - # Turn off output buffering again, it might have been turned on in the settings files
291 - if( ob_get_level() ) {
292 - ob_end_flush();
293 - }
294 - # Same with these
295 - $wgCommandLineMode = true;
296 -
297 - # If these were passed, use them
298 - if( $this->mDbUser )
299 - $wgDBadminuser = $this->mDbUser;
300 - if( $this->mDbPass )
301 - $wgDBadminpass = $this->mDbPass;
302 -
303 - if ( empty( $wgUseNormalUser ) && isset( $wgDBadminuser ) ) {
304 - $wgDBuser = $wgDBadminuser;
305 - $wgDBpassword = $wgDBadminpassword;
306 -
307 - if( $wgDBservers ) {
308 - foreach ( $wgDBservers as $i => $server ) {
309 - $wgDBservers[$i]['user'] = $wgDBuser;
310 - $wgDBservers[$i]['password'] = $wgDBpassword;
311 - }
312 - }
313 - if( isset( $wgLBFactoryConf['serverTemplate'] ) ) {
314 - $wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
315 - $wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
316 - }
317 - }
318 -
319 - if ( defined( 'MW_CMDLINE_CALLBACK' ) ) {
320 - $fn = MW_CMDLINE_CALLBACK;
321 - $fn();
322 - }
323 -
324 - $wgShowSQLErrors = true;
325 - @set_time_limit(0);
326 -
327 - $wgProfiling = false; // only for Profiler.php mode; avoids OOM errors
328 - }
329 -
330 - /**
331 - * Do setup specific to WMF
332 - */
333 - public function loadWikimediaSettings() {
334 - global $IP, $wgNoDBParam, $wgUseNormalUser, $wgConf;
335 -
336 - if ( empty( $wgNoDBParam ) ) {
337 - # Check if we were passed a db name
338 - if ( isset( $this->mOptions['wiki'] ) ) {
339 - $db = $this->mOptions['wiki'];
340 - } else {
341 - $db = array_shift( $this->mArgs );
342 - }
343 - list( $site, $lang ) = $wgConf->siteFromDB( $db );
344 -
345 - # If not, work out the language and site the old way
346 - if ( is_null( $site ) || is_null( $lang ) ) {
347 - if ( !$db ) {
348 - $lang = 'aa';
349 - } else {
350 - $lang = $db;
351 - }
352 - if ( isset( $this->mArgs[0] ) ) {
353 - $site = array_shift( $this->mArgs );
354 - } else {
355 - $site = 'wikipedia';
356 - }
357 - }
358 - } else {
359 - $lang = 'aa';
360 - $site = 'wikipedia';
361 - }
362 -
363 - # This is for the IRC scripts, which now run as the apache user
364 - # The apache user doesn't have access to the wikiadmin_pass command
365 - if ( $_ENV['USER'] == 'apache' ) {
366 - #if ( posix_geteuid() == 48 ) {
367 - $wgUseNormalUser = true;
368 - }
369 -
370 - putenv( 'wikilang='.$lang);
371 -
372 - $DP = $IP;
373 - ini_set( 'include_path', ".:$IP:$IP/includes:$IP/languages:$IP/maintenance" );
374 -
375 - if ( $lang == 'test' && $site == 'wikipedia' ) {
376 - define( 'TESTWIKI', 1 );
377 - }
378 - }
379 -
380 - /**
381 - * Generic setup for most installs. Returns the location of LocalSettings
382 - * @return String
383 - */
384 - public function loadSettings() {
385 - global $wgWikiFarm, $wgCommandLineMode, $IP, $DP;
386 -
387 - $wgWikiFarm = false;
388 - if ( isset( $this->mOptions['conf'] ) ) {
389 - $settingsFile = $this->mOptions['conf'];
390 - } else {
391 - $settingsFile = "$IP/LocalSettings.php";
392 - }
393 - if ( isset( $this->mOptions['wiki'] ) ) {
394 - $bits = explode( '-', $this->mOptions['wiki'] );
395 - if ( count( $bits ) == 1 ) {
396 - $bits[] = '';
397 - }
398 - define( 'MW_DB', $bits[0] );
399 - define( 'MW_PREFIX', $bits[1] );
400 - }
401 -
402 - if ( ! is_readable( $settingsFile ) ) {
403 - $this->error( "A copy of your installation's LocalSettings.php\n" .
404 - "must exist and be readable in the source directory.\n", true );
405 - }
406 - $wgCommandLineMode = true;
407 - $DP = $IP;
408 - $this->finalSetup();
409 - return $settingsFile;
410 - }
 2+<?php
 3+
 4+/**
 5+ * Abstract maintenance class for quickly writing and churning out
 6+ * maintenance scripts with minimal effort. All that _must_ be defined
 7+ * is the execute() method. See docs/maintenance.txt for more info
 8+ * and a quick demo of how to use it.
 9+ *
 10+ * @author Chad Horohoe <chad@anyonecanedit.org>
 11+ * @since 1.16
 12+ * @ingroup Maintenance
 13+ */
 14+abstract class Maintenance {
 15+
 16+ // This is the desired params
 17+ protected $mParams = array();
 18+
 19+ // This is the list of options that were actually passed
 20+ protected $mOptions = array();
 21+
 22+ // This is the list of arguments that were actually passed
 23+ protected $mArgs = array();
 24+
 25+ // Name of the script currently running
 26+ protected $mSelf;
 27+
 28+ // Special vars for params that are always used
 29+ private $mQuiet = false;
 30+ private $mDbUser, $mDbPass;
 31+
 32+ // A description of the script, children should change this
 33+ protected $mDescription = '';
 34+
 35+ /**
 36+ * Default constructor. Children should call this if implementing
 37+ * their own constructors
 38+ */
 39+ public function __construct() {
 40+ $this->addDefaultParams();
 41+ }
 42+
 43+ /**
 44+ * Do the actual work. All child classes will need to implement this
 45+ */
 46+ abstract protected function execute();
 47+
 48+ /**
 49+ * Add a parameter to the script. Will be displayed on --help
 50+ * with the associated description
 51+ *
 52+ * @param $name String The name of the param (help, version, etc)
 53+ * @param $description String The description of the param to show on --help
 54+ * @param $required boolean Is the param required?
 55+ */
 56+ protected function addParam( $name, $description, $required = false ) {
 57+ $this->mParams[ $name ] = array( 'desc' => $description, 'require' => $required );
 58+ }
 59+
 60+ /**
 61+ * Return input from stdin.
 62+ * @param $length int The number of bytes to read
 63+ * @return mixed
 64+ */
 65+ protected function getStdin( $len = 255 ) {
 66+ $f = fopen( 'php://stdin', 'r' );
 67+ $input = fgets( $fr, $len );
 68+ fclose ( $fr );
 69+ return rtrim( $input );
 70+ }
 71+
 72+ /**
 73+ * Throw some output to the user. Scripts can call this with no fears,
 74+ * as we handle all --quiet stuff here
 75+ * @param $out String The text to show to the user
 76+ */
 77+ protected function output( $out ) {
 78+ if( $this->mQuiet ) {
 79+ return;
 80+ }
 81+ $f = fopen( 'php://stdout', 'w' );
 82+ fwrite( $f, $out );
 83+ fclose( $f );
 84+ }
 85+
 86+ /**
 87+ * Throw an error to the user. Doesn't respect --quiet, so don't use
 88+ * this for non-error output
 89+ * @param $err String The error to display
 90+ * @param $die boolean If true, go ahead and die out.
 91+ */
 92+ protected function error( $err, $die = false ) {
 93+ $f = fopen( 'php://stderr', 'w' );
 94+ fwrite( $f, $err );
 95+ fclose( $f );
 96+ if( $die ) die();
 97+ }
 98+
 99+ /**
 100+ * Does the script need DB access? Override this and return true,
 101+ * if needed
 102+ * @return boolean
 103+ */
 104+ protected function needsDB() {
 105+ return false;
 106+ }
 107+
 108+ /**
 109+ * Add the default parameters to the scripts
 110+ */
 111+ private function addDefaultParams() {
 112+ $this->addParam( 'help', "Display this help message" );
 113+ $this->addParam( 'quiet', "Whether to supress non-error output" );
 114+ $this->addParam( 'conf', "Location of LocalSettings.php, if not default" );
 115+ $this->addParam( 'wiki', "For specifying the wiki ID" );
 116+ if( $this->needsDB() ) {
 117+ $this->addParam( 'dbuser', "The DB user to use for this script" );
 118+ $this->addParam( 'dbpass', "The password to use for this script" );
 119+ }
 120+ }
 121+
 122+ /**
 123+ * Do some sanity checking
 124+ */
 125+ public function setup() {
 126+ global $IP, $wgCommandLineMode, $wgUseNormalUser, $wgRequestTime;
 127+
 128+ # Abort if called from a web server
 129+ if ( isset( $_SERVER ) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
 130+ $this->error( "This script must be run from the command line\n", true );
 131+ }
 132+
 133+ # Make sure we can handle script parameters
 134+ if( !ini_get( 'register_argc_argv' ) ) {
 135+ $this->error( "Cannot get command line arguments, register_argc_argv is set to false", true );
 136+ }
 137+
 138+ # Make sure we're on PHP5 or better
 139+ if( version_compare( PHP_VERSION, '5.0.0' ) < 0 ) {
 140+ $this->error( "Sorry! This version of MediaWiki requires PHP 5; you are running " .
 141+ PHP_VERSION . ".\n\n" .
 142+ "If you are sure you already have PHP 5 installed, it may be installed\n" .
 143+ "in a different path from PHP 4. Check with your system administrator.\n", true );
 144+ }
 145+
 146+ if( version_compare( phpversion(), '5.2.4' ) >= 0 ) {
 147+ // Send PHP warnings and errors to stderr instead of stdout.
 148+ // This aids in diagnosing problems, while keeping messages
 149+ // out of redirected output.
 150+ if( ini_get( 'display_errors' ) ) {
 151+ ini_set( 'display_errors', 'stderr' );
 152+ }
 153+
 154+ // Don't touch the setting on earlier versions of PHP,
 155+ // as setting it would disable output if you'd wanted it.
 156+
 157+ // Note that exceptions are also sent to stderr when
 158+ // command-line mode is on, regardless of PHP version.
 159+ }
 160+
 161+ # Set the memory limit
 162+ ini_set( 'memory_limit', -1 );
 163+
 164+ $wgRequestTime = microtime(true);
 165+
 166+ # Define us as being in Mediawiki
 167+ define( 'MEDIAWIKI', true );
 168+
 169+ # Setup $IP, using MW_INSTALL_PATH if it exists
 170+ $IP = strval( getenv('MW_INSTALL_PATH') ) !== ''
 171+ ? getenv('MW_INSTALL_PATH')
 172+ : realpath( dirname( __FILE__ ) . '/..' );
 173+
 174+ $wgCommandLineMode = true;
 175+ # Turn off output buffering if it's on
 176+ @ob_end_flush();
 177+
 178+ if (!isset( $wgUseNormalUser ) ) {
 179+ $wgUseNormalUser = false;
 180+ }
 181+
 182+ $this->loadArgs();
 183+ $this->maybeHelp();
 184+ }
 185+
 186+ /**
 187+ * Process command line arguments
 188+ * $mOptions becomes an array with keys set to the option names
 189+ * $mArgs becomes a zero-based array containing the non-option arguments
 190+ */
 191+ private function loadArgs() {
 192+ global $argv;
 193+ $this->mSelf = array_shift( $argv );
 194+
 195+ $options = array();
 196+ $args = array();
 197+
 198+ # Parse arguments
 199+ for( $arg = reset( $argv ); $arg !== false; $arg = next( $argv ) ) {
 200+ if ( $arg == '--' ) {
 201+ # End of options, remainder should be considered arguments
 202+ $arg = next( $argv );
 203+ while( $arg !== false ) {
 204+ $args[] = $arg;
 205+ $arg = next( $argv );
 206+ }
 207+ break;
 208+ } elseif ( substr( $arg, 0, 2 ) == '--' ) {
 209+ # Long options
 210+ $option = substr( $arg, 2 );
 211+ if ( isset( $this->mParams[$option] ) ) {
 212+ $param = next( $argv );
 213+ if ( $param === false ) {
 214+ $this->error( "$arg needs a value after it\n", true );
 215+ }
 216+ $options[$option] = $param;
 217+ } else {
 218+ $bits = explode( '=', $option, 2 );
 219+ if( count( $bits ) > 1 ) {
 220+ $option = $bits[0];
 221+ $param = $bits[1];
 222+ } else {
 223+ $param = 1;
 224+ }
 225+ $options[$option] = $param;
 226+ }
 227+ } elseif ( substr( $arg, 0, 1 ) == '-' ) {
 228+ # Short options
 229+ for ( $p=1; $p<strlen( $arg ); $p++ ) {
 230+ $option = $arg{$p};
 231+ if ( isset( $this->mParams[$option] ) ) {
 232+ $param = next( $argv );
 233+ if ( $param === false ) {
 234+ $this->error( "$arg needs a value after it\n", true );
 235+ }
 236+ $options[$option] = $param;
 237+ } else {
 238+ $options[$option] = 1;
 239+ }
 240+ }
 241+ } else {
 242+ $args[] = $arg;
 243+ }
 244+ }
 245+
 246+ # These vars get special treatment
 247+ if( isset( $options['dbuser'] ) )
 248+ $this->mDbUser = $options['dbuser'];
 249+ if( isset( $options['dbpass'] ) )
 250+ $this->mDbPass = $options['dbpass'];
 251+ if( isset( $options['quiet'] ) )
 252+ $this->mQuiet = true;
 253+
 254+ # Check to make sure we've got all the required ones
 255+ foreach( $this->mParams as $opt => $info ) {
 256+ if( $info['required'] && !isset( $this->mOptions[$opt] ) ) {
 257+ $this->error( "Param $opt required.\n", true );
 258+ }
 259+ }
 260+
 261+ $this->mOptions = $options;
 262+ $this->mArgs = $args;
 263+ }
 264+
 265+ /**
 266+ * Maybe show the help.
 267+ */
 268+ private function maybeHelp() {
 269+ if( isset( $this->mOptions['help'] ) ) {
 270+ $this->mQuiet = false;
 271+ if( $this->mDescription ) {
 272+ $this->output( $this->mDescription . "\n" );
 273+ }
 274+ $this->output( "\nUsage: php " . $this->mSelf . " [--" .
 275+ implode( array_keys( $this->mParams ), "|--" ) . "]\n" );
 276+ foreach( $params as $par => $desc ) {
 277+ $this->output( "\t$par : $desc\n" );
 278+ }
 279+ }
 280+ }
 281+
 282+ /**
 283+ * Handle some last-minute setup here.
 284+ */
 285+ private function finalSetup() {
 286+ global $wgCommandLineMode, $wgUseNormalUser, $wgShowSQLErrors;
 287+ global $wgTitle, $wgProfiling, $IP, $wgDBadminuser, $wgDBadminpassword;
 288+ global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
 289+
 290+ # Turn off output buffering again, it might have been turned on in the settings files
 291+ if( ob_get_level() ) {
 292+ ob_end_flush();
 293+ }
 294+ # Same with these
 295+ $wgCommandLineMode = true;
 296+
 297+ # If these were passed, use them
 298+ if( $this->mDbUser )
 299+ $wgDBadminuser = $this->mDbUser;
 300+ if( $this->mDbPass )
 301+ $wgDBadminpass = $this->mDbPass;
 302+
 303+ if ( empty( $wgUseNormalUser ) && isset( $wgDBadminuser ) ) {
 304+ $wgDBuser = $wgDBadminuser;
 305+ $wgDBpassword = $wgDBadminpassword;
 306+
 307+ if( $wgDBservers ) {
 308+ foreach ( $wgDBservers as $i => $server ) {
 309+ $wgDBservers[$i]['user'] = $wgDBuser;
 310+ $wgDBservers[$i]['password'] = $wgDBpassword;
 311+ }
 312+ }
 313+ if( isset( $wgLBFactoryConf['serverTemplate'] ) ) {
 314+ $wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
 315+ $wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
 316+ }
 317+ }
 318+
 319+ if ( defined( 'MW_CMDLINE_CALLBACK' ) ) {
 320+ $fn = MW_CMDLINE_CALLBACK;
 321+ $fn();
 322+ }
 323+
 324+ $wgShowSQLErrors = true;
 325+ @set_time_limit(0);
 326+
 327+ $wgProfiling = false; // only for Profiler.php mode; avoids OOM errors
 328+ }
 329+
 330+ /**
 331+ * Do setup specific to WMF
 332+ */
 333+ public function loadWikimediaSettings() {
 334+ global $IP, $wgNoDBParam, $wgUseNormalUser, $wgConf;
 335+
 336+ if ( empty( $wgNoDBParam ) ) {
 337+ # Check if we were passed a db name
 338+ if ( isset( $this->mOptions['wiki'] ) ) {
 339+ $db = $this->mOptions['wiki'];
 340+ } else {
 341+ $db = array_shift( $this->mArgs );
 342+ }
 343+ list( $site, $lang ) = $wgConf->siteFromDB( $db );
 344+
 345+ # If not, work out the language and site the old way
 346+ if ( is_null( $site ) || is_null( $lang ) ) {
 347+ if ( !$db ) {
 348+ $lang = 'aa';
 349+ } else {
 350+ $lang = $db;
 351+ }
 352+ if ( isset( $this->mArgs[0] ) ) {
 353+ $site = array_shift( $this->mArgs );
 354+ } else {
 355+ $site = 'wikipedia';
 356+ }
 357+ }
 358+ } else {
 359+ $lang = 'aa';
 360+ $site = 'wikipedia';
 361+ }
 362+
 363+ # This is for the IRC scripts, which now run as the apache user
 364+ # The apache user doesn't have access to the wikiadmin_pass command
 365+ if ( $_ENV['USER'] == 'apache' ) {
 366+ #if ( posix_geteuid() == 48 ) {
 367+ $wgUseNormalUser = true;
 368+ }
 369+
 370+ putenv( 'wikilang='.$lang);
 371+
 372+ $DP = $IP;
 373+ ini_set( 'include_path', ".:$IP:$IP/includes:$IP/languages:$IP/maintenance" );
 374+
 375+ if ( $lang == 'test' && $site == 'wikipedia' ) {
 376+ define( 'TESTWIKI', 1 );
 377+ }
 378+ }
 379+
 380+ /**
 381+ * Generic setup for most installs. Returns the location of LocalSettings
 382+ * @return String
 383+ */
 384+ public function loadSettings() {
 385+ global $wgWikiFarm, $wgCommandLineMode, $IP, $DP;
 386+
 387+ $wgWikiFarm = false;
 388+ if ( isset( $this->mOptions['conf'] ) ) {
 389+ $settingsFile = $this->mOptions['conf'];
 390+ } else {
 391+ $settingsFile = "$IP/LocalSettings.php";
 392+ }
 393+ if ( isset( $this->mOptions['wiki'] ) ) {
 394+ $bits = explode( '-', $this->mOptions['wiki'] );
 395+ if ( count( $bits ) == 1 ) {
 396+ $bits[] = '';
 397+ }
 398+ define( 'MW_DB', $bits[0] );
 399+ define( 'MW_PREFIX', $bits[1] );
 400+ }
 401+
 402+ if ( ! is_readable( $settingsFile ) ) {
 403+ $this->error( "A copy of your installation's LocalSettings.php\n" .
 404+ "must exist and be readable in the source directory.\n", true );
 405+ }
 406+ $wgCommandLineMode = true;
 407+ $DP = $IP;
 408+ $this->finalSetup();
 409+ return $settingsFile;
 410+ }
411411 }
\ No newline at end of file
Property changes on: branches/maintenance-work/maintenance/Maintenance.php
___________________________________________________________________
Name: svn:eol-style
412412 + native
Index: branches/maintenance-work/docs/maintenance.txt
@@ -1,54 +1,54 @@
2 -Prior to version 1.16, maintenance scripts were a hodgepodge of code that
3 -had no cohesion or formal method of action. Beginning in 1.16, maintenance
4 -scripts have been cleaned up to use a unified class.
5 -
6 -1. Directory structure
7 -2. How to run a script
8 -3. How to write your own
9 -
10 -1. DIRECTORY STRUCTURE
11 - The /maintenance directory of a MediaWiki installation contains several
12 -subdirectories, all of which have unique purposes.
13 -
14 -2. HOW TO RUN A SCRIPT
15 - Ridiculously simple, just call 'php someScript.php' that's in the top-
16 -level /maintenance directory.
17 -
18 -Example:
19 - php clear_stats.php
20 -
21 -The following parameters are available to all maintenance scripts
22 -
23 -3. HOW TO WRITE YOUR OWN
24 -Make a file in the maintenance directory called myScript.php or something.
25 -In it, write the following:
26 -
27 -==BEGIN==
28 -
29 -<?php
30 -
31 -require_once( "Maintenance.php" );
32 -
33 -class DemoMaint extends Maintenance {
34 -
35 - public function __construct() {
36 - parent::__construct();
37 - }
38 -
39 - protected function execute() {
40 - }
41 -}
42 -
43 -$maintClass = "DemoMaint";
44 -require_once( "doMaintenance.php" );
45 -
46 -==END==
47 -
48 -That's it. In the execute() method, you have access to all of the normal
49 -MediaWiki functions, so you can get a DB connection, use the cache, etc.
50 -For full docs on the Maintenance class, see the auto-generated docs at
 2+Prior to version 1.16, maintenance scripts were a hodgepodge of code that
 3+had no cohesion or formal method of action. Beginning in 1.16, maintenance
 4+scripts have been cleaned up to use a unified class.
 5+
 6+1. Directory structure
 7+2. How to run a script
 8+3. How to write your own
 9+
 10+1. DIRECTORY STRUCTURE
 11+ The /maintenance directory of a MediaWiki installation contains several
 12+subdirectories, all of which have unique purposes.
 13+
 14+2. HOW TO RUN A SCRIPT
 15+ Ridiculously simple, just call 'php someScript.php' that's in the top-
 16+level /maintenance directory.
 17+
 18+Example:
 19+ php clear_stats.php
 20+
 21+The following parameters are available to all maintenance scripts
 22+--help : Print a help message
 23+--quiet : Quiet non-error output
 24+--dbuser : The database user to use for the script (if needed)
 25+--dbpass : Same as above (if needed)
 26+
 27+3. HOW TO WRITE YOUR OWN
 28+Make a file in the maintenance directory called myScript.php or something.
 29+In it, write the following:
 30+
 31+==BEGIN==
 32+
 33+<?php
 34+
 35+require_once( "Maintenance.php" );
 36+
 37+class DemoMaint extends Maintenance {
 38+
 39+ public function __construct() {
 40+ parent::__construct();
 41+ }
 42+
 43+ protected function execute() {
 44+ }
 45+}
 46+
 47+$maintClass = "DemoMaint";
 48+require_once( "doMaintenance.php" );
 49+
 50+==END==
 51+
 52+That's it. In the execute() method, you have access to all of the normal
 53+MediaWiki functions, so you can get a DB connection, use the cache, etc.
 54+For full docs on the Maintenance class, see the auto-generated docs at
5155 http://svn.wikimedia.org/doc/classMaintenance.html
\ No newline at end of file
Property changes on: branches/maintenance-work/docs/maintenance.txt
___________________________________________________________________
Name: svn:eol-style
5256 + native

Status & tagging log