178 register_shutdown_function( [ $this,
'outputChanneled' ],
false );
191 if ( !function_exists(
'debug_backtrace' ) ) {
196 $bt = debug_backtrace();
197 $count = count( $bt );
201 if ( $bt[0][
'class'] !== self::class || $bt[0][
'function'] !==
'shouldExecute' ) {
204 $includeFuncs = [
'require_once',
'require',
'include',
'include_once' ];
205 for ( $i = 1; $i < $count; $i++ ) {
206 if ( !in_array( $bt[$i][
'function'], $includeFuncs ) ) {
231 return isset( $this->mParams[$name] );
245 protected function addOption( $name, $description, $required =
false,
246 $withArg =
false, $shortName =
false, $multiOccurrence =
false
248 $this->mParams[$name] = [
249 'desc' => $description,
250 'require' => $required,
251 'withArg' => $withArg,
252 'shortName' => $shortName,
253 'multiOccurrence' => $multiOccurrence
256 if ( $shortName !==
false ) {
257 $this->mShortParamsMap[$shortName] = $name;
268 return isset( $this->mOptions[$name] );
282 protected function getOption( $name, $default =
null ) {
284 return $this->mOptions[$name];
296 protected function addArg( $arg, $description, $required =
true ) {
297 $this->mArgList[] = [
299 'desc' => $description,
300 'require' => $required
309 unset( $this->mParams[$name] );
318 $this->mAllowUnregisteredOptions = $allow;
326 $this->mDescription = $text;
334 protected function hasArg( $argId = 0 ) {
335 if ( func_num_args() === 0 ) {
336 wfDeprecated( __METHOD__ .
' without an $argId',
'1.33' );
339 return isset( $this->mArgs[$argId] );
349 protected function getArg( $argId = 0, $default =
null ) {
350 if ( func_num_args() === 0 ) {
351 wfDeprecated( __METHOD__ .
' without an $argId',
'1.33' );
354 return $this->mArgs[$argId] ?? $default;
373 $this->mBatchSize =
$s;
380 if ( $this->mBatchSize ) {
381 $this->
addOption(
'batch-size',
'Run this many operations ' .
382 'per batch, default: ' . $this->mBatchSize,
false,
true );
383 if ( isset( $this->mParams[
'batch-size'] ) ) {
385 $this->mDependantParameters[
'batch-size'] = $this->mParams[
'batch-size'];
405 if ( $len == self::STDIN_ALL ) {
406 return file_get_contents(
'php://stdin' );
408 $f = fopen(
'php://stdin',
'rt' );
412 $input = fgets( $f, $len );
415 return rtrim( $input );
432 protected function output( $out, $channel =
null ) {
434 if ( class_exists( MediaWikiServices::class ) ) {
436 $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
437 if ( $stats->getDataCount() > 1000 ) {
438 MediaWiki::emitBufferedStatsdData( $stats, $this->
getConfig() );
442 if ( $this->mQuiet ) {
445 if ( $channel ===
null ) {
449 $out = preg_replace(
'/\n\z/',
'', $out );
461 protected function error( $err, $die = 0 ) {
462 if ( intval( $die ) !== 0 ) {
468 ( PHP_SAPI ==
'cli' || PHP_SAPI ==
'phpdbg' ) &&
469 !defined(
'MW_PHPUNIT_TEST' )
471 fwrite( STDERR, $err .
"\n" );
486 $this->
error( $msg );
497 if ( !$this->atLineStart ) {
499 $this->atLineStart =
true;
512 if ( $msg ===
false ) {
519 if ( !$this->atLineStart && $channel !== $this->lastChannel ) {
525 $this->atLineStart =
false;
526 if ( $channel ===
null ) {
529 $this->atLineStart =
true;
531 $this->lastChannel = $channel;
553 # Generic (non script dependant) options:
555 $this->
addOption(
'help',
'Display this help message',
false,
false,
'h' );
556 $this->
addOption(
'quiet',
'Whether to suppress non-error output',
false,
false,
'q' );
557 $this->
addOption(
'conf',
'Location of LocalSettings.php, if not default',
false,
true );
558 $this->
addOption(
'wiki',
'For specifying the wiki ID',
false,
true );
559 $this->
addOption(
'globals',
'Output globals at the end of processing for debugging' );
562 'Set a specific memory limit for the script, '
563 .
'"max" for no limit or "default" to avoid changing it',
567 $this->
addOption(
'server',
"The protocol and server name to use in URLs, e.g. " .
568 "http://en.wikipedia.org. This is sometimes necessary because " .
569 "server name detection may fail in command line scripts.",
false,
true );
570 $this->
addOption(
'profiler',
'Profiler output format (usually "text")',
false,
true );
572 # Save generic options to display them separately in help
575 # Script dependant options:
579 $this->
addOption(
'dbuser',
'The DB user to use for this script',
false,
true );
580 $this->
addOption(
'dbpass',
'The password to use for this script',
false,
true );
581 $this->
addOption(
'dbgroupdefault',
'The default DB group to use.',
false,
true );
584 # Save additional script dependant options to display
585 # Â them separately in help
586 $this->mDependantParameters = array_diff_key( $this->mParams, $this->mGenericParameters );
595 if ( $this->config ===
null ) {
596 $this->config = MediaWikiServices::getInstance()->getMainConfig();
620 $this->requiredExtensions[] = $name;
629 $registry = ExtensionRegistry::getInstance();
631 foreach ( $this->requiredExtensions as $name ) {
632 if ( !$registry->isLoaded( $name ) ) {
638 $joined = implode(
', ', $missing );
639 $msg =
"The following extensions are required to be installed "
640 .
"for this script to run: $joined. Please enable them and then try again.";
650 if ( function_exists(
'posix_getpwuid' ) ) {
651 $agent = posix_getpwuid( posix_geteuid() )[
'name'];
657 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
659 $lbFactory->setAgentName(
660 mb_strlen( $agent ) > 15 ? mb_substr( $agent, 0, 15 ) .
'...' : $agent
671 $services = MediaWikiServices::getInstance();
672 $stats = $services->getStatsdDataFactory();
674 $lbFactory = $services->getDBLoadBalancerFactory();
675 $lbFactory->setWaitForReplicationListener(
677 function () use ( $stats,
$config ) {
680 DeferredUpdates::tryOpportunisticExecute(
'run' );
683 MediaWiki::emitBufferedStatsdData( $stats,
$config );
688 $lbFactory->getMainLB()->setTransactionListener(
690 function ( $trigger ) use ( $stats,
$config ) {
692 if (
$config->
get(
'CommandLineMode' ) && $trigger === IDatabase::TRIGGER_COMMIT ) {
693 DeferredUpdates::tryOpportunisticExecute(
'run' );
696 MediaWiki::emitBufferedStatsdData( $stats,
$config );
712 require_once $classFile;
715 $this->
error(
"Cannot spawn child: $maintClass" );
723 $child->loadParamsAndArgs( $this->mSelf, $this->mOptions, $this->mArgs );
724 if ( $this->mDb !==
null ) {
725 $child->setDB( $this->mDb );
737 # Abort if called from a web server
738 # wfIsCLI() is not available yet
739 if ( PHP_SAPI !==
'cli' && PHP_SAPI !==
'phpdbg' ) {
740 $this->
fatalError(
'This script must be run from the command line' );
743 if ( $IP ===
null ) {
744 $this->
fatalError(
"\$IP not set, aborting!\n" .
745 '(Did you forget to call parent::__construct() in your maintenance script?)' );
748 # Make sure we can handle script parameters
749 if ( !defined(
'HPHP_VERSION' ) && !ini_get(
'register_argc_argv' ) ) {
750 $this->
fatalError(
'Cannot get command line arguments, register_argc_argv is set to false' );
756 if ( ini_get(
'display_errors' ) ) {
757 ini_set(
'display_errors',
'stderr' );
762 # Set the memory limit
763 # Note we need to set it again later in cache LocalSettings changed it
766 # Set max execution time to 0 (no limit). PHP.net says that
767 # "When running PHP from the command line the default setting is 0."
768 # But sometimes this doesn't seem to be the case.
769 ini_set(
'max_execution_time', 0 );
773 # Turn off output buffering if it's on
774 while ( ob_get_level() > 0 ) {
790 $limit = $this->
getOption(
'memory-limit',
'max' );
791 $limit = trim( $limit,
"\" '" );
800 if ( $limit ==
'max' ) {
803 if ( $limit !=
'default' ) {
804 ini_set(
'memory_limit', $limit );
814 $output = $this->
getOption(
'profiler' );
822 $profiler =
new $class(
823 [
'sampling' => 1,
'output' => [ $output ] ]
825 + [
'threshold' => 0.0 ]
827 $profiler->setAllowOutput();
828 Profiler::replaceStubInstance( $profiler );
831 $trxProfiler = Profiler::instance()->getTransactionProfiler();
832 $trxProfiler->setLogger( LoggerFactory::getInstance(
'DBPerformance' ) );
840 $this->mOptions = [];
842 $this->mInputLoaded =
false;
855 $this->orderedOptions = [];
858 for ( $arg = reset( $argv ); $arg !==
false; $arg = next( $argv ) ) {
859 if ( $arg ==
'--' ) {
860 # End of options, remainder should be considered arguments
861 $arg = next( $argv );
862 while ( $arg !==
false ) {
864 $arg = next( $argv );
867 } elseif ( substr( $arg, 0, 2 ) ==
'--' ) {
869 $option = substr( $arg, 2 );
870 if ( isset( $this->mParams[$option] ) && $this->mParams[$option][
'withArg'] ) {
871 $param = next( $argv );
872 if ( $param ===
false ) {
873 $this->
error(
"\nERROR: $option parameter needs a value after it\n" );
877 $this->
setParam( $options, $option, $param );
879 $bits = explode(
'=', $option, 2 );
880 $this->
setParam( $options, $bits[0], $bits[1] ?? 1 );
882 } elseif ( $arg ==
'-' ) {
883 # Lonely "-", often used to indicate stdin or stdout.
885 } elseif ( substr( $arg, 0, 1 ) ==
'-' ) {
887 $argLength = strlen( $arg );
888 for ( $p = 1; $p < $argLength; $p++ ) {
890 if ( !isset( $this->mParams[$option] ) && isset( $this->mShortParamsMap[$option] ) ) {
891 $option = $this->mShortParamsMap[$option];
894 if ( isset( $this->mParams[$option][
'withArg'] ) && $this->mParams[$option][
'withArg'] ) {
895 $param = next( $argv );
896 if ( $param ===
false ) {
897 $this->
error(
"\nERROR: $option parameter needs a value after it\n" );
900 $this->
setParam( $options, $option, $param );
902 $this->
setParam( $options, $option, 1 );
910 $this->mOptions = $options;
911 $this->mArgs =
$args;
913 $this->mInputLoaded =
true;
928 private function setParam( &$options, $option, $value ) {
929 $this->orderedOptions[] = [ $option, $value ];
931 if ( isset( $this->mParams[$option] ) ) {
932 $multi = $this->mParams[$option][
'multiOccurrence'];
936 $exists = array_key_exists( $option, $options );
937 if ( $multi && $exists ) {
938 $options[$option][] = $value;
939 } elseif ( $multi ) {
940 $options[$option] = [ $value ];
941 } elseif ( !$exists ) {
942 $options[$option] = $value;
944 $this->
error(
"\nERROR: $option parameter given twice\n" );
959 # If we were given opts or args, set those and return early
961 $this->mSelf =
$self;
962 $this->mInputLoaded =
true;
965 $this->mOptions = $opts;
966 $this->mInputLoaded =
true;
969 $this->mArgs =
$args;
970 $this->mInputLoaded =
true;
973 # If we've already loaded input (either by user values or from $argv)
974 # skip on loading it again. The array_shift() will corrupt values if
975 # it's run again and again
976 if ( $this->mInputLoaded ) {
983 $this->mSelf = $argv[0];
993 # Check to make sure we've got all the required options
994 foreach ( $this->mParams as $opt => $info ) {
995 if ( $info[
'require'] && !$this->
hasOption( $opt ) ) {
996 $this->
error(
"Param $opt required!" );
1000 # Check arg list too
1001 foreach ( $this->mArgList as $k => $info ) {
1002 if ( $info[
'require'] && !$this->
hasArg( $k ) ) {
1003 $this->
error(
'Argument <' . $info[
'name'] .
'> required!' );
1007 if ( !$this->mAllowUnregisteredOptions ) {
1008 # Check for unexpected options
1009 foreach ( $this->mOptions as $opt => $val ) {
1011 $this->
error(
"Unexpected option $opt!" );
1026 $this->mDbUser = $this->
getOption(
'dbuser' );
1029 $this->mDbPass = $this->
getOption(
'dbpass' );
1032 $this->mQuiet =
true;
1034 if ( $this->
hasOption(
'batch-size' ) ) {
1035 $this->mBatchSize = intval( $this->
getOption(
'batch-size' ) );
1045 if ( !$force && !$this->
hasOption(
'help' ) ) {
1058 $descWidth = $screenWidth - ( 2 * strlen( $tab ) );
1060 ksort( $this->mParams );
1061 $this->mQuiet =
false;
1064 if ( $this->mDescription ) {
1065 $this->
output(
"\n" . wordwrap( $this->mDescription, $screenWidth ) .
"\n" );
1067 $output =
"\nUsage: php " . basename( $this->mSelf );
1070 if ( $this->mParams ) {
1071 $output .=
" [--" . implode(
"|--", array_keys( $this->mParams ) ) .
"]";
1075 if ( $this->mArgList ) {
1077 foreach ( $this->mArgList as $k => $arg ) {
1078 if ( $arg[
'require'] ) {
1079 $output .=
'<' . $arg[
'name'] .
'>';
1081 $output .=
'[' . $arg[
'name'] .
']';
1083 if ( $k < count( $this->mArgList ) - 1 ) {
1088 $this->
output(
"$output\n\n" );
1090 # TODO abstract some repetitive code below
1093 $this->
output(
"Generic maintenance parameters:\n" );
1094 foreach ( $this->mGenericParameters as $par => $info ) {
1095 if ( $info[
'shortName'] !==
false ) {
1096 $par .=
" (-{$info['shortName']})";
1099 wordwrap(
"$tab--$par: " . $info[
'desc'], $descWidth,
1100 "\n$tab$tab" ) .
"\n"
1106 if ( count( $scriptDependantParams ) > 0 ) {
1107 $this->
output(
"Script dependant parameters:\n" );
1109 foreach ( $scriptDependantParams as $par => $info ) {
1110 if ( $info[
'shortName'] !==
false ) {
1111 $par .=
" (-{$info['shortName']})";
1114 wordwrap(
"$tab--$par: " . $info[
'desc'], $descWidth,
1115 "\n$tab$tab" ) .
"\n"
1123 $scriptSpecificParams = array_diff_key(
1124 # all script parameters:
1126 # remove the Maintenance default parameters:
1130 '@phan-var array[] $scriptSpecificParams';
1131 if ( count( $scriptSpecificParams ) > 0 ) {
1132 $this->
output(
"Script specific parameters:\n" );
1134 foreach ( $scriptSpecificParams as $par => $info ) {
1135 if ( $info[
'shortName'] !==
false ) {
1136 $par .=
" (-{$info['shortName']})";
1139 wordwrap(
"$tab--$par: " . $info[
'desc'], $descWidth,
1140 "\n$tab$tab" ) .
"\n"
1147 if ( count( $this->mArgList ) > 0 ) {
1148 $this->
output(
"Arguments:\n" );
1150 foreach ( $this->mArgList as $info ) {
1151 $openChar = $info[
'require'] ?
'<' :
'[';
1152 $closeChar = $info[
'require'] ?
'>' :
']';
1154 wordwrap(
"$tab$openChar" . $info[
'name'] .
"$closeChar: " .
1155 $info[
'desc'], $descWidth,
"\n$tab$tab" ) .
"\n"
1171 # Turn off output buffering again, it might have been turned on in the settings files
1172 if ( ob_get_level() ) {
1178 # Override $wgServer
1180 $wgServer = $this->
getOption(
'server', $wgServer );
1183 # If these were passed, use them
1184 if ( $this->mDbUser ) {
1187 if ( $this->mDbPass ) {
1190 if ( $this->
hasOption(
'dbgroupdefault' ) ) {
1191 $wgDBDefaultGroup = $this->
getOption(
'dbgroupdefault',
null );
1193 $service = MediaWikiServices::getInstance()->peekService(
'DBLoadBalancerFactory' );
1195 $service->destroy();
1216 $service = MediaWikiServices::getInstance()->peekService(
'DBLoadBalancerFactory' );
1218 $service->destroy();
1227 $wgShowExceptionDetails =
true;
1230 Wikimedia\suppressWarnings();
1231 set_time_limit( 0 );
1232 Wikimedia\restoreWarnings();
1242 if ( defined(
'MW_CMDLINE_CALLBACK' ) ) {
1243 call_user_func( MW_CMDLINE_CALLBACK );
1264 if ( isset( $this->mOptions[
'conf'] ) ) {
1265 $settingsFile = $this->mOptions[
'conf'];
1266 } elseif ( defined(
"MW_CONFIG_FILE" ) ) {
1267 $settingsFile = MW_CONFIG_FILE;
1269 $settingsFile =
"$IP/LocalSettings.php";
1271 if ( isset( $this->mOptions[
'wiki'] ) ) {
1272 $bits = explode(
'-', $this->mOptions[
'wiki'], 2 );
1273 define(
'MW_DB', $bits[0] );
1274 define(
'MW_PREFIX', $bits[1] ??
'' );
1275 } elseif ( isset( $this->mOptions[
'server'] ) ) {
1280 $_SERVER[
'SERVER_NAME'] = $this->mOptions[
'server'];
1283 if ( !is_readable( $settingsFile ) ) {
1284 $this->
fatalError(
"A copy of your installation's LocalSettings.php\n" .
1285 "must exist and be readable in the source directory.\n" .
1286 "Use --conf to specify it." );
1288 $wgCommandLineMode =
true;
1290 return $settingsFile;
1299 # Data should come off the master, wrapped in a transaction
1303 # Get "active" text records via the content table
1305 $this->
output(
'Searching for active text records via contents table...' );
1306 $res = $dbw->select(
'content',
'content_address', [], __METHOD__, [
'DISTINCT' ] );
1307 $blobStore = MediaWikiServices::getInstance()->getBlobStore();
1308 foreach (
$res as $row ) {
1310 $textId = $blobStore->getTextIdFromAddress( $row->content_address );
1315 $this->
output(
"done.\n" );
1317 # Get the IDs of all text records not in these sets
1318 $this->
output(
'Searching for inactive text records...' );
1319 $cond =
'old_id NOT IN ( ' . $dbw->makeList( $cur ) .
' )';
1320 $res = $dbw->select(
'text',
'old_id', [ $cond ], __METHOD__, [
'DISTINCT' ] );
1322 foreach (
$res as $row ) {
1323 $old[] = $row->old_id;
1325 $this->
output(
"done.\n" );
1327 # Inform the user of what we're going to do
1328 $count = count( $old );
1329 $this->
output(
"$count inactive items found.\n" );
1331 # Delete as appropriate
1332 if ( $delete && $count ) {
1333 $this->
output(
'Deleting...' );
1334 $dbw->delete(
'text', [
'old_id' => $old ], __METHOD__ );
1335 $this->
output(
"done.\n" );
1346 return __DIR__ .
'/../';
1363 protected function getDB( $db, $groups = [], $dbDomain =
false ) {
1364 if ( $this->mDb ===
null ) {
1365 return MediaWikiServices::getInstance()
1366 ->getDBLoadBalancerFactory()
1367 ->getMainLB( $dbDomain )
1368 ->getMaintenanceConnectionRef( $db, $groups, $dbDomain );
1395 $dbw->
begin( $fname );
1411 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
1412 $waitSucceeded = $lbFactory->waitForReplication(
1413 [
'timeout' => 30,
'ifWritesSince' => $this->lastReplicationWait ]
1415 $this->lastReplicationWait = microtime(
true );
1416 return $waitSucceeded;
1438 $write = [
'searchindex' ];
1448 $db->lockTables( $read, $write, __CLASS__ .
'-searchIndexLock' );
1456 $db->unlockTables( __CLASS__ .
'-searchIndexLock' );
1480 if ( $maxLockTime ) {
1481 $this->
output(
" --- Waiting for lock ---" );
1487 # Loop through the results and do a search update
1488 foreach ( $results as $row ) {
1489 # Allow reads to be processed
1490 if ( $maxLockTime && time() > $lockTime + $maxLockTime ) {
1491 $this->
output(
" --- Relocking ---" );
1496 call_user_func( $callback, $row );
1499 # Unlock searchindex
1500 if ( $maxLockTime ) {
1501 $this->
output(
" --- Unlocking --" );
1514 $rev = MediaWikiServices::getInstance()
1515 ->getRevisionLookup()
1516 ->getRevisionByPageId( $pageId, 0, IDBAccessObject::READ_LATEST );
1519 $titleObj = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
1520 $title = $titleObj->getPrefixedDBkey();
1521 $this->
output(
"$title..." );
1522 # Update searchindex
1523 $u =
new SearchUpdate( $pageId, $titleObj, $rev->getContent( SlotRecord::MAIN ) );
1545 for ( $i = $seconds; $i >= 0; $i-- ) {
1546 if ( $i != $seconds ) {
1547 $this->
output( str_repeat(
"\x08", strlen( $i + 1 ) ) );
1566 if ( !function_exists(
'posix_isatty' ) ) {
1579 static $isatty =
null;
1580 if ( $isatty ===
null ) {
1584 if ( $isatty && function_exists(
'readline' ) ) {
1585 return readline( $prompt );
1590 if ( feof( STDIN ) ) {
1593 $st = fgets( STDIN, 1024 );
1596 if ( $st ===
false ) {
1599 $resp = trim( $st );
1611 $bash = ExecutableFinder::findInDefaultPaths(
'bash' );
1614 $encPrompt = Shell::escape( $prompt );
1615 $command =
"read -er -p $encPrompt && echo \"\$REPLY\"";
1616 $encCommand = Shell::escape(
$command );
1617 $line = Shell::escape(
"$bash -c $encCommand", $retval, [], [
'walltime' => 0 ] );
1620 if ( $retval == 0 ) {
1622 } elseif ( $retval == 127 ) {
1633 if ( feof( STDIN ) ) {
1638 return fgets( STDIN, 1024 );
1649 $default = [ 80, 50 ];
1653 if ( Shell::isDisabled() ) {
1663 $result = Shell::command(
'stty',
'size' )
1665 if ( $result->getExitCode() !== 0 ) {
1668 if ( !preg_match(
'/^(\d+) (\d+)$/', $result->getStdout(), $m ) ) {
1671 return [ intval( $m[2] ), intval( $m[1] ) ];
1679 require_once __DIR__ .
'/../../tests/common/TestsAutoLoader.php';
1689 if ( !$this->hookContainer ) {
1690 $this->hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1704 if ( !$this->hookRunner ) {
1721 $ids = preg_split(
'/[\s,;:|]+/', $text );
1728 return array_filter( $ids );
$wgDBuser
Database username.
$wgDBadminuser
Separate username for maintenance tasks.
$wgTrxProfilerLimits
Performance expectations for DB usage.
$wgDBservers
Database load balancer This is a two-dimensional array, an array of server info structures Fields are...
$wgShowHostnames
Expose backend server host names through the API and various HTML comments.
$wgDBDefaultGroup
Default group to use when getting database connections.
$wgDBadminpassword
Separate password for maintenance tasks.
$wgProfiler
Profiler configuration.
$wgShowExceptionDetails
If set to true, uncaught exceptions will print the exception message and a complete stack trace to ou...
$wgServer
URL of the server.
$wgLBFactoryConf
Load balancer factory configuration To set up a multi-master wiki farm, set the class here to somethi...
$wgDBpassword
Database user's password.
global $wgCommandLineMode
wfHostname()
Get host name of the current machine, for use in error reporting.
wfIsWindows()
Check if the operating system is Windows.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
getDB( $db, $groups=[], $dbDomain=false)
Returns a database to be used by current maintenance script.
setup()
Do some sanity checking and basic setup.
array[] $mParams
Array of desired/allowed params.
__construct()
Default constructor.
error( $err, $die=0)
Throw an error to the user.
getName()
Get the script's name.
array[] $mGenericParameters
Generic options added by addDefaultParams()
addArg( $arg, $description, $required=true)
Add some args that are needed.
requireExtension( $name)
Indicate that the specified extension must be loaded before the script can run.
showHelp()
Definitely show the help.
relockSearchindex( $db)
Unlock and lock again Since the lock is low-priority, queued reads will be able to complete.
int $mBatchSize
Batch size.
setAgentAndTriggers()
Set triggers like when to try to run deferred updates.
$mAllowUnregisteredOptions
setAllowUnregisteredOptions( $allow)
Sets whether to allow unregistered options, which are options passed to a script that do not match an...
beginTransaction(IDatabase $dbw, $fname)
Begin a transcation on a DB.
static getTermSize()
Get the terminal size as a two-element array where the first element is the width (number of columns)...
HookContainer null $hookContainer
clearParamsAndArgs()
Clear all params and arguments.
static setLBFactoryTriggers(LBFactory $LBFactory, Config $config)
array $requiredExtensions
setParam(&$options, $option, $value)
Helper function used solely by loadParamsAndArgs to prevent code duplication.
const DB_NONE
Constants for DB access type.
commitTransaction(IDatabase $dbw, $fname)
Commit the transcation on a DB handle and wait for replica DBs to catch up.
array[] $mDependantParameters
Generic options which might or not be supported by the script.
output( $out, $channel=null)
Throw some output to the user.
supportsOption( $name)
Checks to see if a particular option in supported.
getStdin( $len=null)
Return input from stdin.
cleanupChanneled()
Clean up channeled output.
memoryLimit()
Normally we disable the memory_limit when running admin scripts.
getHookRunner()
Get a HookRunner for running core hooks.
afterFinalSetup()
Execute a callback function at the end of initialisation Stable for overriding.
hasArg( $argId=0)
Does a given argument exist?
getDir()
Get the maintenance directory.
addDefaultParams()
Add the default parameters to the scripts.
deleteOption( $name)
Remove an option.
static readlineEmulation( $prompt)
Emulate readline()
static requireTestsAutoloader()
Call this to set up the autoloader to allow classes to be used from the tests directory.
loadParamsAndArgs( $self=null, $opts=null, $args=null)
Process command line arguments $mOptions becomes an array with keys set to the option names $mArgs be...
outputChanneled( $msg, $channel=null)
Message outputter with channeled message support.
finalSetup()
Handle some last-minute setup here.
loadSpecialVars()
Handle the special variables that are global to all scripts Stable for overriding.
setDB(IMaintainableDatabase $db)
Sets database object to be returned by getDB().
float $lastReplicationWait
UNIX timestamp.
array $orderedOptions
Used to read the options in the order they were passed.
loadSettings()
Generic setup for most installs.
hasOption( $name)
Checks to see if a particular option was set.
purgeRedundantText( $delete=true)
Support function for cleaning up redundant text records.
countDown( $seconds)
Count down from $seconds to zero on the terminal, with a one-second pause between showing each number...
runChild( $maintClass, $classFile=null)
Run a child maintenance script.
IMaintainableDatabase $mDb
Used by getDB() / setDB()
execute()
Do the actual work.
static readconsole( $prompt='> ')
Prompt the console for input.
static posix_isatty( $fd)
Wrapper for posix_isatty() We default as considering stdin a tty (for nice readline methods) but trea...
adjustMemoryLimit()
Adjusts PHP's memory limit to better suit our needs, if needed.
validateParamsAndArgs()
Run some validation checks on the params, etc Stable for overriding.
getHookContainer()
Get a HookContainer, for running extension hooks or for hook metadata.
HookRunner null $hookRunner
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
getBatchSize()
Returns batch size.
unlockSearchindex( $db)
Unlock the tables.
parseIntList( $text)
Utility function to parse a string (perhaps from a command line option) into a list of integers (perh...
getArg( $argId=0, $default=null)
Get an argument.
addDescription( $text)
Set the description text.
activateProfiler()
Activate the profiler (assuming $wgProfiler is set)
maybeHelp( $force=false)
Maybe show the help.
resource $fileHandle
Used when creating separate schema files.
updateSearchIndexForPage(int $pageId)
Update the searchindex table for a given pageid.
loadWithArgv( $argv)
Load params and arguments from a given array of command-line arguments.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
static shouldExecute()
Should we execute the maintenance script, or just allow it to be included as a standalone class?...
getOption( $name, $default=null)
Get an option, or return the default.
Config $config
Accessible via getConfig()
lockSearchindex( $db)
Lock the search index.
checkRequiredExtensions()
Verify that the required extensions are installed.
rollbackTransaction(IDatabase $dbw, $fname)
Rollback the transcation on a DB handle.
updateSearchIndex( $maxLockTime, $callback, $dbw, $results)
Perform a search index update with locking.
globals()
Potentially debug globals.
setConfig(Config $config)
setBatchSize( $s=0)
Set the batch size.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
Database independant search index updater.
while(( $__line=Maintenance::readconsole()) !==false) print
Interface for configuration instances.
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Advanced database interface for IDatabase handles that include maintenance methods.