MediaWiki  REL1_28
Maintenance.php
Go to the documentation of this file.
1 <?php
23 // Bail on old versions of PHP, or if composer has not been run yet to install
24 // dependencies.
25 require_once __DIR__ . '/../includes/PHPVersionCheck.php';
26 wfEntryPointCheck( 'cli' );
27 
33 // Define this so scripts can easily find doMaintenance.php
34 define( 'RUN_MAINTENANCE_IF_MAIN', __DIR__ . '/doMaintenance.php' );
35 define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless
36 
37 $maintClass = false;
38 
41 
52 abstract class Maintenance {
57  const DB_NONE = 0;
58  const DB_STD = 1;
59  const DB_ADMIN = 2;
60 
61  // Const for getStdin()
62  const STDIN_ALL = 'all';
63 
64  // This is the desired params
65  protected $mParams = [];
66 
67  // Array of mapping short parameters to long ones
68  protected $mShortParamsMap = [];
69 
70  // Array of desired args
71  protected $mArgList = [];
72 
73  // This is the list of options that were actually passed
74  protected $mOptions = [];
75 
76  // This is the list of arguments that were actually passed
77  protected $mArgs = [];
78 
79  // Name of the script currently running
80  protected $mSelf;
81 
82  // Special vars for params that are always used
83  protected $mQuiet = false;
84  protected $mDbUser, $mDbPass;
85 
86  // A description of the script, children should change this via addDescription()
87  protected $mDescription = '';
88 
89  // Have we already loaded our user input?
90  protected $mInputLoaded = false;
91 
98  protected $mBatchSize = null;
99 
100  // Generic options added by addDefaultParams()
101  private $mGenericParameters = [];
102  // Generic options which might or not be supported by the script
103  private $mDependantParameters = [];
104 
109  private $mDb = null;
110 
112  private $lastReplicationWait = 0.0;
113 
118  public $fileHandle;
119 
125  private $config;
126 
131  private $requiredExtensions = [];
132 
144  public $orderedOptions = [];
145 
150  public function __construct() {
151  // Setup $IP, using MW_INSTALL_PATH if it exists
152  global $IP;
153  $IP = strval( getenv( 'MW_INSTALL_PATH' ) ) !== ''
154  ? getenv( 'MW_INSTALL_PATH' )
155  : realpath( __DIR__ . '/..' );
156 
157  $this->addDefaultParams();
158  register_shutdown_function( [ $this, 'outputChanneled' ], false );
159  }
160 
168  public static function shouldExecute() {
170 
171  if ( !function_exists( 'debug_backtrace' ) ) {
172  // If someone has a better idea...
173  return $wgCommandLineMode;
174  }
175 
176  $bt = debug_backtrace();
177  $count = count( $bt );
178  if ( $count < 2 ) {
179  return false; // sanity
180  }
181  if ( $bt[0]['class'] !== 'Maintenance' || $bt[0]['function'] !== 'shouldExecute' ) {
182  return false; // last call should be to this function
183  }
184  $includeFuncs = [ 'require_once', 'require', 'include', 'include_once' ];
185  for ( $i = 1; $i < $count; $i++ ) {
186  if ( !in_array( $bt[$i]['function'], $includeFuncs ) ) {
187  return false; // previous calls should all be "requires"
188  }
189  }
190 
191  return true;
192  }
193 
197  abstract public function execute();
198 
210  protected function addOption( $name, $description, $required = false,
211  $withArg = false, $shortName = false, $multiOccurrence = false
212  ) {
213  $this->mParams[$name] = [
214  'desc' => $description,
215  'require' => $required,
216  'withArg' => $withArg,
217  'shortName' => $shortName,
218  'multiOccurrence' => $multiOccurrence
219  ];
220 
221  if ( $shortName !== false ) {
222  $this->mShortParamsMap[$shortName] = $name;
223  }
224  }
225 
231  protected function hasOption( $name ) {
232  return isset( $this->mOptions[$name] );
233  }
234 
245  protected function getOption( $name, $default = null ) {
246  if ( $this->hasOption( $name ) ) {
247  return $this->mOptions[$name];
248  } else {
249  // Set it so we don't have to provide the default again
250  $this->mOptions[$name] = $default;
251 
252  return $this->mOptions[$name];
253  }
254  }
255 
262  protected function addArg( $arg, $description, $required = true ) {
263  $this->mArgList[] = [
264  'name' => $arg,
265  'desc' => $description,
266  'require' => $required
267  ];
268  }
269 
274  protected function deleteOption( $name ) {
275  unset( $this->mParams[$name] );
276  }
277 
282  protected function addDescription( $text ) {
283  $this->mDescription = $text;
284  }
285 
291  protected function hasArg( $argId = 0 ) {
292  return isset( $this->mArgs[$argId] );
293  }
294 
301  protected function getArg( $argId = 0, $default = null ) {
302  return $this->hasArg( $argId ) ? $this->mArgs[$argId] : $default;
303  }
304 
309  protected function setBatchSize( $s = 0 ) {
310  $this->mBatchSize = $s;
311 
312  // If we support $mBatchSize, show the option.
313  // Used to be in addDefaultParams, but in order for that to
314  // work, subclasses would have to call this function in the constructor
315  // before they called parent::__construct which is just weird
316  // (and really wasn't done).
317  if ( $this->mBatchSize ) {
318  $this->addOption( 'batch-size', 'Run this many operations ' .
319  'per batch, default: ' . $this->mBatchSize, false, true );
320  if ( isset( $this->mParams['batch-size'] ) ) {
321  // This seems a little ugly...
322  $this->mDependantParameters['batch-size'] = $this->mParams['batch-size'];
323  }
324  }
325  }
326 
331  public function getName() {
332  return $this->mSelf;
333  }
334 
341  protected function getStdin( $len = null ) {
342  if ( $len == Maintenance::STDIN_ALL ) {
343  return file_get_contents( 'php://stdin' );
344  }
345  $f = fopen( 'php://stdin', 'rt' );
346  if ( !$len ) {
347  return $f;
348  }
349  $input = fgets( $f, $len );
350  fclose( $f );
351 
352  return rtrim( $input );
353  }
354 
358  public function isQuiet() {
359  return $this->mQuiet;
360  }
361 
368  protected function output( $out, $channel = null ) {
369  if ( $this->mQuiet ) {
370  return;
371  }
372  if ( $channel === null ) {
373  $this->cleanupChanneled();
374  print $out;
375  } else {
376  $out = preg_replace( '/\n\z/', '', $out );
377  $this->outputChanneled( $out, $channel );
378  }
379  }
380 
387  protected function error( $err, $die = 0 ) {
388  $this->outputChanneled( false );
389  if ( PHP_SAPI == 'cli' ) {
390  fwrite( STDERR, $err . "\n" );
391  } else {
392  print $err;
393  }
394  $die = intval( $die );
395  if ( $die > 0 ) {
396  die( $die );
397  }
398  }
399 
400  private $atLineStart = true;
401  private $lastChannel = null;
402 
406  public function cleanupChanneled() {
407  if ( !$this->atLineStart ) {
408  print "\n";
409  $this->atLineStart = true;
410  }
411  }
412 
421  public function outputChanneled( $msg, $channel = null ) {
422  if ( $msg === false ) {
423  $this->cleanupChanneled();
424 
425  return;
426  }
427 
428  // End the current line if necessary
429  if ( !$this->atLineStart && $channel !== $this->lastChannel ) {
430  print "\n";
431  }
432 
433  print $msg;
434 
435  $this->atLineStart = false;
436  if ( $channel === null ) {
437  // For unchanneled messages, output trailing newline immediately
438  print "\n";
439  $this->atLineStart = true;
440  }
441  $this->lastChannel = $channel;
442  }
443 
454  public function getDbType() {
455  return Maintenance::DB_STD;
456  }
457 
461  protected function addDefaultParams() {
462 
463  # Generic (non script dependant) options:
464 
465  $this->addOption( 'help', 'Display this help message', false, false, 'h' );
466  $this->addOption( 'quiet', 'Whether to supress non-error output', false, false, 'q' );
467  $this->addOption( 'conf', 'Location of LocalSettings.php, if not default', false, true );
468  $this->addOption( 'wiki', 'For specifying the wiki ID', false, true );
469  $this->addOption( 'globals', 'Output globals at the end of processing for debugging' );
470  $this->addOption(
471  'memory-limit',
472  'Set a specific memory limit for the script, '
473  . '"max" for no limit or "default" to avoid changing it'
474  );
475  $this->addOption( 'server', "The protocol and server name to use in URLs, e.g. " .
476  "http://en.wikipedia.org. This is sometimes necessary because " .
477  "server name detection may fail in command line scripts.", false, true );
478  $this->addOption( 'profiler', 'Profiler output format (usually "text")', false, true );
479 
480  # Save generic options to display them separately in help
481  $this->mGenericParameters = $this->mParams;
482 
483  # Script dependant options:
484 
485  // If we support a DB, show the options
486  if ( $this->getDbType() > 0 ) {
487  $this->addOption( 'dbuser', 'The DB user to use for this script', false, true );
488  $this->addOption( 'dbpass', 'The password to use for this script', false, true );
489  }
490 
491  # Save additional script dependant options to display
492  #  them separately in help
493  $this->mDependantParameters = array_diff_key( $this->mParams, $this->mGenericParameters );
494  }
495 
500  public function getConfig() {
501  if ( $this->config === null ) {
502  $this->config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
503  }
504 
505  return $this->config;
506  }
507 
512  public function setConfig( Config $config ) {
513  $this->config = $config;
514  }
515 
525  protected function requireExtension( $name ) {
526  $this->requiredExtensions[] = $name;
527  }
528 
534  public function checkRequiredExtensions() {
535  $registry = ExtensionRegistry::getInstance();
536  $missing = [];
537  foreach ( $this->requiredExtensions as $name ) {
538  if ( !$registry->isLoaded( $name ) ) {
539  $missing[] = $name;
540  }
541  }
542 
543  if ( $missing ) {
544  $joined = implode( ', ', $missing );
545  $msg = "The following extensions are required to be installed "
546  . "for this script to run: $joined. Please enable them and then try again.";
547  $this->error( $msg, 1 );
548  }
549 
550  }
551 
556  public function setAgentAndTriggers() {
557  if ( function_exists( 'posix_getpwuid' ) ) {
558  $agent = posix_getpwuid( posix_geteuid() )['name'];
559  } else {
560  $agent = 'sysadmin';
561  }
562  $agent .= '@' . wfHostname();
563 
564  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
565  // Add a comment for easy SHOW PROCESSLIST interpretation
566  $lbFactory->setAgentName(
567  mb_strlen( $agent ) > 15 ? mb_substr( $agent, 0, 15 ) . '...' : $agent
568  );
570  }
571 
576  public static function setLBFactoryTriggers( LBFactory $LBFactory ) {
577  // Hook into period lag checks which often happen in long-running scripts
578  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
579  $lbFactory->setWaitForReplicationListener(
580  __METHOD__,
581  function () {
583  // Check config in case of JobRunner and unit tests
584  if ( $wgCommandLineMode ) {
586  }
587  }
588  );
589  // Check for other windows to run them. A script may read or do a few writes
590  // to the master but mostly be writing to something else, like a file store.
591  $lbFactory->getMainLB()->setTransactionListener(
592  __METHOD__,
593  function ( $trigger ) {
595  // Check config in case of JobRunner and unit tests
596  if ( $wgCommandLineMode && $trigger === IDatabase::TRIGGER_COMMIT ) {
598  }
599  }
600  );
601  }
602 
610  public function runChild( $maintClass, $classFile = null ) {
611  // Make sure the class is loaded first
612  if ( !class_exists( $maintClass ) ) {
613  if ( $classFile ) {
614  require_once $classFile;
615  }
616  if ( !class_exists( $maintClass ) ) {
617  $this->error( "Cannot spawn child: $maintClass" );
618  }
619  }
620 
624  $child = new $maintClass();
625  $child->loadParamsAndArgs( $this->mSelf, $this->mOptions, $this->mArgs );
626  if ( !is_null( $this->mDb ) ) {
627  $child->setDB( $this->mDb );
628  }
629 
630  return $child;
631  }
632 
636  public function setup() {
638 
639  # Abort if called from a web server
640  if ( isset( $_SERVER ) && isset( $_SERVER['REQUEST_METHOD'] ) ) {
641  $this->error( 'This script must be run from the command line', true );
642  }
643 
644  if ( $IP === null ) {
645  $this->error( "\$IP not set, aborting!\n" .
646  '(Did you forget to call parent::__construct() in your maintenance script?)', 1 );
647  }
648 
649  # Make sure we can handle script parameters
650  if ( !defined( 'HPHP_VERSION' ) && !ini_get( 'register_argc_argv' ) ) {
651  $this->error( 'Cannot get command line arguments, register_argc_argv is set to false', true );
652  }
653 
654  // Send PHP warnings and errors to stderr instead of stdout.
655  // This aids in diagnosing problems, while keeping messages
656  // out of redirected output.
657  if ( ini_get( 'display_errors' ) ) {
658  ini_set( 'display_errors', 'stderr' );
659  }
660 
661  $this->loadParamsAndArgs();
662  $this->maybeHelp();
663 
664  # Set the memory limit
665  # Note we need to set it again later in cache LocalSettings changed it
666  $this->adjustMemoryLimit();
667 
668  # Set max execution time to 0 (no limit). PHP.net says that
669  # "When running PHP from the command line the default setting is 0."
670  # But sometimes this doesn't seem to be the case.
671  ini_set( 'max_execution_time', 0 );
672 
673  $wgRequestTime = microtime( true );
674 
675  # Define us as being in MediaWiki
676  define( 'MEDIAWIKI', true );
677 
678  $wgCommandLineMode = true;
679 
680  # Turn off output buffering if it's on
681  while ( ob_get_level() > 0 ) {
682  ob_end_flush();
683  }
684 
685  $this->validateParamsAndArgs();
686  }
687 
697  public function memoryLimit() {
698  $limit = $this->getOption( 'memory-limit', 'max' );
699  $limit = trim( $limit, "\" '" ); // trim quotes in case someone misunderstood
700  return $limit;
701  }
702 
706  protected function adjustMemoryLimit() {
707  $limit = $this->memoryLimit();
708  if ( $limit == 'max' ) {
709  $limit = -1; // no memory limit
710  }
711  if ( $limit != 'default' ) {
712  ini_set( 'memory_limit', $limit );
713  }
714  }
715 
719  protected function activateProfiler() {
720  global $wgProfiler, $wgProfileLimit, $wgTrxProfilerLimits;
721 
722  $output = $this->getOption( 'profiler' );
723  if ( !$output ) {
724  return;
725  }
726 
727  if ( is_array( $wgProfiler ) && isset( $wgProfiler['class'] ) ) {
728  $class = $wgProfiler['class'];
730  $profiler = new $class(
731  [ 'sampling' => 1, 'output' => [ $output ] ]
732  + $wgProfiler
733  + [ 'threshold' => $wgProfileLimit ]
734  );
735  $profiler->setTemplated( true );
736  Profiler::replaceStubInstance( $profiler );
737  }
738 
739  $trxProfiler = Profiler::instance()->getTransactionProfiler();
740  $trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
741  $trxProfiler->setExpectations( $wgTrxProfilerLimits['Maintenance'], __METHOD__ );
742  }
743 
747  public function clearParamsAndArgs() {
748  $this->mOptions = [];
749  $this->mArgs = [];
750  $this->mInputLoaded = false;
751  }
752 
760  public function loadWithArgv( $argv ) {
761  $options = [];
762  $args = [];
763  $this->orderedOptions = [];
764 
765  # Parse arguments
766  for ( $arg = reset( $argv ); $arg !== false; $arg = next( $argv ) ) {
767  if ( $arg == '--' ) {
768  # End of options, remainder should be considered arguments
769  $arg = next( $argv );
770  while ( $arg !== false ) {
771  $args[] = $arg;
772  $arg = next( $argv );
773  }
774  break;
775  } elseif ( substr( $arg, 0, 2 ) == '--' ) {
776  # Long options
777  $option = substr( $arg, 2 );
778  if ( isset( $this->mParams[$option] ) && $this->mParams[$option]['withArg'] ) {
779  $param = next( $argv );
780  if ( $param === false ) {
781  $this->error( "\nERROR: $option parameter needs a value after it\n" );
782  $this->maybeHelp( true );
783  }
784 
785  $this->setParam( $options, $option, $param );
786  } else {
787  $bits = explode( '=', $option, 2 );
788  if ( count( $bits ) > 1 ) {
789  $option = $bits[0];
790  $param = $bits[1];
791  } else {
792  $param = 1;
793  }
794 
795  $this->setParam( $options, $option, $param );
796  }
797  } elseif ( $arg == '-' ) {
798  # Lonely "-", often used to indicate stdin or stdout.
799  $args[] = $arg;
800  } elseif ( substr( $arg, 0, 1 ) == '-' ) {
801  # Short options
802  $argLength = strlen( $arg );
803  for ( $p = 1; $p < $argLength; $p++ ) {
804  $option = $arg[$p];
805  if ( !isset( $this->mParams[$option] ) && isset( $this->mShortParamsMap[$option] ) ) {
806  $option = $this->mShortParamsMap[$option];
807  }
808 
809  if ( isset( $this->mParams[$option]['withArg'] ) && $this->mParams[$option]['withArg'] ) {
810  $param = next( $argv );
811  if ( $param === false ) {
812  $this->error( "\nERROR: $option parameter needs a value after it\n" );
813  $this->maybeHelp( true );
814  }
815  $this->setParam( $options, $option, $param );
816  } else {
817  $this->setParam( $options, $option, 1 );
818  }
819  }
820  } else {
821  $args[] = $arg;
822  }
823  }
824 
825  $this->mOptions = $options;
826  $this->mArgs = $args;
827  $this->loadSpecialVars();
828  $this->mInputLoaded = true;
829  }
830 
843  private function setParam( &$options, $option, $value ) {
844  $this->orderedOptions[] = [ $option, $value ];
845 
846  if ( isset( $this->mParams[$option] ) ) {
847  $multi = $this->mParams[$option]['multiOccurrence'];
848  } else {
849  $multi = false;
850  }
851  $exists = array_key_exists( $option, $options );
852  if ( $multi && $exists ) {
853  $options[$option][] = $value;
854  } elseif ( $multi ) {
855  $options[$option] = [ $value ];
856  } elseif ( !$exists ) {
857  $options[$option] = $value;
858  } else {
859  $this->error( "\nERROR: $option parameter given twice\n" );
860  $this->maybeHelp( true );
861  }
862  }
863 
873  public function loadParamsAndArgs( $self = null, $opts = null, $args = null ) {
874  # If we were given opts or args, set those and return early
875  if ( $self ) {
876  $this->mSelf = $self;
877  $this->mInputLoaded = true;
878  }
879  if ( $opts ) {
880  $this->mOptions = $opts;
881  $this->mInputLoaded = true;
882  }
883  if ( $args ) {
884  $this->mArgs = $args;
885  $this->mInputLoaded = true;
886  }
887 
888  # If we've already loaded input (either by user values or from $argv)
889  # skip on loading it again. The array_shift() will corrupt values if
890  # it's run again and again
891  if ( $this->mInputLoaded ) {
892  $this->loadSpecialVars();
893 
894  return;
895  }
896 
897  global $argv;
898  $this->mSelf = $argv[0];
899  $this->loadWithArgv( array_slice( $argv, 1 ) );
900  }
901 
905  protected function validateParamsAndArgs() {
906  $die = false;
907  # Check to make sure we've got all the required options
908  foreach ( $this->mParams as $opt => $info ) {
909  if ( $info['require'] && !$this->hasOption( $opt ) ) {
910  $this->error( "Param $opt required!" );
911  $die = true;
912  }
913  }
914  # Check arg list too
915  foreach ( $this->mArgList as $k => $info ) {
916  if ( $info['require'] && !$this->hasArg( $k ) ) {
917  $this->error( 'Argument <' . $info['name'] . '> required!' );
918  $die = true;
919  }
920  }
921 
922  if ( $die ) {
923  $this->maybeHelp( true );
924  }
925  }
926 
930  protected function loadSpecialVars() {
931  if ( $this->hasOption( 'dbuser' ) ) {
932  $this->mDbUser = $this->getOption( 'dbuser' );
933  }
934  if ( $this->hasOption( 'dbpass' ) ) {
935  $this->mDbPass = $this->getOption( 'dbpass' );
936  }
937  if ( $this->hasOption( 'quiet' ) ) {
938  $this->mQuiet = true;
939  }
940  if ( $this->hasOption( 'batch-size' ) ) {
941  $this->mBatchSize = intval( $this->getOption( 'batch-size' ) );
942  }
943  }
944 
949  protected function maybeHelp( $force = false ) {
950  if ( !$force && !$this->hasOption( 'help' ) ) {
951  return;
952  }
953 
954  $screenWidth = 80; // TODO: Calculate this!
955  $tab = " ";
956  $descWidth = $screenWidth - ( 2 * strlen( $tab ) );
957 
958  ksort( $this->mParams );
959  $this->mQuiet = false;
960 
961  // Description ...
962  if ( $this->mDescription ) {
963  $this->output( "\n" . wordwrap( $this->mDescription, $screenWidth ) . "\n" );
964  }
965  $output = "\nUsage: php " . basename( $this->mSelf );
966 
967  // ... append parameters ...
968  if ( $this->mParams ) {
969  $output .= " [--" . implode( array_keys( $this->mParams ), "|--" ) . "]";
970  }
971 
972  // ... and append arguments.
973  if ( $this->mArgList ) {
974  $output .= ' ';
975  foreach ( $this->mArgList as $k => $arg ) {
976  if ( $arg['require'] ) {
977  $output .= '<' . $arg['name'] . '>';
978  } else {
979  $output .= '[' . $arg['name'] . ']';
980  }
981  if ( $k < count( $this->mArgList ) - 1 ) {
982  $output .= ' ';
983  }
984  }
985  }
986  $this->output( "$output\n\n" );
987 
988  # TODO abstract some repetitive code below
989 
990  // Generic parameters
991  $this->output( "Generic maintenance parameters:\n" );
992  foreach ( $this->mGenericParameters as $par => $info ) {
993  if ( $info['shortName'] !== false ) {
994  $par .= " (-{$info['shortName']})";
995  }
996  $this->output(
997  wordwrap( "$tab--$par: " . $info['desc'], $descWidth,
998  "\n$tab$tab" ) . "\n"
999  );
1000  }
1001  $this->output( "\n" );
1002 
1003  $scriptDependantParams = $this->mDependantParameters;
1004  if ( count( $scriptDependantParams ) > 0 ) {
1005  $this->output( "Script dependant parameters:\n" );
1006  // Parameters description
1007  foreach ( $scriptDependantParams as $par => $info ) {
1008  if ( $info['shortName'] !== false ) {
1009  $par .= " (-{$info['shortName']})";
1010  }
1011  $this->output(
1012  wordwrap( "$tab--$par: " . $info['desc'], $descWidth,
1013  "\n$tab$tab" ) . "\n"
1014  );
1015  }
1016  $this->output( "\n" );
1017  }
1018 
1019  // Script specific parameters not defined on construction by
1020  // Maintenance::addDefaultParams()
1021  $scriptSpecificParams = array_diff_key(
1022  # all script parameters:
1023  $this->mParams,
1024  # remove the Maintenance default parameters:
1025  $this->mGenericParameters,
1026  $this->mDependantParameters
1027  );
1028  if ( count( $scriptSpecificParams ) > 0 ) {
1029  $this->output( "Script specific parameters:\n" );
1030  // Parameters description
1031  foreach ( $scriptSpecificParams as $par => $info ) {
1032  if ( $info['shortName'] !== false ) {
1033  $par .= " (-{$info['shortName']})";
1034  }
1035  $this->output(
1036  wordwrap( "$tab--$par: " . $info['desc'], $descWidth,
1037  "\n$tab$tab" ) . "\n"
1038  );
1039  }
1040  $this->output( "\n" );
1041  }
1042 
1043  // Print arguments
1044  if ( count( $this->mArgList ) > 0 ) {
1045  $this->output( "Arguments:\n" );
1046  // Arguments description
1047  foreach ( $this->mArgList as $info ) {
1048  $openChar = $info['require'] ? '<' : '[';
1049  $closeChar = $info['require'] ? '>' : ']';
1050  $this->output(
1051  wordwrap( "$tab$openChar" . $info['name'] . "$closeChar: " .
1052  $info['desc'], $descWidth, "\n$tab$tab" ) . "\n"
1053  );
1054  }
1055  $this->output( "\n" );
1056  }
1057 
1058  die( 1 );
1059  }
1060 
1064  public function finalSetup() {
1065  global $wgCommandLineMode, $wgShowSQLErrors, $wgServer;
1068 
1069  # Turn off output buffering again, it might have been turned on in the settings files
1070  if ( ob_get_level() ) {
1071  ob_end_flush();
1072  }
1073  # Same with these
1074  $wgCommandLineMode = true;
1075 
1076  # Override $wgServer
1077  if ( $this->hasOption( 'server' ) ) {
1078  $wgServer = $this->getOption( 'server', $wgServer );
1079  }
1080 
1081  # If these were passed, use them
1082  if ( $this->mDbUser ) {
1084  }
1085  if ( $this->mDbPass ) {
1087  }
1088 
1089  if ( $this->getDbType() == self::DB_ADMIN && isset( $wgDBadminuser ) ) {
1092 
1093  if ( $wgDBservers ) {
1097  foreach ( $wgDBservers as $i => $server ) {
1098  $wgDBservers[$i]['user'] = $wgDBuser;
1099  $wgDBservers[$i]['password'] = $wgDBpassword;
1100  }
1101  }
1102  if ( isset( $wgLBFactoryConf['serverTemplate'] ) ) {
1103  $wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
1104  $wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
1105  }
1106  MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->destroy();
1107  }
1108 
1109  // Per-script profiling; useful for debugging
1110  $this->activateProfiler();
1111 
1112  $this->afterFinalSetup();
1113 
1114  $wgShowSQLErrors = true;
1115 
1116  MediaWiki\suppressWarnings();
1117  set_time_limit( 0 );
1118  MediaWiki\restoreWarnings();
1119 
1120  $this->adjustMemoryLimit();
1121  }
1122 
1126  protected function afterFinalSetup() {
1127  if ( defined( 'MW_CMDLINE_CALLBACK' ) ) {
1128  call_user_func( MW_CMDLINE_CALLBACK );
1129  }
1130  }
1131 
1136  public function globals() {
1137  if ( $this->hasOption( 'globals' ) ) {
1138  print_r( $GLOBALS );
1139  }
1140  }
1141 
1146  public function loadSettings() {
1148 
1149  if ( isset( $this->mOptions['conf'] ) ) {
1150  $settingsFile = $this->mOptions['conf'];
1151  } elseif ( defined( "MW_CONFIG_FILE" ) ) {
1152  $settingsFile = MW_CONFIG_FILE;
1153  } else {
1154  $settingsFile = "$IP/LocalSettings.php";
1155  }
1156  if ( isset( $this->mOptions['wiki'] ) ) {
1157  $bits = explode( '-', $this->mOptions['wiki'] );
1158  if ( count( $bits ) == 1 ) {
1159  $bits[] = '';
1160  }
1161  define( 'MW_DB', $bits[0] );
1162  define( 'MW_PREFIX', $bits[1] );
1163  }
1164 
1165  if ( !is_readable( $settingsFile ) ) {
1166  $this->error( "A copy of your installation's LocalSettings.php\n" .
1167  "must exist and be readable in the source directory.\n" .
1168  "Use --conf to specify it.", true );
1169  }
1170  $wgCommandLineMode = true;
1171 
1172  return $settingsFile;
1173  }
1174 
1180  public function purgeRedundantText( $delete = true ) {
1181  # Data should come off the master, wrapped in a transaction
1182  $dbw = $this->getDB( DB_MASTER );
1183  $this->beginTransaction( $dbw, __METHOD__ );
1184 
1185  # Get "active" text records from the revisions table
1186  $cur = [];
1187  $this->output( 'Searching for active text records in revisions table...' );
1188  $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
1189  foreach ( $res as $row ) {
1190  $cur[] = $row->rev_text_id;
1191  }
1192  $this->output( "done.\n" );
1193 
1194  # Get "active" text records from the archive table
1195  $this->output( 'Searching for active text records in archive table...' );
1196  $res = $dbw->select( 'archive', 'ar_text_id', [], __METHOD__, [ 'DISTINCT' ] );
1197  foreach ( $res as $row ) {
1198  # old pre-MW 1.5 records can have null ar_text_id's.
1199  if ( $row->ar_text_id !== null ) {
1200  $cur[] = $row->ar_text_id;
1201  }
1202  }
1203  $this->output( "done.\n" );
1204 
1205  # Get the IDs of all text records not in these sets
1206  $this->output( 'Searching for inactive text records...' );
1207  $cond = 'old_id NOT IN ( ' . $dbw->makeList( $cur ) . ' )';
1208  $res = $dbw->select( 'text', 'old_id', [ $cond ], __METHOD__, [ 'DISTINCT' ] );
1209  $old = [];
1210  foreach ( $res as $row ) {
1211  $old[] = $row->old_id;
1212  }
1213  $this->output( "done.\n" );
1214 
1215  # Inform the user of what we're going to do
1216  $count = count( $old );
1217  $this->output( "$count inactive items found.\n" );
1218 
1219  # Delete as appropriate
1220  if ( $delete && $count ) {
1221  $this->output( 'Deleting...' );
1222  $dbw->delete( 'text', [ 'old_id' => $old ], __METHOD__ );
1223  $this->output( "done.\n" );
1224  }
1225 
1226  # Done
1227  $this->commitTransaction( $dbw, __METHOD__ );
1228  }
1229 
1234  protected function getDir() {
1235  return __DIR__;
1236  }
1237 
1248  protected function getDB( $db, $groups = [], $wiki = false ) {
1249  if ( is_null( $this->mDb ) ) {
1250  return wfGetDB( $db, $groups, $wiki );
1251  } else {
1252  return $this->mDb;
1253  }
1254  }
1255 
1261  public function setDB( IDatabase $db ) {
1262  $this->mDb = $db;
1263  }
1264 
1275  protected function beginTransaction( IDatabase $dbw, $fname ) {
1276  $dbw->begin( $fname );
1277  }
1278 
1290  protected function commitTransaction( IDatabase $dbw, $fname ) {
1291  $dbw->commit( $fname );
1292  try {
1293  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
1294  $lbFactory->waitForReplication(
1295  [ 'timeout' => 30, 'ifWritesSince' => $this->lastReplicationWait ]
1296  );
1297  $this->lastReplicationWait = microtime( true );
1298 
1299  return true;
1300  } catch ( DBReplicationWaitError $e ) {
1301  return false;
1302  }
1303  }
1304 
1315  protected function rollbackTransaction( IDatabase $dbw, $fname ) {
1316  $dbw->rollback( $fname );
1317  }
1318 
1323  private function lockSearchindex( $db ) {
1324  $write = [ 'searchindex' ];
1325  $read = [
1326  'page',
1327  'revision',
1328  'text',
1329  'interwiki',
1330  'l10n_cache',
1331  'user',
1332  'page_restrictions'
1333  ];
1334  $db->lockTables( $read, $write, __CLASS__ . '::' . __METHOD__ );
1335  }
1336 
1341  private function unlockSearchindex( $db ) {
1342  $db->unlockTables( __CLASS__ . '::' . __METHOD__ );
1343  }
1344 
1350  private function relockSearchindex( $db ) {
1351  $this->unlockSearchindex( $db );
1352  $this->lockSearchindex( $db );
1353  }
1354 
1362  public function updateSearchIndex( $maxLockTime, $callback, $dbw, $results ) {
1363  $lockTime = time();
1364 
1365  # Lock searchindex
1366  if ( $maxLockTime ) {
1367  $this->output( " --- Waiting for lock ---" );
1368  $this->lockSearchindex( $dbw );
1369  $lockTime = time();
1370  $this->output( "\n" );
1371  }
1372 
1373  # Loop through the results and do a search update
1374  foreach ( $results as $row ) {
1375  # Allow reads to be processed
1376  if ( $maxLockTime && time() > $lockTime + $maxLockTime ) {
1377  $this->output( " --- Relocking ---" );
1378  $this->relockSearchindex( $dbw );
1379  $lockTime = time();
1380  $this->output( "\n" );
1381  }
1382  call_user_func( $callback, $dbw, $row );
1383  }
1384 
1385  # Unlock searchindex
1386  if ( $maxLockTime ) {
1387  $this->output( " --- Unlocking --" );
1388  $this->unlockSearchindex( $dbw );
1389  $this->output( "\n" );
1390  }
1391  }
1392 
1399  public function updateSearchIndexForPage( $dbw, $pageId ) {
1400  // Get current revision
1401  $rev = Revision::loadFromPageId( $dbw, $pageId );
1402  $title = null;
1403  if ( $rev ) {
1404  $titleObj = $rev->getTitle();
1405  $title = $titleObj->getPrefixedDBkey();
1406  $this->output( "$title..." );
1407  # Update searchindex
1408  $u = new SearchUpdate( $pageId, $titleObj->getText(), $rev->getContent() );
1409  $u->doUpdate();
1410  $this->output( "\n" );
1411  }
1412 
1413  return $title;
1414  }
1415 
1424  public static function posix_isatty( $fd ) {
1425  if ( !function_exists( 'posix_isatty' ) ) {
1426  return !$fd;
1427  } else {
1428  return posix_isatty( $fd );
1429  }
1430  }
1431 
1437  public static function readconsole( $prompt = '> ' ) {
1438  static $isatty = null;
1439  if ( is_null( $isatty ) ) {
1440  $isatty = self::posix_isatty( 0 /*STDIN*/ );
1441  }
1442 
1443  if ( $isatty && function_exists( 'readline' ) ) {
1444  $resp = readline( $prompt );
1445  if ( $resp === null ) {
1446  // Workaround for https://github.com/facebook/hhvm/issues/4776
1447  return false;
1448  } else {
1449  return $resp;
1450  }
1451  } else {
1452  if ( $isatty ) {
1453  $st = self::readlineEmulation( $prompt );
1454  } else {
1455  if ( feof( STDIN ) ) {
1456  $st = false;
1457  } else {
1458  $st = fgets( STDIN, 1024 );
1459  }
1460  }
1461  if ( $st === false ) {
1462  return false;
1463  }
1464  $resp = trim( $st );
1465 
1466  return $resp;
1467  }
1468  }
1469 
1475  private static function readlineEmulation( $prompt ) {
1476  $bash = Installer::locateExecutableInDefaultPaths( [ 'bash' ] );
1477  if ( !wfIsWindows() && $bash ) {
1478  $retval = false;
1479  $encPrompt = wfEscapeShellArg( $prompt );
1480  $command = "read -er -p $encPrompt && echo \"\$REPLY\"";
1481  $encCommand = wfEscapeShellArg( $command );
1482  $line = wfShellExec( "$bash -c $encCommand", $retval, [], [ 'walltime' => 0 ] );
1483 
1484  if ( $retval == 0 ) {
1485  return $line;
1486  } elseif ( $retval == 127 ) {
1487  // Couldn't execute bash even though we thought we saw it.
1488  // Shell probably spit out an error message, sorry :(
1489  // Fall through to fgets()...
1490  } else {
1491  // EOF/ctrl+D
1492  return false;
1493  }
1494  }
1495 
1496  // Fallback... we'll have no editing controls, EWWW
1497  if ( feof( STDIN ) ) {
1498  return false;
1499  }
1500  print $prompt;
1501 
1502  return fgets( STDIN, 1024 );
1503  }
1504 
1509  public static function requireTestsAutoloader() {
1510  require_once __DIR__ . '/../tests/common/TestsAutoLoader.php';
1511  }
1512 }
1513 
1518  protected $mSelf = "FakeMaintenanceScript";
1519 
1520  public function execute() {
1521  return;
1522  }
1523 }
1524 
1529 abstract class LoggedUpdateMaintenance extends Maintenance {
1530  public function __construct() {
1531  parent::__construct();
1532  $this->addOption( 'force', 'Run the update even if it was completed already' );
1533  $this->setBatchSize( 200 );
1534  }
1535 
1536  public function execute() {
1537  $db = $this->getDB( DB_MASTER );
1538  $key = $this->getUpdateKey();
1539 
1540  if ( !$this->hasOption( 'force' )
1541  && $db->selectRow( 'updatelog', '1', [ 'ul_key' => $key ], __METHOD__ )
1542  ) {
1543  $this->output( "..." . $this->updateSkippedMessage() . "\n" );
1544 
1545  return true;
1546  }
1547 
1548  if ( !$this->doDBUpdates() ) {
1549  return false;
1550  }
1551 
1552  if ( $db->insert( 'updatelog', [ 'ul_key' => $key ], __METHOD__, 'IGNORE' ) ) {
1553  return true;
1554  } else {
1555  $this->output( $this->updatelogFailedMessage() . "\n" );
1556 
1557  return false;
1558  }
1559  }
1560 
1565  protected function updateSkippedMessage() {
1566  $key = $this->getUpdateKey();
1567 
1568  return "Update '{$key}' already logged as completed.";
1569  }
1570 
1575  protected function updatelogFailedMessage() {
1576  $key = $this->getUpdateKey();
1577 
1578  return "Unable to log update '{$key}' as completed.";
1579  }
1580 
1586  abstract protected function doDBUpdates();
1587 
1592  abstract protected function getUpdateKey();
1593 }
FakeMaintenance\$mSelf
$mSelf
Definition: Maintenance.php:1518
RUN_MAINTENANCE_IF_MAIN
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:34
Maintenance\$mBatchSize
int $mBatchSize
Batch size.
Definition: Maintenance.php:98
LoggedUpdateMaintenance\__construct
__construct()
Default constructor.
Definition: Maintenance.php:1530
Maintenance\setParam
setParam(&$options, $option, $value)
Helper function used solely by loadParamsAndArgs to prevent code duplication.
Definition: Maintenance.php:843
Maintenance\$mDb
Database $mDb
Used by getDB() / setDB()
Definition: Maintenance.php:109
use
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
Definition: APACHE-LICENSE-2.0.txt:3
Maintenance\$mShortParamsMap
$mShortParamsMap
Definition: Maintenance.php:68
Maintenance\getStdin
getStdin( $len=null)
Return input from stdin.
Definition: Maintenance.php:341
Profiler\replaceStubInstance
static replaceStubInstance(Profiler $profiler)
Replace the current profiler with $profiler if no non-stub profiler is set.
Definition: Profiler.php:96
Profiler\instance
static instance()
Singleton.
Definition: Profiler.php:61
array
the array() calling protocol came about after MediaWiki 1.4rc1.
Maintenance\getDbType
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
Definition: Maintenance.php:454
Maintenance\maybeHelp
maybeHelp( $force=false)
Maybe show the help.
Definition: Maintenance.php:949
Maintenance\$mDbPass
$mDbPass
Definition: Maintenance.php:84
Maintenance\addDescription
addDescription( $text)
Set the description text.
Definition: Maintenance.php:282
Maintenance\setup
setup()
Do some sanity checking and basic setup.
Definition: Maintenance.php:636
Maintenance\$requiredExtensions
array $requiredExtensions
Definition: Maintenance.php:131
Maintenance\runChild
runChild( $maintClass, $classFile=null)
Run a child maintenance script.
Definition: Maintenance.php:610
Maintenance\readconsole
static readconsole( $prompt='> ')
Prompt the console for input.
Definition: Maintenance.php:1437
DBReplicationWaitError
Exception class for replica DB wait timeouts.
Definition: DBReplicationWaitError.php:26
$out
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:805
Maintenance\loadParamsAndArgs
loadParamsAndArgs( $self=null, $opts=null, $args=null)
Process command line arguments $mOptions becomes an array with keys set to the option names $mArgs be...
Definition: Maintenance.php:873
$fname
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined.
Definition: Setup.php:36
Maintenance\relockSearchindex
relockSearchindex( $db)
Unlock and lock again Since the lock is low-priority, queued reads will be able to complete.
Definition: Maintenance.php:1350
Maintenance\getName
getName()
Get the script's name.
Definition: Maintenance.php:331
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:956
wfHostname
wfHostname()
Fetch server name for use in error reporting etc.
Definition: GlobalFunctions.php:1447
$wgLBFactoryConf
$wgLBFactoryConf
Load balancer factory configuration To set up a multi-master wiki farm, set the class here to somethi...
Definition: DefaultSettings.php:1956
$s
$s
Definition: mergeMessageFileList.php:198
Maintenance\hasArg
hasArg( $argId=0)
Does a given argument exist?
Definition: Maintenance.php:291
Maintenance\setDB
setDB(IDatabase $db)
Sets database object to be returned by getDB().
Definition: Maintenance.php:1261
$res
$res
Definition: database.txt:21
Maintenance
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: maintenance.txt:39
LBFactory
An interface for generating database load balancers.
Definition: LBFactory.php:31
Maintenance\setConfig
setConfig(Config $config)
Definition: Maintenance.php:512
$lbFactory
$lbFactory
Definition: doMaintenance.php:117
$maintClass
$maintClass
Definition: Maintenance.php:37
$wgDBpassword
$wgDBpassword
Database user's password.
Definition: DefaultSettings.php:1765
Maintenance\$lastChannel
$lastChannel
Definition: Maintenance.php:401
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
Maintenance\loadWithArgv
loadWithArgv( $argv)
Load params and arguments from a given array of command-line arguments.
Definition: Maintenance.php:760
Maintenance\checkRequiredExtensions
checkRequiredExtensions()
Verify that the required extensions are installed.
Definition: Maintenance.php:534
Installer\locateExecutableInDefaultPaths
static locateExecutableInDefaultPaths( $names, $versionInfo=false)
Same as locateExecutable(), but checks in getPossibleBinPaths() by default.
Definition: Installer.php:1235
Maintenance\finalSetup
finalSetup()
Handle some last-minute setup here.
Definition: Maintenance.php:1064
Maintenance\rollbackTransaction
rollbackTransaction(IDatabase $dbw, $fname)
Rollback the transcation on a DB handle.
Definition: Maintenance.php:1315
wfEntryPointCheck
wfEntryPointCheck( $entryPoint)
Check php version and that external dependencies are installed, and display an informative error if e...
Definition: PHPVersionCheck.php:32
Maintenance\$mDescription
$mDescription
Definition: Maintenance.php:87
Maintenance\beginTransaction
beginTransaction(IDatabase $dbw, $fname)
Begin a transcation on a DB.
Definition: Maintenance.php:1275
Maintenance\afterFinalSetup
afterFinalSetup()
Execute a callback function at the end of initialisation.
Definition: Maintenance.php:1126
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:78
$wgDBadminuser
$wgDBadminuser
Separate username for maintenance tasks.
Definition: DefaultSettings.php:1795
Maintenance\unlockSearchindex
unlockSearchindex( $db)
Unlock the tables.
Definition: Maintenance.php:1341
Maintenance\clearParamsAndArgs
clearParamsAndArgs()
Clear all params and arguments.
Definition: Maintenance.php:747
Config
Interface for configuration instances.
Definition: Config.php:28
$wgDBservers
$wgDBservers
Database load balancer This is a two-dimensional array, an array of server info structures Fields are...
Definition: DefaultSettings.php:1944
Maintenance\$mSelf
$mSelf
Definition: Maintenance.php:80
Maintenance\updateSearchIndex
updateSearchIndex( $maxLockTime, $callback, $dbw, $results)
Perform a search index update with locking.
Definition: Maintenance.php:1362
Maintenance\$mArgs
$mArgs
Definition: Maintenance.php:77
Maintenance\loadSpecialVars
loadSpecialVars()
Handle the special variables that are global to all scripts.
Definition: Maintenance.php:930
Maintenance\getConfig
getConfig()
Definition: Maintenance.php:500
LoggedUpdateMaintenance
Class for scripts that perform database maintenance and want to log the update in updatelog so we can...
Definition: Maintenance.php:1529
Maintenance\$atLineStart
$atLineStart
Definition: Maintenance.php:400
$wgCommandLineMode
global $wgCommandLineMode
Definition: Setup.php:495
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3073
Maintenance\$lastReplicationWait
float $lastReplicationWait
UNIX timestamp.
Definition: Maintenance.php:112
$count
$count
Definition: importImages.php:141
Revision\loadFromPageId
static loadFromPageId( $db, $pageid, $id=0)
Load either the current, or a specified, revision that's attached to a given page.
Definition: Revision.php:256
Maintenance\addOption
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
Definition: Maintenance.php:210
Maintenance\$mDbUser
$mDbUser
Definition: Maintenance.php:84
Maintenance\requireExtension
requireExtension( $name)
Indicate that the specified extension must be loaded before the script can run.
Definition: Maintenance.php:525
ConfigFactory\getDefaultInstance
static getDefaultInstance()
Definition: ConfigFactory.php:51
Maintenance\$orderedOptions
array $orderedOptions
Used to read the options in the order they were passed.
Definition: Maintenance.php:144
Maintenance\globals
globals()
Potentially debug globals.
Definition: Maintenance.php:1136
LoggedUpdateMaintenance\updatelogFailedMessage
updatelogFailedMessage()
Message to show that the update log was unable to log the completion of this update.
Definition: Maintenance.php:1575
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
FakeMaintenance
Fake maintenance wrapper, mostly used for the web installer/updater.
Definition: Maintenance.php:1517
DB_MASTER
const DB_MASTER
Definition: defines.php:23
Maintenance\addDefaultParams
addDefaultParams()
Add the default parameters to the scripts.
Definition: Maintenance.php:461
Maintenance\readlineEmulation
static readlineEmulation( $prompt)
Emulate readline()
Definition: Maintenance.php:1475
Maintenance\DB_ADMIN
const DB_ADMIN
Definition: Maintenance.php:59
Maintenance\$mGenericParameters
$mGenericParameters
Definition: Maintenance.php:101
Maintenance\deleteOption
deleteOption( $name)
Remove an option.
Definition: Maintenance.php:274
IDatabase\commit
commit( $fname=__METHOD__, $flush='')
Commits a transaction previously started using begin().
Maintenance\shouldExecute
static shouldExecute()
Should we execute the maintenance script, or just allow it to be included as a standalone class?...
Definition: Maintenance.php:168
$command
$command
Definition: cdb.php:65
$line
$line
Definition: cdb.php:59
LoggedUpdateMaintenance\execute
execute()
Do the actual work.
Definition: Maintenance.php:1536
Maintenance\DB_STD
const DB_STD
Definition: Maintenance.php:58
Maintenance\updateSearchIndexForPage
updateSearchIndexForPage( $dbw, $pageId)
Update the searchindex table for a given pageid.
Definition: Maintenance.php:1399
$value
$value
Definition: styleTest.css.php:45
$options
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1049
Maintenance\$mQuiet
$mQuiet
Definition: Maintenance.php:83
Maintenance\isQuiet
isQuiet()
Definition: Maintenance.php:358
Maintenance\activateProfiler
activateProfiler()
Activate the profiler (assuming $wgProfiler is set)
Definition: Maintenance.php:719
DeferredUpdates\tryOpportunisticExecute
static tryOpportunisticExecute( $mode='run')
Run all deferred updates immediately if there are no DB writes active.
Definition: DeferredUpdates.php:279
Database
Relational database abstraction object.
Definition: Database.php:36
wfIsWindows
wfIsWindows()
Check if the operating system is Windows.
Definition: GlobalFunctions.php:2046
Maintenance\$mParams
$mParams
Definition: Maintenance.php:65
$wgServer
$wgServer
URL of the server.
Definition: DefaultSettings.php:109
wfEscapeShellArg
wfEscapeShellArg()
Version of escapeshellarg() that works better on Windows.
Definition: GlobalFunctions.php:2208
Maintenance\requireTestsAutoloader
static requireTestsAutoloader()
Call this to set up the autoloader to allow classes to be used from the tests directory.
Definition: Maintenance.php:1509
Maintenance\posix_isatty
static posix_isatty( $fd)
Wrapper for posix_isatty() We default as considering stdin a tty (for nice readline methods) but trea...
Definition: Maintenance.php:1424
LoggedUpdateMaintenance\updateSkippedMessage
updateSkippedMessage()
Message to show that the update was done already and was just skipped.
Definition: Maintenance.php:1565
Maintenance\$mDependantParameters
$mDependantParameters
Definition: Maintenance.php:103
Maintenance\commitTransaction
commitTransaction(IDatabase $dbw, $fname)
Commit the transcation on a DB handle and wait for replica DBs to catch up.
Definition: Maintenance.php:1290
Maintenance\validateParamsAndArgs
validateParamsAndArgs()
Run some validation checks on the params, etc.
Definition: Maintenance.php:905
Maintenance\$config
Config $config
Accessible via getConfig()
Definition: Maintenance.php:125
Maintenance\cleanupChanneled
cleanupChanneled()
Clean up channeled output.
Definition: Maintenance.php:406
Maintenance\DB_NONE
const DB_NONE
Constants for DB access type.
Definition: Maintenance.php:57
Maintenance\loadSettings
loadSettings()
Generic setup for most installs.
Definition: Maintenance.php:1146
LoggedUpdateMaintenance\doDBUpdates
doDBUpdates()
Do the actual work.
IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:34
Maintenance\adjustMemoryLimit
adjustMemoryLimit()
Adjusts PHP's memory limit to better suit our needs, if needed.
Definition: Maintenance.php:706
Maintenance\setLBFactoryTriggers
static setLBFactoryTriggers(LBFactory $LBFactory)
Definition: Maintenance.php:576
LoggedUpdateMaintenance\getUpdateKey
getUpdateKey()
Get the update key name to go in the update log table.
Maintenance\purgeRedundantText
purgeRedundantText( $delete=true)
Support function for cleaning up redundant text records.
Definition: Maintenance.php:1180
$self
$self
Definition: doMaintenance.php:56
$rev
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1724
Maintenance\$fileHandle
resource $fileHandle
Used when creating separate schema files.
Definition: Maintenance.php:118
$args
if( $line===false) $args
Definition: cdb.php:64
Maintenance\$mInputLoaded
$mInputLoaded
Definition: Maintenance.php:90
Maintenance\getOption
getOption( $name, $default=null)
Get an option, or return the default.
Definition: Maintenance.php:245
Maintenance\STDIN_ALL
const STDIN_ALL
Definition: Maintenance.php:62
$wgRequestTime
float $wgRequestTime
Request start time as fractional seconds since epoch.
Definition: WebStart.php:43
$output
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object & $output
Definition: hooks.txt:1049
Maintenance\addArg
addArg( $arg, $description, $required=true)
Add some args that are needed.
Definition: Maintenance.php:262
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Maintenance\$mOptions
$mOptions
Definition: Maintenance.php:74
Maintenance\setAgentAndTriggers
setAgentAndTriggers()
Set triggers like when to try to run deferred updates.
Definition: Maintenance.php:556
$wgProfiler
$wgProfiler
Definition: WebStart.php:73
Maintenance\getDB
getDB( $db, $groups=[], $wiki=false)
Returns a database to be used by current maintenance script.
Definition: Maintenance.php:1248
LoggerFactory
MediaWiki Logger LoggerFactory implements a PSR[0] compatible message logging system Named Psr Log LoggerInterface instances can be obtained from the MediaWiki Logger LoggerFactory::getInstance() static method. MediaWiki\Logger\LoggerFactory expects a class implementing the MediaWiki\Logger\Spi interface to act as a factory for new Psr\Log\LoggerInterface instances. The "Spi" in MediaWiki\Logger\Spi stands for "service provider interface". An SPI is an API intended to be implemented or extended by a third party. This software design pattern is intended to enable framework extension and replaceable components. It is specifically used in the MediaWiki\Logger\LoggerFactory service to allow alternate PSR-3 logging implementations to be easily integrated with MediaWiki. The service provider interface allows the backend logging library to be implemented in multiple ways. The $wgMWLoggerDefaultSpi global provides the classname of the default MediaWiki\Logger\Spi implementation to be loaded at runtime. This can either be the name of a class implementing the MediaWiki\Logger\Spi with a zero argument const ructor or a callable that will return an MediaWiki\Logger\Spi instance. Alternately the MediaWiki\Logger\LoggerFactory MediaWiki Logger LoggerFactory
Definition: logger.txt:5
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
Maintenance\error
error( $err, $die=0)
Throw an error to the user.
Definition: Maintenance.php:387
Maintenance\output
output( $out, $channel=null)
Throw some output to the user.
Definition: Maintenance.php:368
$limit
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
Definition: hooks.txt:1049
Maintenance\$mArgList
$mArgList
Definition: Maintenance.php:71
Maintenance\getDir
getDir()
Get the maintenance directory.
Definition: Maintenance.php:1234
$wgDBuser
$wgDBuser
Database username.
Definition: DefaultSettings.php:1760
the
#define the
MediaWikiServices
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
Maintenance\hasOption
hasOption( $name)
Checks to see if a particular param exists.
Definition: Maintenance.php:231
Maintenance\getArg
getArg( $argId=0, $default=null)
Get an argument.
Definition: Maintenance.php:301
Maintenance::execute
public function execute()
Definition: maintenance.txt:45
$IP
$IP
Definition: WebStart.php:58
$wgDBadminpassword
$wgDBadminpassword
Separate password for maintenance tasks.
Definition: DefaultSettings.php:1800
Maintenance\outputChanneled
outputChanneled( $msg, $channel=null)
Message outputter with channeled message support.
Definition: Maintenance.php:421
IDatabase\begin
begin( $fname=__METHOD__, $mode=self::TRANSACTION_EXPLICIT)
Begin a transaction.
Maintenance\__construct
__construct()
Default constructor.
Definition: Maintenance.php:150
$retval
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account incomplete not yet checked for validity & $retval
Definition: hooks.txt:246
FakeMaintenance\execute
execute()
Do the actual work.
Definition: Maintenance.php:1520
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
Maintenance\lockSearchindex
lockSearchindex( $db)
Lock the search index.
Definition: Maintenance.php:1323
Maintenance\setBatchSize
setBatchSize( $s=0)
Set the batch size.
Definition: Maintenance.php:309
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2105
IDatabase\rollback
rollback( $fname=__METHOD__, $flush='')
Rollback a transaction previously started using begin().
Maintenance\memoryLimit
memoryLimit()
Normally we disable the memory_limit when running admin scripts.
Definition: Maintenance.php:697
wfShellExec
wfShellExec( $cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
Definition: GlobalFunctions.php:2310