Make revdel input form more consistent with other forms:
[lhc/web/wiklou.git] / maintenance / Maintenance.php
index 4cc49d6..107e66a 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 // Define this so scripts can easily find doMaintenance.php
-define( 'DO_MAINTENANCE', dirname(__FILE__) . '/doMaintenance.php' );
+define( 'DO_MAINTENANCE', dirname( __FILE__ ) . '/doMaintenance.php' );
+$maintClass = false;
 
 // Make sure we're on PHP5 or better
 if( version_compare( PHP_VERSION, '5.0.0' ) < 0 ) {
@@ -45,39 +46,39 @@ abstract class Maintenance {
        const DB_NONE  = 0;
        const DB_STD   = 1;
        const DB_ADMIN = 2;
-       
+
        // Const for getStdin()
        const STDIN_ALL = 'all';
 
        // This is the desired params
-       private $mParams = array();
-       
+       protected $mParams = array();
+
        // Array of desired args
-       private $mArgList = array();
+       protected $mArgList = array();
 
        // This is the list of options that were actually passed
-       private $mOptions = array();
+       protected $mOptions = array();
 
        // This is the list of arguments that were actually passed
        protected $mArgs = array();
-       
+
        // Name of the script currently running
        protected $mSelf;
 
        // Special vars for params that are always used
-       private $mQuiet = false;
-       private $mDbUser, $mDbPass;
+       protected $mQuiet = false;
+       protected $mDbUser, $mDbPass;
 
        // A description of the script, children should change this
        protected $mDescription = '';
-       
+
        // Have we already loaded our user input?
-       private $mInputLoaded = false;
-       
+       protected $mInputLoaded = false;
+
        // Batch size. If a script supports this, they should set
        // a default with setBatchSize()
        protected $mBatchSize = null;
-       
+
        /**
         * List of all the core maintenance scripts. This is added
         * to scripts added by extensions in $wgMaintenanceScripts
@@ -108,18 +109,18 @@ abstract class Maintenance {
         * @param $withArg Boolean Is an argument required with this option?
         */
        protected function addOption( $name, $description, $required = false, $withArg = false ) {
-               $this->mParams[ $name ] = array( 'desc' => $description, 'require' => $required, 'withArg' => $withArg );
+               $this->mParams[$name] = array( 'desc' => $description, 'require' => $required, 'withArg' => $withArg );
        }
-       
+
        /**
         * Checks to see if a particular param exists.
         * @param $name String The name of the param
         * @return boolean
         */
        protected function hasOption( $name ) {
-               return isset( $this->mOptions[ $name ] );
+               return isset( $this->mOptions[$name] );
        }
-       
+
        /**
         * Get an option, or return the default
         * @param $name String The name of the param
@@ -127,7 +128,7 @@ abstract class Maintenance {
         * @return mixed
         */
        protected function getOption( $name, $default = null ) {
-               if( $this->hasOption($name) ) {
+               if( $this->hasOption( $name ) ) {
                        return $this->mOptions[$name];
                } else {
                        // Set it so we don't have to provide the default again
@@ -135,21 +136,28 @@ abstract class Maintenance {
                        return $this->mOptions[$name];
                }
        }
-       
+
        /**
-        * Add some args that are needed. Used in formatting help
+        * Add some args that are needed
+        * @param $arg String Name of the arg, like 'start'
+        * @param $description String Short description of the arg
+        * @param $required Boolean Is this required?
         */
-       protected function addArgs( $args ) {
-               $this->mArgList = array_merge( $this->mArgList, $args );
+       protected function addArg( $arg, $description, $required = true ) {
+               $this->mArgList[] = array( 
+                       'name' => $arg,
+                       'desc' => $description, 
+                       'require' => $required 
+               );
        }
-       
+
        /**
         * Does a given argument exist?
         * @param $argId int The integer value (from zero) for the arg
         * @return boolean
         */
        protected function hasArg( $argId = 0 ) {
-               return isset( $this->mArgs[ $argId ] ) ;
+               return isset( $this->mArgs[$argId] );
        }
 
        /**
@@ -159,7 +167,7 @@ abstract class Maintenance {
         * @return mixed
         */
        protected function getArg( $argId = 0, $default = null ) {
-               return $this->hasArg($argId) ? $this->mArgs[$argId] : $default;
+               return $this->hasArg( $argId ) ? $this->mArgs[$argId] : $default;
        }
 
        /**
@@ -192,7 +200,7 @@ abstract class Maintenance {
                if( !$len )
                        return $f;
                $input = fgets( $f, $len );
-               fclose ( $f );
+               fclose( $f );
                return rtrim( $input );
        }
 
@@ -224,23 +232,23 @@ abstract class Maintenance {
        }
 
        /**
-        * Does the script need normal DB access? By default, we give Maintenance
-        * scripts admin rights to the DB (when available). Sometimes, a script needs
-        * normal access for a reason and sometimes they want no access. Subclasses 
-        * should override and return one of the following values, as needed:
+        * Does the script need different DB access? By default, we give Maintenance
+        * scripts normal rights to the DB. Sometimes, a script needs admin rights
+        * access for a reason and sometimes they want no access. Subclasses should 
+        * override and return one of the following values, as needed:
         *    Maintenance::DB_NONE  -  For no DB access at all
-        *    Maintenance::DB_STD   -  For normal DB access
-        *    Maintenance::DB_ADMIN -  For admin DB access, default
+        *    Maintenance::DB_STD   -  For normal DB access, default
+        *    Maintenance::DB_ADMIN -  For admin DB access
         * @return int
         */
        protected function getDbType() {
-               return Maintenance :: DB_ADMIN;
+               return Maintenance::DB_STD;
        }
 
        /**
         * Add the default parameters to the scripts
         */
-       private function addDefaultParams() {
+       protected function addDefaultParams() {
                $this->addOption( 'help', "Display this help message" );
                $this->addOption( 'quiet', "Whether to supress non-error output" );
                $this->addOption( 'conf', "Location of LocalSettings.php, if not default", false, true );
@@ -259,17 +267,17 @@ abstract class Maintenance {
        }
 
        /**
-        * Spawn a child maintenance script. Pass all of the current arguments
+        * Run a child maintenance script. Pass all of the current arguments
         * to it.
         * @param $maintClass String A name of a child maintenance class
         * @param $classFile String Full path of where the child is
         * @return Maintenance child
         */
-       protected function spawnChild( $maintClass, $classFile = null ) {
+       protected function runChild( $maintClass, $classFile = null ) {
                // If we haven't already specified, kill setup procedures
                // for child scripts, we've already got a sane environment
                self::disableSetup();
-               
+
                // Make sure the class is loaded first
                if( !class_exists( $maintClass ) ) {
                        if( $classFile ) {
@@ -279,7 +287,7 @@ abstract class Maintenance {
                                $this->error( "Cannot spawn child: $maintClass" );
                        }
                }
-               
+
                $child = new $maintClass();
                $child->loadParamsAndArgs( $this->mSelf, $this->mOptions, $this->mArgs );
                return $child;
@@ -327,21 +335,26 @@ abstract class Maintenance {
                # Set the memory limit
                ini_set( 'memory_limit', -1 );
 
-               $wgRequestTime = microtime(true);
+               # Set max execution time to 0 (no limit). PHP.net says that
+               # "When running PHP from the command line the default setting is 0."
+               # But sometimes this doesn't seem to be the case.
+               ini_set( 'max_execution_time', 0 );
+
+               $wgRequestTime = microtime( true );
 
-               # Define us as being in Mediawiki
+               # Define us as being in MediaWiki
                define( 'MEDIAWIKI', true );
 
                # Setup $IP, using MW_INSTALL_PATH if it exists
-               $IP = strval( getenv('MW_INSTALL_PATH') ) !== ''
-                       ? getenv('MW_INSTALL_PATH')
+               $IP = strval( getenv( 'MW_INSTALL_PATH' ) ) !== ''
+                       ? getenv( 'MW_INSTALL_PATH' )
                        : realpath( dirname( __FILE__ ) . '/..' );
-               
+
                $wgCommandLineMode = true;
                # Turn off output buffering if it's on
                @ob_end_flush();
 
-               if (!isset( $wgUseNormalUser ) ) {
+               if ( !isset( $wgUseNormalUser ) ) {
                        $wgUseNormalUser = false;
                }
 
@@ -413,7 +426,8 @@ abstract class Maintenance {
                                if ( isset( $this->mParams[$option] ) && $this->mParams[$option]['withArg'] ) {
                                        $param = next( $argv );
                                        if ( $param === false ) {
-                                               $this->error( "$arg needs a value after it", true );
+                                               $this->error( "\nERROR: $option needs a value after it\n" );
+                                               $this->maybeHelp( true );
                                        }
                                        $options[$option] = $param;
                                } else {
@@ -433,7 +447,8 @@ abstract class Maintenance {
                                        if ( $this->mParams[$option]['withArg'] ) {
                                                $param = next( $argv );
                                                if ( $param === false ) {
-                                                       $this->error( "$arg needs a value after it", true );
+                                                       $this->error( "\nERROR: $option needs a value after it\n" );
+                                                       $this->maybeHelp( true );
                                                }
                                                $options[$option] = $param;
                                        } else {
@@ -454,24 +469,30 @@ abstract class Maintenance {
        /**
         * Run some validation checks on the params, etc
         */
-       private function validateParamsAndArgs() {
-               # Check to make sure we've got all the required ones
+       protected function validateParamsAndArgs() {
+               $die = false;
+               # Check to make sure we've got all the required options
                foreach( $this->mParams as $opt => $info ) {
-                       if( $info['require'] && !$this->hasOption($opt) ) {
-                               $this->error( "Param $opt required.", true );
+                       if( $info['require'] && !$this->hasOption( $opt ) ) {
+                               $this->error( "Param $opt required!" );
+                               $die = true;
                        }
                }
-
-               # Also make sure we've got enough arguments
-               if ( count( $this->mArgs ) < count( $this->mArgList ) ) {
-                       $this->error( "Not enough arguments passed", true );
+               # Check arg list too
+               foreach( $this->mArgList as $k => $info ) {
+                       if( $info['require'] && !$this->hasArg($k) ) {
+                               $this->error( "Argument <" . $info['name'] . "> required!" );
+                               $die = true;
+                       }
                }
+               
+               if( $die ) $this->maybeHelp( true );
        }
-       
+
        /**
         * Handle the special variables that are global to all scripts
         */
-       private function loadSpecialVars() {
+       protected function loadSpecialVars() {
                if( $this->hasOption( 'dbuser' ) )
                        $this->mDbUser = $this->getOption( 'dbuser' );
                if( $this->hasOption( 'dbpass' ) )
@@ -486,9 +507,9 @@ abstract class Maintenance {
         * Maybe show the help.
         * @param $force boolean Whether to force the help to show, default false
         */
-       private function maybeHelp( $force = false ) {
+       protected function maybeHelp( $force = false ) {
                ksort( $this->mParams );
-               if( $this->hasOption('help') || in_array( 'help', $this->mArgs ) || $force ) {
+               if( $this->hasOption( 'help' ) || $force ) {
                        $this->mQuiet = false;
                        if( $this->mDescription ) {
                                $this->output( "\n" . $this->mDescription . "\n" );
@@ -498,24 +519,32 @@ abstract class Maintenance {
                                $this->output( " [--" . implode( array_keys( $this->mParams ), "|--" ) . "]" );
                        }
                        if( $this->mArgList ) {
-                               $this->output( " <" . implode( $this->mArgList, "> <" ) . ">" );
+                               $this->output( " <" );
+                               foreach( $this->mArgList as $k => $arg ) {
+                                       $this->output( $arg['name'] . ">" );
+                                       if( $k < count( $this->mArgList ) - 1 )
+                                               $this->output( " <" );
+                               }
                        }
                        $this->output( "\n" );
                        foreach( $this->mParams as $par => $info ) {
                                $this->output( "\t$par : " . $info['desc'] . "\n" );
                        }
+                       foreach( $this->mArgList as $info ) {
+                               $this->output( "\t<" . $info['name'] . "> : " . $info['desc'] . "\n" );
+                       }
                        die( 1 );
                }
        }
-       
+
        /**
         * Handle some last-minute setup here.
         */
-       private function finalSetup() {
+       public function finalSetup() {
                global $wgCommandLineMode, $wgUseNormalUser, $wgShowSQLErrors;
                global $wgTitle, $wgProfiling, $IP, $wgDBadminuser, $wgDBadminpassword;
                global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
-               
+
                # Turn off output buffering again, it might have been turned on in the settings files
                if( ob_get_level() ) {
                        ob_end_flush();
@@ -527,12 +556,12 @@ abstract class Maintenance {
                if( $this->mDbUser )
                        $wgDBadminuser = $this->mDbUser;
                if( $this->mDbPass )
-                       $wgDBadminpass = $this->mDbPass;
+                       $wgDBadminpassword = $this->mDbPass;
 
                if ( empty( $wgUseNormalUser ) && isset( $wgDBadminuser ) ) {
                        $wgDBuser = $wgDBadminuser;
                        $wgDBpassword = $wgDBadminpassword;
-       
+
                        if( $wgDBservers ) {
                                foreach ( $wgDBservers as $i => $server ) {
                                        $wgDBservers[$i]['user'] = $wgDBuser;
@@ -544,15 +573,15 @@ abstract class Maintenance {
                                $wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
                        }
                }
-       
+
                if ( defined( 'MW_CMDLINE_CALLBACK' ) ) {
                        $fn = MW_CMDLINE_CALLBACK;
                        $fn();
                }
-       
+
                $wgShowSQLErrors = true;
                @set_time_limit( 0 );
-       
+
                $wgProfiling = false; // only for Profiler.php mode; avoids OOM errors
        }
 
@@ -570,7 +599,7 @@ abstract class Maintenance {
         * Do setup specific to WMF
         */
        public function loadWikimediaSettings() {
-               global $IP, $wgNoDBParam, $wgUseNormalUser, $wgConf;
+               global $IP, $wgNoDBParam, $wgUseNormalUser, $wgConf, $site, $lang;
 
                if ( empty( $wgNoDBParam ) ) {
                        # Check if we were passed a db name
@@ -580,7 +609,7 @@ abstract class Maintenance {
                                $db = array_shift( $this->mArgs );
                        }
                        list( $site, $lang ) = $wgConf->siteFromDB( $db );
-       
+
                        # If not, work out the language and site the old way
                        if ( is_null( $site ) || is_null( $lang ) ) {
                                if ( !$db ) {
@@ -598,19 +627,19 @@ abstract class Maintenance {
                        $lang = 'aa';
                        $site = 'wikipedia';
                }
-       
+
                # This is for the IRC scripts, which now run as the apache user
                # The apache user doesn't have access to the wikiadmin_pass command
                if ( $_ENV['USER'] == 'apache' ) {
                #if ( posix_geteuid() == 48 ) {
                        $wgUseNormalUser = true;
                }
-       
+
                putenv( 'wikilang=' . $lang );
-       
+
                $DP = $IP;
                ini_set( 'include_path', ".:$IP:$IP/includes:$IP/languages:$IP/maintenance" );
-       
+
                if ( $lang == 'test' && $site == 'wikipedia' ) {
                        define( 'TESTWIKI', 1 );
                }
@@ -637,17 +666,16 @@ abstract class Maintenance {
                        define( 'MW_DB', $bits[0] );
                        define( 'MW_PREFIX', $bits[1] );
                }
-       
-               if ( ! is_readable( $settingsFile ) ) {
+
+               if ( !is_readable( $settingsFile ) ) {
                        $this->error( "A copy of your installation's LocalSettings.php\n" .
                                                "must exist and be readable in the source directory.", true );
                }
                $wgCommandLineMode = true;
                $DP = $IP;
-               $this->finalSetup();
                return $settingsFile;
        }
-       
+
        /**
         * Support function for cleaning up redundant text records
         * @param $delete boolean Whether or not to actually delete the records
@@ -665,7 +693,7 @@ abstract class Maintenance {
                # Get "active" text records from the revisions table
                $this->output( "Searching for active text records in revisions table..." );
                $res = $dbw->query( "SELECT DISTINCT rev_text_id FROM $tbl_rev" );
-               while( $row = $dbw->fetchObject( $res ) ) {
+               foreach( $res as $row ) {
                        $cur[] = $row->rev_text_id;
                }
                $this->output( "done.\n" );
@@ -673,7 +701,7 @@ abstract class Maintenance {
                # Get "active" text records from the archive table
                $this->output( "Searching for active text records in archive table..." );
                $res = $dbw->query( "SELECT DISTINCT ar_text_id FROM $tbl_arc" );
-               while( $row = $dbw->fetchObject( $res ) ) {
+               foreach( $res as $row ) {
                        $cur[] = $row->ar_text_id;
                }
                $this->output( "done.\n" );
@@ -683,7 +711,7 @@ abstract class Maintenance {
                $set = implode( ', ', $cur );
                $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" );
                $old = array();
-               while( $row = $dbw->fetchObject( $res ) ) {
+               foreach( $res as $row ) {
                        $old[] = $row->old_id;
                }
                $this->output( "done.\n" );
@@ -703,7 +731,7 @@ abstract class Maintenance {
                # Done
                $dbw->commit();
        }
-       
+
        /**
         * Get the maintenance directory.
         */
@@ -721,15 +749,12 @@ abstract class Maintenance {
                global $wgMaintenanceScripts;
                return $wgMaintenanceScripts + self::getCoreScripts();
        }
-       
+
        /**
         * Return all of the core maintenance scripts
-        * @todo Finish porting all scripts so this doesn't blow up
         * @return array
         */
-       private static function getCoreScripts() {
-               return array();
-       /**
+       protected static function getCoreScripts() {
                if( !self::$mCoreScripts ) {
                        self::disableSetup();
                        $paths = array(
@@ -742,8 +767,11 @@ abstract class Maintenance {
                        foreach( $paths as $p ) {
                                $handle = opendir( $p );
                                while( ( $file = readdir( $handle ) ) !== false ) {
+                                       if( $file == 'Maintenance.php' )
+                                               continue;
                                        $file = $p . '/' . $file;
-                                       if( is_dir( $file ) || !strpos( $file, '.php' ) ) {
+                                       if( is_dir( $file ) || !strpos( $file, '.php' ) || 
+                                               ( strpos( file_get_contents( $file ), '$maintClass' ) === false ) ) {
                                                continue;
                                        }
                                        require( $file );
@@ -756,6 +784,5 @@ abstract class Maintenance {
                        }
                }
                return self::$mCoreScripts;
-       */
        }
 }