Manual:Writing maintenance scripts

From MediaWiki.org
Jump to: navigation, search

Other languages:
Deutsch • ‎English • ‎español • ‎français • ‎日本語 • ‎polski • ‎português do Brasil • ‎українська

This is a step-by-step tutorial on writing a maintenance script based on the Maintenance class (see Maintenance.phpManual:Maintenance.php) which was introduced in MediaWiki 1.16 to make it easier to write command-line MediaWiki maintenance scripts.

Example script[edit]

We'll walk through a helloWorld.php maintenance script that simply prints “Hello, World”. This program contains the minimum amount of code needed to run as well as the expected copyright header (for alternative headers, see copyright headers):

 1 <?php
 2 
 3 /**
 4  * To the extent possible under law,  I, Mark Hershberger, have waived all copyright and
 5  * related or neighboring rights to Hello World. This work is published from the
 6  * United States.
 7  *
 8  * @copyright CC0 http://creativecommons.org/publicdomain/zero/1.0/
 9  * @author Mark A. Hershberger <mah@everybody.org>
10  * @ingroup Maintenance
11  */
12 
13 $basePath = getenv( 'MW_INSTALL_PATH' ) !== false ? getenv( 'MW_INSTALL_PATH' ) : __DIR__ . '/../../..';
14 require_once $basePath . '/maintenance/Maintenance.php';
15 
16 class HelloWorld extends Maintenance {
17 	public function execute() {
18 		echo "Hello, World!\n";
19 	}
20 }
21 
22 $maintClass = 'HelloWorld';
23 
24 require_once RUN_MAINTENANCE_IF_MAIN;

The program will just print out “Hello, World!” but already has a --help (and other command line options). Sample output:

$ php helloWorld.php
Hello, World!
$ php helloWorld.php --help

Usage: php helloWorld.php [--conf|--dbpass|--dbuser|--globals|--help|--quiet|--wiki]
    conf : Location of LocalSettings.php, if not default
    dbpass : The password to use for this script
    dbuser : The DB user to use for this script
    globals : Output globals at the end of processing for debugging
    help : Display this help message
    quiet : Whether to supress non-error output
    wiki : For specifying the wiki ID

An overview:

13 require_once __DIR__ . "/Maintenance.php";
We include Maintenance.php. This defines the abstract class Maintenance which has method to parse arguments, read the console, get the database, etc. It is best to use the full path to Maintenance.php.
15 class HelloWorld extends Maintenance {
We extend the Maintenance class and then, with
21 $maintClass = 'HelloWorld';
22 
23 require_once RUN_MAINTENANCE_IF_MAIN;
tell the Maintenance class to run the script using our HelloWorld class, only if being executed from the command line.

Internally, RUN_MAINTENANCE_IF_MAIN loads another file doMaintenance.php which autoloads MediaWiki classes and configuration, and then

16 	public function execute() {
The execute() function that we've defined is executed, and our script does its work.

Adding a description[edit]

"But what is this maintenance script for?" I can hear you asking.

We can put a description at the top of the "--help" output by using the addDescription method in our constructor:

16 	public function __construct() {
17 		parent::__construct();
18 
19 		$this->addDescription( 'Say hello.' );
20 	}

The output now gives us the description:

$ php helloWorld.php --help

Say hello.

Usage: php helloWorld.php [--conf|--dbpass|--dbuser|--globals|--help|--quiet|--wiki]
…

Option and argument parsing[edit]

Greeting the world is all well and good, but we want to be able to greet individuals, too.

To add a command-line option, add a constructor to class HelloWorld that calls Maintenance's addOption() and update the execute() method to use the new option. addOption()'s parameters are $name, $description, $required = false, $withArg = false, $shortName = false, so:

16 	public function __construct() {
17 		parent::__construct();
18 
19 		$this->addDescription( 'Say hello.' );
20 		$this->addOption( 'name', 'Who to say Hello to', false, true );
21 	}
22 
23 	public function execute() {
24 		$name = $this->getOption( 'name', 'World' );
25 		echo "Hello, $name!\n";
26 	}

This time, when executed, the output of the helloWorld.php script changes depending on the argument provided:

$ php helloWorld.php
Hello, World!
$ php helloWorld.php --name=Mark
Hello, Mark!
$ php helloWorld.php --help

Say hello.

Usage: php helloWorld.php [--conf|--dbpass|--dbuser|--globals|--help|--name|--quiet|--wiki]
…
    name : Who to say Hello to

Extensions[edit]

MediaWiki version: 1.28
Gerrit change 301709

If your maintenance script is for an extension, then you should add a requirement that the extension is installed:

16 	public function __construct() {
17 		parent::__construct();
18 		$this->requireExtension( 'FooBar' );
19 		$this->addOption( 'name', 'Who to say Hello to', false, true );
20 	}

Mostly this provides a nice error message when the extension is not enabled on that wiki (likely on wiki farms). This will only work for extensions that use extension.jsonManual:Extension registration.