diff options
Diffstat (limited to 'maintenance')
233 files changed, 7840 insertions, 2227 deletions
diff --git a/maintenance/Doxyfile b/maintenance/Doxyfile index e6862acd..ffc8c3b0 100644 --- a/maintenance/Doxyfile +++ b/maintenance/Doxyfile @@ -1,5 +1,7 @@ -# Doxyfile 1.7.5.1 +# Doxyfile 1.7.6.1 +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for MediaWiki. # # Some placeholders have been added for MediaWiki usage: # {{OUTPUT_DIRECTORY}} @@ -44,7 +46,7 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 +TAB_SIZE = 4 ALIASES = "type{1}=<b> \1 </b>:" \ "types{2}=<b> \1 </b> or <b> \2 </b>:" \ "types{3}=<b> \1 </b>, <b> \2 </b>, or <b> \3 </b>:" \ @@ -64,6 +66,7 @@ ALIASES = "type{1}=<b> \1 </b>:" \ "copyright=\note" \ "license=\note" \ "codeCoverageIgnore=" +TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO @@ -72,13 +75,14 @@ EXTENSION_MAPPING = BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = YES SUBGROUPING = YES INLINE_GROUPED_CLASSES = NO INLINE_SIMPLE_STRUCTS = NO TYPEDEF_HIDES_STRUCT = NO SYMBOL_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 1 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -176,6 +180,7 @@ FILE_PATTERNS = *.c \ *.txt \ README RECURSIVE = YES +EXCLUDE = {{EXCLUDE}} EXCLUDE_SYMLINKS = YES EXCLUDE_PATTERNS = LocalSettings.php AdminSettings.php StartProfiler.php .svn */.git/* {{EXCLUDE_PATTERNS}} EXCLUDE_SYMBOLS = @@ -216,7 +221,7 @@ HTML_STYLESHEET = HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 -HTML_COLORSTYLE_GAMMA = 80 +HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = YES HTML_ALIGN_MEMBERS = YES HTML_DYNAMIC_SECTIONS = NO @@ -358,7 +363,7 @@ MSCFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO +DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES DOT_CLEANUP = YES diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php index a13453df..30e93c90 100644 --- a/maintenance/Maintenance.php +++ b/maintenance/Maintenance.php @@ -23,7 +23,7 @@ // Make sure we're on PHP5.3.2 or better if ( !function_exists( 'version_compare' ) || version_compare( PHP_VERSION, '5.3.2' ) < 0 ) { // We need to use dirname( __FILE__ ) here cause __DIR__ is PHP5.3+ - require_once( dirname( __FILE__ ) . '/../includes/PHPVersionError.php' ); + require_once dirname( __FILE__ ) . '/../includes/PHPVersionError.php'; wfPHPVersionError( 'cli' ); } @@ -54,8 +54,8 @@ abstract class Maintenance { * Constants for DB access type * @see Maintenance::getDbType() */ - const DB_NONE = 0; - const DB_STD = 1; + const DB_NONE = 0; + const DB_STD = 1; const DB_ADMIN = 2; // Const for getStdin() @@ -153,7 +153,7 @@ abstract class Maintenance { return false; // last call should be to this function } $includeFuncs = array( 'require_once', 'require', 'include', 'include_once' ); - for( $i=1; $i < $count; $i++ ) { + for ( $i = 1; $i < $count; $i++ ) { if ( !in_array( $bt[$i]['function'], $includeFuncs ) ) { return false; // previous calls should all be "requires" } @@ -327,7 +327,7 @@ abstract class Maintenance { } if ( $channel === null ) { $this->cleanupChanneled(); - print( $out ); + print $out; } else { $out = preg_replace( '/\n\z/', '', $out ); $this->outputChanneled( $out, $channel ); @@ -426,9 +426,10 @@ abstract class Maintenance { $this->addOption( 'server', "The protocol and server name to use in URLs, e.g. " . "http://en.wikipedia.org. This is sometimes necessary because " . "server name detection may fail in command line scripts.", false, true ); + $this->addOption( 'profiler', 'Set to "text" or "trace" to show profiling output', false, true ); # Save generic options to display them separately in help - $this->mGenericParameters = $this->mParams ; + $this->mGenericParameters = $this->mParams; # Script dependant options: @@ -452,11 +453,11 @@ abstract class Maintenance { */ public function runChild( $maintClass, $classFile = null ) { // Make sure the class is loaded first - if ( !MWInit::classExists( $maintClass ) ) { + if ( !class_exists( $maintClass ) ) { if ( $classFile ) { - require_once( $classFile ); + require_once $classFile; } - if ( !MWInit::classExists( $maintClass ) ) { + if ( !class_exists( $maintClass ) ) { $this->error( "Cannot spawn child: $maintClass" ); } } @@ -476,15 +477,20 @@ abstract class Maintenance { * Do some sanity checking and basic setup */ public function setup() { - global $wgCommandLineMode, $wgRequestTime; + global $IP, $wgCommandLineMode, $wgRequestTime; # Abort if called from a web server if ( isset( $_SERVER ) && isset( $_SERVER['REQUEST_METHOD'] ) ) { $this->error( 'This script must be run from the command line', true ); } + if ( $IP === null ) { + $this->error( "\$IP not set, aborting!\n" . + '(Did you forget to call parent::__construct() in your maintenance script?)', 1 ); + } + # Make sure we can handle script parameters - if ( !function_exists( 'hphp_thread_set_warmup_enabled' ) && !ini_get( 'register_argc_argv' ) ) { + if ( !defined( 'HPHP_VERSION' ) && !ini_get( 'register_argc_argv' ) ) { $this->error( 'Cannot get command line arguments, register_argc_argv is set to false', true ); } @@ -515,7 +521,7 @@ abstract class Maintenance { $wgCommandLineMode = true; # Turn off output buffering if it's on - while( ob_get_level() > 0 ) { + while ( ob_get_level() > 0 ) { ob_end_flush(); } @@ -634,7 +640,7 @@ abstract class Maintenance { } elseif ( substr( $arg, 0, 1 ) == '-' ) { # Short options for ( $p = 1; $p < strlen( $arg ); $p++ ) { - $option = $arg { $p } ; + $option = $arg { $p }; if ( !isset( $this->mParams[$option] ) && isset( $this->mShortParamsMap[$option] ) ) { $option = $this->mShortParamsMap[$option]; } @@ -712,7 +718,7 @@ abstract class Maintenance { * @param $force boolean Whether to force the help to show, default false */ protected function maybeHelp( $force = false ) { - if( !$force && !$this->hasOption( 'help' ) ) { + if ( !$force && !$this->hasOption( 'help' ) ) { return; } @@ -743,8 +749,9 @@ abstract class Maintenance { } else { $output .= '[' . $arg['name'] . ']'; } - if ( $k < count( $this->mArgList ) - 1 ) + if ( $k < count( $this->mArgList ) - 1 ) { $output .= ' '; + } } } $this->output( "$output\n\n" ); @@ -765,7 +772,7 @@ abstract class Maintenance { $this->output( "\n" ); $scriptDependantParams = $this->mDependantParameters; - if( count($scriptDependantParams) > 0 ) { + if ( count( $scriptDependantParams ) > 0 ) { $this->output( "Script dependant parameters:\n" ); // Parameters description foreach ( $scriptDependantParams as $par => $info ) { @@ -790,7 +797,7 @@ abstract class Maintenance { $this->mGenericParameters, $this->mDependantParameters ); - if( count($scriptSpecificParams) > 0 ) { + if ( count( $scriptSpecificParams ) > 0 ) { $this->output( "Script specific parameters:\n" ); // Parameters description foreach ( $scriptSpecificParams as $par => $info ) { @@ -806,7 +813,7 @@ abstract class Maintenance { } // Print arguments - if( count( $this->mArgList ) > 0 ) { + if ( count( $this->mArgList ) > 0 ) { $this->output( "Arguments:\n" ); // Arguments description foreach ( $this->mArgList as $info ) { @@ -839,7 +846,7 @@ abstract class Maintenance { $wgCommandLineMode = true; # Override $wgServer - if( $this->hasOption( 'server') ) { + if ( $this->hasOption( 'server' ) ) { $wgServer = $this->getOption( 'server', $wgServer ); } @@ -876,6 +883,16 @@ abstract class Maintenance { $wgShowSQLErrors = true; @set_time_limit( 0 ); $this->adjustMemoryLimit(); + + // Per-script profiling; useful for debugging + $forcedProfiler = $this->getOption( 'profiler' ); + if ( $forcedProfiler === 'text' ) { + Profiler::setInstance( new ProfilerSimpleText( array() ) ); + Profiler::instance()->setTemplated( true ); + } elseif ( $forcedProfiler === 'trace' ) { + Profiler::setInstance( new ProfilerSimpleTrace( array() ) ); + Profiler::instance()->setTemplated( true ); + } } /** @@ -906,7 +923,7 @@ abstract class Maintenance { if ( isset( $this->mOptions['conf'] ) ) { $settingsFile = $this->mOptions['conf']; - } elseif ( defined("MW_CONFIG_FILE") ) { + } elseif ( defined( "MW_CONFIG_FILE" ) ) { $settingsFile = MW_CONFIG_FILE; } else { $settingsFile = "$IP/LocalSettings.php"; @@ -1025,7 +1042,7 @@ abstract class Maintenance { ( strpos( file_get_contents( $file ), '$maintClass' ) === false ) ) { continue; } - require( $file ); + require $file; $vars = get_defined_vars(); if ( array_key_exists( 'maintClass', $vars ) ) { self::$mCoreScripts[$vars['maintClass']] = $file; @@ -1076,7 +1093,7 @@ abstract class Maintenance { * @param &$db DatabaseBase object */ private function unlockSearchindex( &$db ) { - $db->unlockTables( __CLASS__ . '::' . __METHOD__ ); + $db->unlockTables( __CLASS__ . '::' . __METHOD__ ); } /** @@ -1143,8 +1160,7 @@ abstract class Maintenance { $title = $titleObj->getPrefixedDBkey(); $this->output( "$title..." ); # Update searchindex - # TODO: pass the Content object to SearchUpdate, let the search engine decide how to deal with it. - $u = new SearchUpdate( $pageId, $titleObj->getText(), $rev->getContent()->getTextForSearchIndex() ); + $u = new SearchUpdate( $pageId, $titleObj->getText(), $rev->getContent() ); $u->doUpdate(); $this->output( "\n" ); } @@ -1160,7 +1176,7 @@ abstract class Maintenance { * @return bool */ public static function posix_isatty( $fd ) { - if ( !MWInit::functionExists( 'posix_isatty' ) ) { + if ( !function_exists( 'posix_isatty' ) ) { return !$fd; } else { return posix_isatty( $fd ); @@ -1190,7 +1206,9 @@ abstract class Maintenance { $st = fgets( STDIN, 1024 ); } } - if ( $st === false ) return false; + if ( $st === false ) { + return false; + } $resp = trim( $st ); return $resp; } diff --git a/maintenance/archives/patch-archive-ar_id.sql b/maintenance/archives/patch-archive-ar_id.sql new file mode 100644 index 00000000..ddd1d7b4 --- /dev/null +++ b/maintenance/archives/patch-archive-ar_id.sql @@ -0,0 +1,8 @@ +-- +-- patch-archive-ar_id.sql +-- +-- Bug 39675. Add archive.ar_id. + +ALTER TABLE /*$wgDBprefix*/archive + ADD COLUMN ar_id int unsigned NOT NULL AUTO_INCREMENT FIRST, + ADD PRIMARY KEY (ar_id); diff --git a/maintenance/archives/patch-change_tag.sql b/maintenance/archives/patch-change_tag.sql index 030e086b..3079a5bb 100644 --- a/maintenance/archives/patch-change_tag.sql +++ b/maintenance/archives/patch-change_tag.sql @@ -13,20 +13,3 @@ CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag); -- Covering index, so we can pull all the info only out of the index. CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); - --- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT that only works on MySQL 4.1+ -CREATE TABLE /*_*/tag_summary ( - ts_rc_id int NULL, - ts_log_id int NULL, - ts_rev_id int NULL, - ts_tags BLOB NOT NULL -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); - - -CREATE TABLE /*_*/valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -) /*$wgDBTableOptions*/; diff --git a/maintenance/archives/patch-eu_local_id.sql b/maintenance/archives/patch-eu_local_id.sql deleted file mode 100644 index bb59d067..00000000 --- a/maintenance/archives/patch-eu_local_id.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE /*_*/external_user -CHANGE COLUMN eu_wiki_id -eu_local_id int unsigned NOT NULL; diff --git a/maintenance/archives/patch-external_user.sql b/maintenance/archives/patch-external_user.sql deleted file mode 100644 index 176b46d4..00000000 --- a/maintenance/archives/patch-external_user.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE /*_*/external_user ( - -- Foreign key to user_id - eu_local_id int unsigned NOT NULL PRIMARY KEY, - - -- Some opaque identifier provided by the external database - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); diff --git a/maintenance/archives/patch-externallinks-el_id.sql b/maintenance/archives/patch-externallinks-el_id.sql new file mode 100644 index 00000000..d4b51b51 --- /dev/null +++ b/maintenance/archives/patch-externallinks-el_id.sql @@ -0,0 +1,8 @@ +-- +-- patch-extenallinks-el_id.sql +-- +-- Bug 15441. Add externallinks.el_id. + +ALTER TABLE /*$wgDBprefix*/externallinks + ADD COLUMN el_id int unsigned NOT NULL AUTO_INCREMENT FIRST, + ADD PRIMARY KEY (el_id); diff --git a/maintenance/archives/patch-iwl_prefix_title_from-non-unique.sql b/maintenance/archives/patch-iwl_prefix_title_from-non-unique.sql new file mode 100644 index 00000000..bff63c74 --- /dev/null +++ b/maintenance/archives/patch-iwl_prefix_title_from-non-unique.sql @@ -0,0 +1,5 @@ +-- +-- Makes the iwl_prefix_title_from index for the iwlinks table non-unique +-- +DROP INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks; +CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); diff --git a/maintenance/archives/patch-iwlinks-from-title-index.sql b/maintenance/archives/patch-iwlinks-from-title-index.sql new file mode 100644 index 00000000..8b73f9e3 --- /dev/null +++ b/maintenance/archives/patch-iwlinks-from-title-index.sql @@ -0,0 +1,4 @@ +-- +-- Recreates the iwl_prefix_from_title index for the iwlinks table +-- +CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title); diff --git a/maintenance/archives/patch-kill-iwl_pft.sql b/maintenance/archives/patch-kill-iwl_pft.sql deleted file mode 100644 index 96e14356..00000000 --- a/maintenance/archives/patch-kill-iwl_pft.sql +++ /dev/null @@ -1,7 +0,0 @@ --- --- Kill the old iwl_prefix_from_title index, which may be present on some --- installs if they ran update.php between it being added and being renamed --- - -DROP INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks; - diff --git a/maintenance/archives/patch-tag_summary.sql b/maintenance/archives/patch-tag_summary.sql new file mode 100644 index 00000000..a81b3680 --- /dev/null +++ b/maintenance/archives/patch-tag_summary.sql @@ -0,0 +1,12 @@ +-- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT that only works on MySQL 4.1+ +-- Andrew Garrett, 2009-01 +CREATE TABLE /*_*/tag_summary ( + ts_rc_id int NULL, + ts_log_id int NULL, + ts_rev_id int NULL, + ts_tags BLOB NOT NULL +) /*$wgDBTableOptions*/; + +CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); +CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); +CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); diff --git a/maintenance/archives/patch-valid_tag.sql b/maintenance/archives/patch-valid_tag.sql new file mode 100644 index 00000000..994a5d53 --- /dev/null +++ b/maintenance/archives/patch-valid_tag.sql @@ -0,0 +1,4 @@ +-- Andrew Garrett, 2009-01 +CREATE TABLE /*_*/valid_tag ( + vt_tag varchar(255) NOT NULL PRIMARY KEY +) /*$wgDBTableOptions*/; diff --git a/maintenance/archives/upgradeLogging.php b/maintenance/archives/upgradeLogging.php index f0806458..0749bbf6 100644 --- a/maintenance/archives/upgradeLogging.php +++ b/maintenance/archives/upgradeLogging.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceArchive */ -require( __DIR__ . '/../commandLine.inc' ); +require __DIR__ . '/../commandLine.inc'; /** * Maintenance script that upgrade for log_id/log_deleted fields in a diff --git a/maintenance/attachLatest.php b/maintenance/attachLatest.php index 475cafc9..2cf277fe 100644 --- a/maintenance/attachLatest.php +++ b/maintenance/attachLatest.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to correct wrong values in the `page_latest` field @@ -83,4 +83,4 @@ class AttachLatest extends Maintenance { } $maintClass = "AttachLatest"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/backup.inc b/maintenance/backup.inc index e3dc488b..3dc94c88 100644 --- a/maintenance/backup.inc +++ b/maintenance/backup.inc @@ -40,17 +40,17 @@ class BackupDumper { var $reportingInterval = 100; var $reporting = true; var $pageCount = 0; - var $revCount = 0; - var $server = null; // use default - var $pages = null; // all pages + var $revCount = 0; + var $server = null; // use default + var $pages = null; // all pages var $skipHeader = false; // don't output <mediawiki> and <siteinfo> var $skipFooter = false; // don't output </mediawiki> - var $startId = 0; - var $endId = 0; + var $startId = 0; + var $endId = 0; var $revStartId = 0; - var $revEndId = 0; - var $sink = null; // Output filters - var $stubText = false; // include rev_text_id instead of text; for 2-pass dump + var $revEndId = 0; + var $sink = null; // Output filters + var $stubText = false; // include rev_text_id instead of text; for 2-pass dump var $dumpUploads = false; var $dumpUploadFileContents = false; var $lastTime = 0; @@ -116,7 +116,7 @@ class BackupDumper { */ function loadPlugin( $class, $file ) { if ( $file != '' ) { - require_once( $file ); + require_once $file; } $register = array( $class, 'register' ); call_user_func_array( $register, array( &$this ) ); @@ -133,7 +133,7 @@ class BackupDumper { $matches = array(); if ( preg_match( '/^--(.+?)(?:=(.+?)(?::(.+?))?)?$/', $arg, $matches ) ) { @list( /* $full */ , $opt, $val, $param ) = $matches; - switch( $opt ) { + switch ( $opt ) { case "plugin": $this->loadPlugin( $val, $param ); break; @@ -170,11 +170,8 @@ class BackupDumper { break; case "force-normal": if ( !function_exists( 'utf8_normalize' ) ) { - wfDl( "php_utfnormal.so" ); - if ( !function_exists( 'utf8_normalize' ) ) { - $this->fatalError( "Failed to load UTF-8 normalization extension. " . - "Install or remove --force-normal parameter to use slower code." ); - } + $this->fatalError( "UTF-8 normalization extension not loaded. " . + "Install or remove --force-normal parameter to use slower code." ); } break; default: @@ -202,8 +199,9 @@ class BackupDumper { function dump( $history, $text = WikiExporter::TEXT ) { # Notice messages will foul up your XML output even if they're # relatively harmless. - if ( ini_get( 'display_errors' ) ) + if ( ini_get( 'display_errors' ) ) { ini_set( 'display_errors', 'stderr' ); + } $this->initProgress( $history ); @@ -215,8 +213,9 @@ class BackupDumper { $wrapper = new ExportProgressFilter( $this->sink, $this ); $exporter->setOutputSink( $wrapper ); - if ( !$this->skipHeader ) + if ( !$this->skipHeader ) { $exporter->openStream(); + } # Log item dumps: all or by range if ( $history & WikiExporter::LOGS ) { if ( $this->startId || $this->endId ) { @@ -225,7 +224,7 @@ class BackupDumper { $exporter->allLogs(); } # Page dumps: all or by page ID range - } else if ( is_null( $this->pages ) ) { + } elseif ( is_null( $this->pages ) ) { if ( $this->startId || $this->endId ) { $exporter->pagesByRange( $this->startId, $this->endId ); } elseif ( $this->revStartId || $this->revEndId ) { @@ -238,8 +237,9 @@ class BackupDumper { $exporter->pagesByName( $this->pages ); } - if ( !$this->skipFooter ) + if ( !$this->skipFooter ) { $exporter->closeStream(); + } $this->report( true ); } @@ -365,7 +365,7 @@ class BackupDumper { function fatalError( $msg ) { $this->progress( "$msg\n" ); - die(1); + die( 1 ); } } diff --git a/maintenance/backupPrefetch.inc b/maintenance/backupPrefetch.inc index cc0a7e17..04352b9b 100644 --- a/maintenance/backupPrefetch.inc +++ b/maintenance/backupPrefetch.inc @@ -51,7 +51,7 @@ class BaseDump { $this->infiles = explode( ';', $infile ); $this->reader = new XMLReader(); $infile = array_shift( $this->infiles ); - if (defined( 'LIBXML_PARSEHUGE' ) ) { + if ( defined( 'LIBXML_PARSEHUGE' ) ) { $this->reader->open( $infile, null, LIBXML_PARSEHUGE ); } else { @@ -110,8 +110,8 @@ class BaseDump { } } else { $this->close(); - if (count($this->infiles)) { - $infile = array_shift($this->infiles); + if ( count( $this->infiles ) ) { + $infile = array_shift( $this->infiles ); $this->reader->open( $infile ); $this->atEnd = false; } @@ -181,7 +181,7 @@ class BaseDump { } $buffer = ""; while ( $this->reader->read() ) { - switch( $this->reader->nodeType ) { + switch ( $this->reader->nodeType ) { case XMLReader::TEXT: // case XMLReader::WHITESPACE: case XMLReader::SIGNIFICANT_WHITESPACE: diff --git a/maintenance/backupTextPass.inc b/maintenance/backupTextPass.inc index 0b8b3445..c515c6fe 100644 --- a/maintenance/backupTextPass.inc +++ b/maintenance/backupTextPass.inc @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/backup.inc' ); +require_once __DIR__ . '/backup.inc'; /** * @ingroup Maintenance @@ -141,8 +141,9 @@ class TextPassDumper extends BackupDumper { function dump( $history, $text = WikiExporter::TEXT ) { // Notice messages will foul up your XML output even if they're // relatively harmless. - if ( ini_get( 'display_errors' ) ) + if ( ini_get( 'display_errors' ) ) { ini_set( 'display_errors', 'stderr' ); + } $this->initProgress( $this->history ); @@ -182,7 +183,7 @@ class TextPassDumper extends BackupDumper { global $IP; $url = $this->processFileOpt( $val, $param ); - switch( $opt ) { + switch ( $opt ) { case 'prefetch': require_once "$IP/maintenance/backupPrefetch.inc"; $this->prefetch = new BaseDump( $url ); @@ -214,7 +215,7 @@ class TextPassDumper extends BackupDumper { function processFileOpt( $val, $param ) { $fileURIs = explode( ';', $param ); foreach ( $fileURIs as $URI ) { - switch( $val ) { + switch ( $val ) { case "file": $newURI = $URI; break; @@ -298,7 +299,7 @@ class TextPassDumper extends BackupDumper { } function checkIfTimeExceeded() { - if ( $this->maxTimeAllowed && ( $this->lastTime - $this->timeOfCheckpoint > $this->maxTimeAllowed ) ) { + if ( $this->maxTimeAllowed && ( $this->lastTime - $this->timeOfCheckpoint > $this->maxTimeAllowed ) ) { return true; } return false; @@ -413,6 +414,8 @@ class TextPassDumper extends BackupDumper { * @throws MWException */ function getText( $id ) { + global $wgContentHandlerUseDB; + $prefetchNotTried = true; // Whether or not we already tried to get the text via prefetch. $text = false; // The candidate for a good text. false if no proper value. $failures = 0; // The number of times, this invocation of getText already failed. @@ -478,7 +481,28 @@ class TextPassDumper extends BackupDumper { if ( ! isset( $this->db ) ) { throw new MWException( "No database available" ); } - $revLength = $this->db->selectField( 'revision', 'rev_len', array( 'rev_id' => $revID ) ); + + $revLength = strlen( $text ); + if ( $wgContentHandlerUseDB ) { + $row = $this->db->selectRow( + 'revision', + array( 'rev_len', 'rev_content_model' ), + array( 'rev_id' => $revID ), + __METHOD__ + ); + if ( $row ) { + // only check the length for the wikitext content handler, + // it's a wasted (and failed) check otherwise + if ( $row->rev_content_model == CONTENT_MODEL_WIKITEXT ) { + $revLength = $row->rev_len; + } + } + + } + else { + $revLength = $this->db->selectField( 'revision', 'rev_len', array( 'rev_id' => $revID ) ); + } + if ( strlen( $text ) == $revLength ) { if ( $tryIsPrefetch ) { $this->prefetchCount++; @@ -611,17 +635,21 @@ class TextPassDumper extends BackupDumper { private function closeSpawn() { wfSuppressWarnings(); - if ( $this->spawnRead ) + if ( $this->spawnRead ) { fclose( $this->spawnRead ); + } $this->spawnRead = false; - if ( $this->spawnWrite ) + if ( $this->spawnWrite ) { fclose( $this->spawnWrite ); + } $this->spawnWrite = false; - if ( $this->spawnErr ) + if ( $this->spawnErr ) { fclose( $this->spawnErr ); + } $this->spawnErr = false; - if ( $this->spawnProc ) + if ( $this->spawnProc ) { pclose( $this->spawnProc ); + } $this->spawnProc = false; wfRestoreWarnings(); } @@ -631,11 +659,15 @@ class TextPassDumper extends BackupDumper { $ok = fwrite( $this->spawnWrite, "$id\n" ); // $this->progress( ">> $id" ); - if ( !$ok ) return false; + if ( !$ok ) { + return false; + } $ok = fflush( $this->spawnWrite ); // $this->progress( ">> [flush]" ); - if ( !$ok ) return false; + if ( !$ok ) { + return false; + } // check that the text id they are sending is the one we asked for // this avoids out of sync revision text errors we have encountered in the past @@ -649,18 +681,24 @@ class TextPassDumper extends BackupDumper { $len = fgets( $this->spawnRead ); // $this->progress( "<< " . trim( $len ) ); - if ( $len === false ) return false; + if ( $len === false ) { + return false; + } $nbytes = intval( $len ); // actual error, not zero-length text - if ( $nbytes < 0 ) return false; + if ( $nbytes < 0 ) { + return false; + } $text = ""; // Subprocess may not send everything at once, we have to loop. while ( $nbytes > strlen( $text ) ) { $buffer = fread( $this->spawnRead, $nbytes - strlen( $text ) ); - if ( $buffer === false ) break; + if ( $buffer === false ) { + break; + } $text .= $buffer; } diff --git a/maintenance/benchmarks/Benchmarker.php b/maintenance/benchmarks/Benchmarker.php index 98b35b53..dd558f32 100644 --- a/maintenance/benchmarks/Benchmarker.php +++ b/maintenance/benchmarks/Benchmarker.php @@ -27,7 +27,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Base class for benchmark scripts. @@ -48,20 +48,20 @@ abstract class Benchmarker extends Maintenance { foreach( $benchs as $bench ) { // handle empty args - if(!array_key_exists( 'args', $bench )) { + if( !array_key_exists( 'args', $bench ) ) { $bench['args'] = array(); } $bench_number++; $start = microtime( true ); - for( $i=0; $i<$count; $i++ ) { + for( $i = 0; $i < $count; $i++ ) { call_user_func_array( $bench['function'], $bench['args'] ); } $delta = microtime( true ) - $start; // function passed as a callback if( is_array( $bench['function'] ) ) { - $ret = get_class( $bench['function'][0] ). '->' . $bench['function'][1]; + $ret = get_class( $bench['function'][0] ) . '->' . $bench['function'][1]; $bench['function'] = $ret; } @@ -85,7 +85,7 @@ abstract class Benchmarker extends Maintenance { join( ', ', $res['arguments'] ) ); $ret .= sprintf( " %6.2fms (%6.2fms each)\n", - $res['delta'] * 1000, + $res['delta'] * 1000, $res['average'] * 1000 ); } diff --git a/maintenance/benchmarks/README b/maintenance/benchmarks/README new file mode 100644 index 00000000..c021abd2 --- /dev/null +++ b/maintenance/benchmarks/README @@ -0,0 +1,7 @@ +This directory hold several benchmarking scripts used as a proof of speed +or to track PHP performances over time. + +To get somehow accurate result, you might want to bound the PHP process +to a specific CPU with `taskset` and raise its priority with `nice`. Example: + + $ taskset 1 nice -n-10 php bench_wfIsWindows.php diff --git a/maintenance/benchmarks/bench_HTTP_HTTPS.php b/maintenance/benchmarks/bench_HTTP_HTTPS.php index fa76ae22..6f800fb3 100644 --- a/maintenance/benchmarks/bench_HTTP_HTTPS.php +++ b/maintenance/benchmarks/bench_HTTP_HTTPS.php @@ -24,7 +24,7 @@ * @author Platonides */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks HTTP request vs HTTPS request. @@ -62,4 +62,4 @@ class bench_HTTP_HTTPS extends Benchmarker { } $maintClass = 'bench_HTTP_HTTPS'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_delete_truncate.php b/maintenance/benchmarks/bench_delete_truncate.php index d9741496..3eff534b 100644 --- a/maintenance/benchmarks/bench_delete_truncate.php +++ b/maintenance/benchmarks/bench_delete_truncate.php @@ -21,7 +21,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks SQL DELETE vs SQL TRUNCATE. @@ -101,4 +101,4 @@ class BenchmarkDeleteTruncate extends Benchmarker { } $maintClass = "BenchmarkDeleteTruncate"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_if_switch.php b/maintenance/benchmarks/bench_if_switch.php index 1f590d4d..80fd9623 100644 --- a/maintenance/benchmarks/bench_if_switch.php +++ b/maintenance/benchmarks/bench_if_switch.php @@ -24,7 +24,7 @@ * @author Platonides */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmark if elseif... versus switch case. @@ -93,4 +93,4 @@ class bench_if_switch extends Benchmarker { } $maintClass = 'bench_if_switch'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_strtr_str_replace.php b/maintenance/benchmarks/bench_strtr_str_replace.php index 10c5cd0b..bd21b186 100644 --- a/maintenance/benchmarks/bench_strtr_str_replace.php +++ b/maintenance/benchmarks/bench_strtr_str_replace.php @@ -23,7 +23,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; function bfNormalizeTitleStrTr( $str ) { return strtr( $str, '_', ' ' ); @@ -75,4 +75,4 @@ class bench_strtr_str_replace extends Benchmarker { } $maintClass = 'bench_strtr_str_replace'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_utf8_title_check.php b/maintenance/benchmarks/bench_utf8_title_check.php index f5987800..078293eb 100644 --- a/maintenance/benchmarks/bench_utf8_title_check.php +++ b/maintenance/benchmarks/bench_utf8_title_check.php @@ -21,7 +21,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * This little benchmark executes the regexp used in Language->checkTitleEncoding() @@ -38,7 +38,7 @@ class bench_utf8_title_check extends Benchmarker { public function __construct() { parent::__construct(); - $this->data = array ( + $this->data = array( "", "United States of America", // 7bit ASCII "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e", @@ -123,4 +123,4 @@ class bench_utf8_title_check extends Benchmarker { } $maintClass = 'bench_utf8_title_check'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_wfBaseConvert.php b/maintenance/benchmarks/bench_wfBaseConvert.php index a1e5c6a4..f8a21562 100644 --- a/maintenance/benchmarks/bench_wfBaseConvert.php +++ b/maintenance/benchmarks/bench_wfBaseConvert.php @@ -22,7 +22,7 @@ * @author Tyler Romeo */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks wfBaseConvert(). @@ -74,4 +74,4 @@ class bench_wfBaseConvert extends Benchmarker { } $maintClass = 'bench_wfBaseConvert'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/bench_wfIsWindows.php b/maintenance/benchmarks/bench_wfIsWindows.php index 85439827..1cd2016b 100644 --- a/maintenance/benchmarks/bench_wfIsWindows.php +++ b/maintenance/benchmarks/bench_wfIsWindows.php @@ -24,7 +24,7 @@ * @author Platonides */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks wfIsWindows(). @@ -66,4 +66,4 @@ class bench_wfIsWindows extends Benchmarker { } $maintClass = 'bench_wfIsWindows'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/benchmarkHooks.php b/maintenance/benchmarks/benchmarkHooks.php index fdb016f4..3f5d6db0 100644 --- a/maintenance/benchmarks/benchmarkHooks.php +++ b/maintenance/benchmarks/benchmarkHooks.php @@ -21,7 +21,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks %MediaWiki hooks. @@ -84,4 +84,4 @@ class BenchmarkHooks extends Benchmarker { } $maintClass = 'BenchmarkHooks'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/benchmarks/benchmarkPurge.php b/maintenance/benchmarks/benchmarkPurge.php index ec686b2a..fd863d52 100644 --- a/maintenance/benchmarks/benchmarkPurge.php +++ b/maintenance/benchmarks/benchmarkPurge.php @@ -21,7 +21,7 @@ * @ingroup Benchmark */ -require_once( __DIR__ . '/Benchmarker.php' ); +require_once __DIR__ . '/Benchmarker.php'; /** * Maintenance script that benchmarks Squid purge. @@ -112,4 +112,4 @@ class BenchmarkPurge extends Benchmarker { } $maintClass = "BenchmarkPurge"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cdb.php b/maintenance/cdb.php index c06c2cd0..d42f9f7a 100644 --- a/maintenance/cdb.php +++ b/maintenance/cdb.php @@ -23,12 +23,12 @@ */ /** */ -require_once( __DIR__ . '/commandLine.inc' ); +require_once __DIR__ . '/commandLine.inc'; function cdbShowHelp( $command ) { $commandList = array( 'load' => 'load a cdb file for reading', - 'get' => 'get a value for a key', + 'get' => 'get a value for a key', 'exit' => 'exit cdb', 'quit' => 'exit cdb', 'help' => 'help about a command', @@ -55,7 +55,9 @@ do { static $fileHandle; $line = Maintenance::readconsole(); - if ( $line === false ) exit; + if ( $line === false ) { + exit; + } $args = explode( ' ', $line ); $command = array_shift( $args ); @@ -67,25 +69,25 @@ do { cdbShowHelp( array_shift( $args ) ); break; case 'load': - if( !isset( $args[0] ) ) { + if ( !isset( $args[0] ) ) { print "Need a filename there buddy\n"; break; } $file = $args[0]; print "Loading cdb file $file..."; $fileHandle = CdbReader::open( $file ); - if( !$fileHandle ) { + if ( !$fileHandle ) { print "not a cdb file or unable to read it\n"; } else { print "ok\n"; } break; case 'get': - if( !$fileHandle ) { + if ( !$fileHandle ) { print "Need to load a cdb file first\n"; break; } - if( !isset( $args[0] ) ) { + if ( !isset( $args[0] ) ) { print "Need to specify a key, Luke\n"; break; } diff --git a/maintenance/changePassword.php b/maintenance/changePassword.php index 861610b7..5d98e1f5 100644 --- a/maintenance/changePassword.php +++ b/maintenance/changePassword.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to change the password of a given user. @@ -62,4 +62,4 @@ class ChangePassword extends Maintenance { } $maintClass = "ChangePassword"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/checkBadRedirects.php b/maintenance/checkBadRedirects.php index 4ba7e66b..a96e9b80 100644 --- a/maintenance/checkBadRedirects.php +++ b/maintenance/checkBadRedirects.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to check that pages marked as being redirects really are. @@ -61,4 +61,4 @@ class CheckBadRedirects extends Maintenance { } $maintClass = "CheckBadRedirects"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/checkImages.php b/maintenance/checkImages.php index c05d9151..e6aea537 100644 --- a/maintenance/checkImages.php +++ b/maintenance/checkImages.php @@ -20,7 +20,7 @@ * @file * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to check images to see if they exist, are readable, etc. @@ -87,4 +87,4 @@ class CheckImages extends Maintenance { } $maintClass = "CheckImages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/checkLess.php b/maintenance/checkLess.php new file mode 100644 index 00000000..d02d8a7b --- /dev/null +++ b/maintenance/checkLess.php @@ -0,0 +1,72 @@ +<?php +/** + * Checks LESS files in known resources for errors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Maintenance + */ + +require_once __DIR__ . '/Maintenance.php'; + +/** + * @ingroup Maintenance + */ +class CheckLess extends Maintenance { + public function __construct() { + parent::__construct(); + $this->mDescription = 'Checks LESS files for errors'; + } + + public function execute() { + $result = false; + $resourceLoader = new ResourceLoader(); + foreach ( $resourceLoader->getModuleNames() as $name ) { + /** @var ResourceLoaderFileModule $module */ + $module = $resourceLoader->getModule( $name ); + if ( !$module || !$module instanceof ResourceLoaderFileModule ) { + continue; + } + + $hadErrors = false; + foreach ( $module->getAllStyleFiles() as $file ) { + if ( $module->getStyleSheetLang( $file ) !== 'less' ) { + continue; + } + try { + $compiler = ResourceLoader::getLessCompiler(); + $compiler->compileFile( $file ); + } catch ( Exception $e ) { + if ( !$hadErrors ) { + $this->error( "Errors checking module $name:\n" ); + $hadErrors = true; + } + $this->error( $e->getMessage() . "\n" ); + $result = true; + } + } + } + if ( !$result ) { + $this->output( "No errors found\n" ); + } else { + die( 1 ); + } + } +} + +$maintClass = 'CheckLess'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/checkSyntax.php b/maintenance/checkSyntax.php index 1e44e239..dc8626df 100644 --- a/maintenance/checkSyntax.php +++ b/maintenance/checkSyntax.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to check syntax of all PHP files in MediaWiki. @@ -221,12 +221,14 @@ class CheckSyntax extends Maintenance { private function isSuitableFile( $file ) { $file = str_replace( '\\', '/', $file ); $ext = pathinfo( $file, PATHINFO_EXTENSION ); - if ( $ext != 'php' && $ext != 'inc' && $ext != 'php5' ) + if ( $ext != 'php' && $ext != 'inc' && $ext != 'php5' ) { return false; + } foreach ( $this->mIgnorePaths as $regex ) { $m = array(); - if ( preg_match( "~{$regex}~", $file, $m ) ) + if ( preg_match( "~{$regex}~", $file, $m ) ) { return false; + } } return true; } @@ -328,14 +330,15 @@ class CheckSyntax extends Maintenance { private function checkForMistakes( $file ) { foreach ( $this->mNoStyleCheckPaths as $regex ) { $m = array(); - if ( preg_match( "~{$regex}~", $file, $m ) ) + if ( preg_match( "~{$regex}~", $file, $m ) ) { return; + } } $text = file_get_contents( $file ); $tokens = token_get_all( $text ); - $this->checkEvilToken( $file, $tokens, '@', 'Error supression operator (@)'); + $this->checkEvilToken( $file, $tokens, '@', 'Error supression operator (@)' ); $this->checkRegex( $file, $text, '/^[\s\r\n]+<\?/', 'leading whitespace' ); $this->checkRegex( $file, $text, '/\?>[\s\r\n]*$/', 'trailing ?>' ); $this->checkRegex( $file, $text, '/^[\xFF\xFE\xEF]/', 'byte-order mark' ); @@ -367,4 +370,4 @@ class CheckSyntax extends Maintenance { } $maintClass = "CheckSyntax"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/checkUsernames.php b/maintenance/checkUsernames.php index dd5e0022..6df189fc 100644 --- a/maintenance/checkUsernames.php +++ b/maintenance/checkUsernames.php @@ -21,8 +21,7 @@ * @ingroup Maintenance */ - -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to check that database usernames are actually valid. @@ -37,25 +36,34 @@ class CheckUsernames extends Maintenance { public function __construct() { parent::__construct(); $this->mDescription = "Verify that database usernames are actually valid"; + $this->setBatchSize( 1000 ); } function execute() { $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'user', - array( 'user_id', 'user_name' ), - null, - __METHOD__ - ); + $maxUserId = 0; + do { + $res = $dbr->select( 'user', + array( 'user_id', 'user_name' ), + array( 'user_id > ' . $maxUserId ), + __METHOD__, + array( + 'ORDER BY' => 'user_id', + 'LIMIT' => $this->mBatchSize, + ) + ); - foreach ( $res as $row ) { - if ( ! User::isValidUserName( $row->user_name ) ) { - $this->error( sprintf( "%s: %6d: '%s'\n", wfWikiID(), $row->user_id, $row->user_name ) ); - wfDebugLog( 'checkUsernames', $row->user_name ); + foreach ( $res as $row ) { + if ( ! User::isValidUserName( $row->user_name ) ) { + $this->error( sprintf( "%s: %6d: '%s'\n", wfWikiID(), $row->user_id, $row->user_name ) ); + wfDebugLog( 'checkUsernames', $row->user_name ); + } } - } + $maxUserId = $row->user_id; + } while ( $res->numRows() ); } } $maintClass = "CheckUsernames"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupAncientTables.php b/maintenance/cleanupAncientTables.php index dbc2e0d3..694efaa6 100644 --- a/maintenance/cleanupAncientTables.php +++ b/maintenance/cleanupAncientTables.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to cleans up old database tables, dropping old indexes @@ -38,7 +38,7 @@ class CleanupAncientTables extends Maintenance { } public function execute() { - if( !$this->hasOption( 'force' ) ) { + if ( !$this->hasOption( 'force' ) ) { $this->error( "This maintenance script will remove old columns and indexes.\n" . "It is recommended to backup your database first, and ensure all your data has been migrated to newer tables\n" . "If you want to continue, run this script again with the --force \n" @@ -61,7 +61,7 @@ class CleanupAncientTables extends Maintenance { 'validate', // 1.6 ); - foreach( $ancientTables as $table ) { + foreach ( $ancientTables as $table ) { if ( $db->tableExists( $table, __METHOD__ ) ) { $this->output( "Dropping table $table..." ); $db->dropTable( $table, __METHOD__ ); @@ -78,7 +78,7 @@ class CleanupAncientTables extends Maintenance { 'user_timestamp', 'usertext_timestamp', ); - foreach( $oldIndexes as $index ) { + foreach ( $oldIndexes as $index ) { if ( $db->indexExists( 'text', $index, __METHOD__ ) ) { $this->output( "Dropping index $index from the text table..." ); $db->query( "DROP INDEX " . $db->addIdentifierQuotes( $index ) @@ -97,7 +97,7 @@ class CleanupAncientTables extends Maintenance { 'old_minor_edit', 'inverse_timestamp', ); - foreach( $oldFields as $field ) { + foreach ( $oldFields as $field ) { if ( $db->fieldExists( 'text', $field, __METHOD__ ) ) { $this->output( "Dropping the $field field from the text table..." ); $db->query( "ALTER TABLE " . $db->tableName( 'text' ) @@ -110,4 +110,4 @@ class CleanupAncientTables extends Maintenance { } $maintClass = "CleanupAncientTables"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupCaps.php b/maintenance/cleanupCaps.php index ec2aa957..1a47ac4e 100644 --- a/maintenance/cleanupCaps.php +++ b/maintenance/cleanupCaps.php @@ -29,7 +29,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/cleanupTable.inc' ); +require_once __DIR__ . '/cleanupTable.inc'; /** * Maintenance script to clean up broken page links when somebody turns on $wgCapitalLinks. @@ -103,4 +103,4 @@ class CapsCleanup extends TableCleanup { } $maintClass = "CapsCleanup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupImages.php b/maintenance/cleanupImages.php index 4e7b937d..0e0b6194 100644 --- a/maintenance/cleanupImages.php +++ b/maintenance/cleanupImages.php @@ -29,7 +29,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/cleanupTable.inc' ); +require_once __DIR__ . '/cleanupTable.inc'; /** * Maintenance script to clean up broken, unparseable upload filenames. @@ -213,4 +213,4 @@ class ImageCleanup extends TableCleanup { } $maintClass = "ImageCleanup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupPreferences.php b/maintenance/cleanupPreferences.php index c0a526b7..06ae17fb 100644 --- a/maintenance/cleanupPreferences.php +++ b/maintenance/cleanupPreferences.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that removes hidden preferences from the database. @@ -36,7 +36,7 @@ class CleanupPreferences extends Maintenance { $dbw = wfGetDB( DB_MASTER ); $dbw->begin( __METHOD__ ); - foreach( $wgHiddenPrefs as $item ) { + foreach ( $wgHiddenPrefs as $item ) { $dbw->delete( 'user_properties', array( 'up_property' => $item ), @@ -49,4 +49,4 @@ class CleanupPreferences extends Maintenance { } $maintClass = 'CleanupPreferences'; // Tells it to run the class -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupRemovedModules.php b/maintenance/cleanupRemovedModules.php index 2085da94..84eec289 100644 --- a/maintenance/cleanupRemovedModules.php +++ b/maintenance/cleanupRemovedModules.php @@ -22,7 +22,7 @@ * @author Roan Kattouw */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to remove cache entries for removed ResourceLoader modules @@ -58,7 +58,7 @@ class CleanupRemovedModules extends Maintenance { $this->output( "Batch $i: $numRows rows\n" ); $i++; wfWaitForSlaves( $maxlag ); - } while( $numRows > 0 ); + } while ( $numRows > 0 ); $this->output( "done\n" ); $this->output( "Cleaning up msg_resource table...\n" ); @@ -72,7 +72,7 @@ class CleanupRemovedModules extends Maintenance { $this->output( "Batch $i: $numRows rows\n" ); $i++; wfWaitForSlaves( $maxlag ); - } while( $numRows > 0 ); + } while ( $numRows > 0 ); $this->output( "done\n" ); $this->output( "Cleaning up msg_resource_links table...\n" ); @@ -85,10 +85,10 @@ class CleanupRemovedModules extends Maintenance { $this->output( "Batch $i: $numRows rows\n" ); $i++; wfWaitForSlaves( $maxlag ); - } while( $numRows > 0 ); + } while ( $numRows > 0 ); $this->output( "done\n" ); } } $maintClass = "CleanupRemovedModules"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupSpam.php b/maintenance/cleanupSpam.php index a41423ae..4b8c9feb 100644 --- a/maintenance/cleanupSpam.php +++ b/maintenance/cleanupSpam.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to cleanup all spam from a given hostname. @@ -141,4 +141,4 @@ class CleanupSpam extends Maintenance { } $maintClass = "CleanupSpam"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupTable.inc b/maintenance/cleanupTable.inc index 57acfd82..cbd1be6b 100644 --- a/maintenance/cleanupTable.inc +++ b/maintenance/cleanupTable.inc @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Generic class to cleanup a database table. Already subclasses Maintenance. @@ -41,6 +41,8 @@ class TableCleanup extends Maintenance { public $batchSize = 100; public $reportInterval = 100; + protected $processed, $updated, $count, $startTime, $table; + public function __construct() { parent::__construct(); $this->addOption( 'dry-run', 'Perform a dry run' ); @@ -66,6 +68,9 @@ class TableCleanup extends Maintenance { $this->table = $table; } + /** + * @param int $updated + */ protected function progress( $updated ) { $this->updated += $updated; $this->processed++; @@ -96,12 +101,16 @@ class TableCleanup extends Maintenance { flush(); } + /** + * @param array $params + * @throws MWException + */ public function runTable( $params ) { $dbr = wfGetDB( DB_SLAVE ); if ( array_diff( array_keys( $params ), - array( 'table', 'conds', 'index', 'callback' ) ) ) - { + array( 'table', 'conds', 'index', 'callback' ) ) + ) { throw new MWException( __METHOD__ . ': Missing parameter ' . implode( ', ', $params ) ); } @@ -111,7 +120,6 @@ class TableCleanup extends Maintenance { $this->init( $count, $table ); $this->output( "Processing $table...\n" ); - $index = (array)$params['index']; $indexConds = array(); $options = array( @@ -156,6 +164,10 @@ class TableCleanup extends Maintenance { $this->output( "Finished $table... $this->updated of $this->processed rows updated\n" ); } + /** + * @param array $matches + * @return string + */ protected function hexChar( $matches ) { return sprintf( "\\x%02x", ord( $matches[1] ) ); } diff --git a/maintenance/cleanupTitles.php b/maintenance/cleanupTitles.php index 66f9e87f..5b5ef184 100644 --- a/maintenance/cleanupTitles.php +++ b/maintenance/cleanupTitles.php @@ -29,7 +29,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/cleanupTable.inc' ); +require_once __DIR__ . '/cleanupTable.inc'; /** * Maintenance script to clean up broken, unparseable titles. @@ -42,6 +42,9 @@ class TitleCleanup extends TableCleanup { $this->mDescription = "Script to clean up broken, unparseable titles"; } + /** + * @param object $row + */ protected function processRow( $row ) { global $wgContLang; $display = Title::makeName( $row->page_namespace, $row->page_title ); @@ -51,40 +54,54 @@ class TitleCleanup extends TableCleanup { if ( !is_null( $title ) && $title->canExist() && $title->getNamespace() == $row->page_namespace - && $title->getDBkey() === $row->page_title ) - { - return $this->progress( 0 ); // all is fine + && $title->getDBkey() === $row->page_title + ) { + $this->progress( 0 ); // all is fine + + return; } if ( $row->page_namespace == NS_FILE && $this->fileExists( $row->page_title ) ) { $this->output( "file $row->page_title needs cleanup, please run cleanupImages.php.\n" ); - return $this->progress( 0 ); + $this->progress( 0 ); } elseif ( is_null( $title ) ) { $this->output( "page $row->page_id ($display) is illegal.\n" ); $this->moveIllegalPage( $row ); - return $this->progress( 1 ); + $this->progress( 1 ); } else { $this->output( "page $row->page_id ($display) doesn't match self.\n" ); $this->moveInconsistentPage( $row, $title ); - return $this->progress( 1 ); + $this->progress( 1 ); } } + /** + * @param string $name + * @return bool + */ protected function fileExists( $name ) { // XXX: Doesn't actually check for file existence, just presence of image record. // This is reasonable, since cleanupImages.php only iterates over the image table. $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'image', array( 'img_name' ), array( 'img_name' => $name ), __METHOD__ ); + return $row !== false; } + /** + * @param object $row + */ protected function moveIllegalPage( $row ) { $legal = 'A-Za-z0-9_/\\\\-'; $legalized = preg_replace_callback( "!([^$legal])!", array( &$this, 'hexChar' ), $row->page_title ); - if ( $legalized == '.' ) $legalized = '(dot)'; - if ( $legalized == '_' ) $legalized = '(space)'; + if ( $legalized == '.' ) { + $legalized = '(dot)'; + } + if ( $legalized == '_' ) { + $legalized = '(space)'; + } $legalized = 'Broken/' . $legalized; $title = Title::newFromText( $legalized ); @@ -100,9 +117,11 @@ class TitleCleanup extends TableCleanup { $dest = $title->getDBkey(); if ( $this->dryrun ) { - $this->output( "DRY RUN: would rename $row->page_id ($row->page_namespace,'$row->page_title') to ($row->page_namespace,'$dest')\n" ); + $this->output( "DRY RUN: would rename $row->page_id ($row->page_namespace," . + "'$row->page_title') to ($row->page_namespace,'$dest')\n" ); } else { - $this->output( "renaming $row->page_id ($row->page_namespace,'$row->page_title') to ($row->page_namespace,'$dest')\n" ); + $this->output( "renaming $row->page_id ($row->page_namespace," . + "'$row->page_title') to ($row->page_namespace,'$dest')\n" ); $dbw = wfGetDB( DB_MASTER ); $dbw->update( 'page', array( 'page_title' => $dest ), @@ -111,6 +130,10 @@ class TitleCleanup extends TableCleanup { } } + /** + * @param object $row + * @param Title $title + */ protected function moveInconsistentPage( $row, $title ) { if ( $title->exists() || $title->getInterwiki() || !$title->canExist() ) { if ( $title->getInterwiki() || !$title->canExist() ) { @@ -121,7 +144,9 @@ class TitleCleanup extends TableCleanup { # Old cleanupTitles could move articles there. See bug 23147. $ns = $row->page_namespace; - if ( $ns < 0 ) $ns = 0; + if ( $ns < 0 ) { + $ns = 0; + } $clean = 'Broken/' . $prior; $verified = Title::makeTitleSafe( $ns, $clean ); @@ -139,9 +164,11 @@ class TitleCleanup extends TableCleanup { $dest = $title->getDBkey(); if ( $this->dryrun ) { - $this->output( "DRY RUN: would rename $row->page_id ($row->page_namespace,'$row->page_title') to ($ns,'$dest')\n" ); + $this->output( "DRY RUN: would rename $row->page_id ($row->page_namespace," . + "'$row->page_title') to ($ns,'$dest')\n" ); } else { - $this->output( "renaming $row->page_id ($row->page_namespace,'$row->page_title') to ($ns,'$dest')\n" ); + $this->output( "renaming $row->page_id ($row->page_namespace," . + "'$row->page_title') to ($ns,'$dest')\n" ); $dbw = wfGetDB( DB_MASTER ); $dbw->update( 'page', array( @@ -156,4 +183,4 @@ class TitleCleanup extends TableCleanup { } $maintClass = "TitleCleanup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupUploadStash.php b/maintenance/cleanupUploadStash.php index 441e8ae3..c2ba5558 100644 --- a/maintenance/cleanupUploadStash.php +++ b/maintenance/cleanupUploadStash.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to remove old or broken uploads from temporary uploaded @@ -65,7 +65,7 @@ class UploadStashCleanup extends Maintenance { } else { // finish the read before starting writes. $keys = array(); - foreach( $res as $row ) { + foreach ( $res as $row ) { array_push( $keys, $row->us_key ); } @@ -76,15 +76,15 @@ class UploadStashCleanup extends Maintenance { $stash = new UploadStash( $repo ); $i = 0; - foreach( $keys as $key ) { + foreach ( $keys as $key ) { $i++; try { $stash->getFile( $key, true ); $stash->removeFileNoAuth( $key ); } catch ( UploadStashBadPathException $ex ) { - $this->output( "Failed removing stashed upload with key: $key\n" ); + $this->output( "Failed removing stashed upload with key: $key\n" ); } catch ( UploadStashZeroLengthFileException $ex ) { - $this->output( "Failed removing stashed upload with key: $key\n" ); + $this->output( "Failed removing stashed upload with key: $key\n" ); } if ( $i % 100 == 0 ) { $this->output( "$i\n" ); @@ -94,7 +94,7 @@ class UploadStashCleanup extends Maintenance { } // Delete all the corresponding thumbnails... - $dir = $tempRepo->getZonePath( 'thumb' ); + $dir = $tempRepo->getZonePath( 'thumb' ); $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir ) ); $this->output( "Deleting old thumbnails...\n" ); $i = 0; @@ -112,8 +112,8 @@ class UploadStashCleanup extends Maintenance { $this->output( "$i done\n" ); // Apparently lots of stash files are not registered in the DB... - $dir = $tempRepo->getZonePath( 'public' ); - $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir ) ); + $dir = $tempRepo->getZonePath( 'public' ); + $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir, 'adviseStat' => 1 ) ); $this->output( "Deleting orphaned temp files...\n" ); if ( strpos( $dir, '/local-temp' ) === false ) { // sanity check $this->error( "Temp repo is not using the temp container.", 1 ); // die @@ -140,4 +140,4 @@ class UploadStashCleanup extends Maintenance { } $maintClass = "UploadStashCleanup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/cleanupWatchlist.php b/maintenance/cleanupWatchlist.php index fbab6a3c..f1a7b481 100644 --- a/maintenance/cleanupWatchlist.php +++ b/maintenance/cleanupWatchlist.php @@ -29,7 +29,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/cleanupTable.inc' ); +require_once __DIR__ . '/cleanupTable.inc'; /** * Maintenance script to remove broken, unparseable titles in the watchlist table. @@ -77,9 +77,9 @@ class WatchlistCleanup extends TableCleanup { if ( !$this->dryrun && $this->hasOption( 'fix' ) ) { $dbw = wfGetDB( DB_MASTER ); $dbw->delete( 'watchlist', array( - 'wl_user' => $row->wl_user, + 'wl_user' => $row->wl_user, 'wl_namespace' => $row->wl_namespace, - 'wl_title' => $row->wl_title ), + 'wl_title' => $row->wl_title ), __METHOD__ ); $this->output( "- removed\n" ); return 1; @@ -90,4 +90,4 @@ class WatchlistCleanup extends TableCleanup { } $maintClass = "WatchlistCleanup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/clearCacheStats.php b/maintenance/clearCacheStats.php index 7a0d664a..6a966121 100644 --- a/maintenance/clearCacheStats.php +++ b/maintenance/clearCacheStats.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to remove all statistics tracking from the cache. @@ -57,4 +57,4 @@ class ClearCacheStats extends Maintenance { } $maintClass = "ClearCacheStats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/clearInterwikiCache.php b/maintenance/clearInterwikiCache.php index 88769df2..80c9004e 100644 --- a/maintenance/clearInterwikiCache.php +++ b/maintenance/clearInterwikiCache.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to clear the cache of interwiki prefixes for all local wikis. @@ -55,4 +55,4 @@ class ClearInterwikiCache extends Maintenance { } $maintClass = "ClearInterwikiCache"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/commandLine.inc b/maintenance/commandLine.inc index 86a558d0..be071422 100644 --- a/maintenance/commandLine.inc +++ b/maintenance/commandLine.inc @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; global $optionsWithArgs; if ( !isset( $optionsWithArgs ) ) { @@ -55,5 +55,5 @@ class CommandLineInc extends Maintenance { } $maintClass = 'CommandLineInc'; -require( RUN_MAINTENANCE_IF_MAIN ); +require RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/compareParsers.php b/maintenance/compareParsers.php index 1f3ac1c3..fabc2571 100644 --- a/maintenance/compareParsers.php +++ b/maintenance/compareParsers.php @@ -28,7 +28,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/dumpIterator.php' ); +require_once __DIR__ . '/dumpIterator.php'; /** * Maintenance script to take page text out of an XML dump file and render @@ -55,8 +55,8 @@ class CompareParsers extends DumpIterator { } public function checkOptions() { - if ( $this->hasOption('save-failed') ) { - $this->saveFailed = $this->getOption('save-failed'); + if ( $this->hasOption( 'save-failed' ) ) { + $this->saveFailed = $this->getOption( 'save-failed' ); } $this->stripParametersEnabled = $this->hasOption( 'strip-parameters' ); @@ -87,8 +87,9 @@ class CompareParsers extends DumpIterator { public function conclusions() { $this->error( "{$this->failed} failed revisions out of {$this->count}" ); - if ($this->count > 0) + if ( $this->count > 0 ) { $this->output( " (" . ( $this->failed / $this->count ) . "%)\n" ); + } } function stripParameters( $text ) { @@ -155,4 +156,4 @@ class CompareParsers extends DumpIterator { } $maintClass = "CompareParsers"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/convertLinks.php b/maintenance/convertLinks.php index 5f7b02e4..17b91110 100644 --- a/maintenance/convertLinks.php +++ b/maintenance/convertLinks.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to convert from the old links schema (string->ID) @@ -80,9 +80,9 @@ This gives a huge speed improvement for very large links tables which are MyISAM # -------------------------------------------------------------------- - list ( $cur, $links, $links_temp, $links_backup ) = $dbw->tableNamesN( 'cur', 'links', 'links_temp', 'links_backup' ); + list( $cur, $links, $links_temp, $links_backup ) = $dbw->tableNamesN( 'cur', 'links', 'links_temp', 'links_backup' ); - if( $dbw->tableExists( 'pagelinks' ) ) { + if ( $dbw->tableExists( 'pagelinks' ) ) { $this->output( "...have pagelinks; skipping old links table updates\n" ); return; } @@ -177,15 +177,16 @@ This gives a huge speed improvement for very large links tables which are MyISAM } $dbw->freeResult( $res ); # $this->output( "rowOffset: $rowOffset\ttuplesAdded: $tuplesAdded\tnumBadLinks: $numBadLinks\n" ); - if ( $tuplesAdded != 0 ) { + if ( $tuplesAdded != 0 ) { if ( $reportLinksConvProgress ) { $this->output( "Inserting $tuplesAdded tuples into $links_temp..." ); } $dbw->query( implode( "", $sqlWrite ) ); $totalTuplesInserted += $tuplesAdded; - if ( $reportLinksConvProgress ) + if ( $reportLinksConvProgress ) { $this->output( " done. Total $totalTuplesInserted tuples inserted.\n" ); - $this->performanceLog( $fh, $totalTuplesInserted . " " . ( $this->getMicroTime() - $baseTime ) . "\n" ); + $this->performanceLog( $fh, $totalTuplesInserted . " " . ( $this->getMicroTime() - $baseTime ) . "\n" ); + } } } $this->output( "$totalTuplesInserted valid titles and $numBadLinks invalid titles were processed.\n\n" ); @@ -258,4 +259,4 @@ This gives a huge speed improvement for very large links tables which are MyISAM } $maintClass = "ConvertLinks"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/convertUserOptions.php b/maintenance/convertUserOptions.php index e2223e1a..34c643bb 100644 --- a/maintenance/convertUserOptions.php +++ b/maintenance/convertUserOptions.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to convert user options to the new `user_properties` table. @@ -96,4 +96,4 @@ class ConvertUserOptions extends Maintenance { } $maintClass = "ConvertUserOptions"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/copyFileBackend.php b/maintenance/copyFileBackend.php index f2c4ac54..21ef4ffa 100644 --- a/maintenance/copyFileBackend.php +++ b/maintenance/copyFileBackend.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Copy all files in one container of one backend to another. @@ -35,6 +35,8 @@ require_once( __DIR__ . '/Maintenance.php' ); * @ingroup Maintenance */ class CopyFileBackend extends Maintenance { + protected $statCache = array(); + public function __construct() { parent::__construct(); $this->mDescription = "Copy files in one backend to another."; @@ -43,8 +45,10 @@ class CopyFileBackend extends Maintenance { $this->addOption( 'containers', 'Pipe separated list of containers', true, true ); $this->addOption( 'subdir', 'Only do items in this child directory', false, true ); $this->addOption( 'ratefile', 'File to check periodically for batch size', false, true ); + $this->addOption( 'prestat', 'Stat the destination files first (try to use listings)' ); $this->addOption( 'skiphash', 'Skip SHA-1 sync checks for files' ); $this->addOption( 'missingonly', 'Only copy files missing from destination listing' ); + $this->addOption( 'syncviadelete', 'Delete destination files missing from source listing' ); $this->addOption( 'utf8only', 'Skip source files that do not have valid UTF-8 names' ); $this->setBatchSize( 50 ); } @@ -53,7 +57,7 @@ class CopyFileBackend extends Maintenance { $src = FileBackendGroup::singleton()->get( $this->getOption( 'src' ) ); $dst = FileBackendGroup::singleton()->get( $this->getOption( 'dst' ) ); $containers = explode( '|', $this->getOption( 'containers' ) ); - $subDir = $this->getOption( rtrim( 'subdir', '/' ), '' ); + $subDir = rtrim( $this->getOption( 'subdir', '' ), '/' ); $rateFile = $this->getOption( 'ratefile' ); @@ -61,7 +65,6 @@ class CopyFileBackend extends Maintenance { $this->error( "Cannot check for UTF-8, mbstring extension missing.", 1 ); // die } - $count = 0; foreach ( $containers as $container ) { if ( $subDir != '' ) { $backendRel = "$container/$subDir"; @@ -71,40 +74,46 @@ class CopyFileBackend extends Maintenance { $this->output( "Doing container '$container'...\n" ); } - $srcPathsRel = $src->getFileList( array( - 'dir' => $src->getRootStoragePath() . "/$backendRel" ) ); - if ( $srcPathsRel === null ) { - $this->error( "Could not list files in $container.", 1 ); // die - } - - // Do a listing comparison if specified if ( $this->hasOption( 'missingonly' ) ) { - $relFilesSrc = array(); - $relFilesDst = array(); - foreach ( $srcPathsRel as $srcPathRel ) { - $relFilesSrc[] = $srcPathRel; + $this->output( "\tBuilding list of missing files..." ); + $srcPathsRel = $this->getListingDiffRel( $src, $dst, $backendRel ); + $this->output( count( $srcPathsRel ) . " file(s) need to be copied.\n" ); + } else { + $srcPathsRel = $src->getFileList( array( + 'dir' => $src->getRootStoragePath() . "/$backendRel", + 'adviseStat' => true // avoid HEADs + ) ); + if ( $srcPathsRel === null ) { + $this->error( "Could not list files in $container.", 1 ); // die } + } + + if ( $this->getOption( 'prestat' ) && !$this->hasOption( 'missingonly' ) ) { + // Build the stat cache for the destination files + $this->output( "\tBuilding destination stat cache..." ); $dstPathsRel = $dst->getFileList( array( - 'dir' => $dst->getRootStoragePath() . "/$backendRel" ) ); + 'dir' => $dst->getRootStoragePath() . "/$backendRel", + 'adviseStat' => true // avoid HEADs + ) ); if ( $dstPathsRel === null ) { $this->error( "Could not list files in $container.", 1 ); // die } + $this->statCache = array(); // clear foreach ( $dstPathsRel as $dstPathRel ) { - $relFilesDst[] = $dstPathRel; + $path = $dst->getRootStoragePath() . "/$backendRel/$dstPathRel"; + $this->statCache[sha1( $path )] = $dst->getFileStat( array( 'src' => $path ) ); } - // Only copy the missing files over in the next loop - $srcPathsRel = array_diff( $relFilesSrc, $relFilesDst ); - $this->output( count( $srcPathsRel ) . " file(s) need to be copied.\n" ); - unset( $relFilesSrc ); - unset( $relFilesDst ); + $this->output( "done [" . count( $this->statCache ) . " file(s)]\n" ); } + $this->output( "\tCopying file(s)...\n" ); + $count = 0; $batchPaths = array(); foreach ( $srcPathsRel as $srcPathRel ) { // Check up on the rate file periodically to adjust the concurrency if ( $rateFile && ( !$count || ( $count % 500 ) == 0 ) ) { $this->mBatchSize = max( 1, (int)file_get_contents( $rateFile ) ); - $this->output( "Batch size is now {$this->mBatchSize}.\n" ); + $this->output( "\tBatch size is now {$this->mBatchSize}.\n" ); } $batchPaths[$srcPathRel] = 1; // remove duplicates if ( count( $batchPaths ) >= $this->mBatchSize ) { @@ -117,6 +126,36 @@ class CopyFileBackend extends Maintenance { $this->copyFileBatch( array_keys( $batchPaths ), $backendRel, $src, $dst ); $batchPaths = array(); // done } + $this->output( "\tCopied $count file(s).\n" ); + + if ( $this->hasOption( 'syncviadelete' ) ) { + $this->output( "\tBuilding list of excess destination files..." ); + $delPathsRel = $this->getListingDiffRel( $dst, $src, $backendRel ); + $this->output( count( $delPathsRel ) . " file(s) need to be deleted.\n" ); + + $this->output( "\tDeleting file(s)...\n" ); + $count = 0; + $batchPaths = array(); + foreach ( $delPathsRel as $delPathRel ) { + // Check up on the rate file periodically to adjust the concurrency + if ( $rateFile && ( !$count || ( $count % 500 ) == 0 ) ) { + $this->mBatchSize = max( 1, (int)file_get_contents( $rateFile ) ); + $this->output( "\tBatch size is now {$this->mBatchSize}.\n" ); + } + $batchPaths[$delPathRel] = 1; // remove duplicates + if ( count( $batchPaths ) >= $this->mBatchSize ) { + $this->delFileBatch( array_keys( $batchPaths ), $backendRel, $dst ); + $batchPaths = array(); // done + } + ++$count; + } + if ( count( $batchPaths ) ) { // left-overs + $this->delFileBatch( array_keys( $batchPaths ), $backendRel, $dst ); + $batchPaths = array(); // done + } + + $this->output( "\tDeleted $count file(s).\n" ); + } if ( $subDir != '' ) { $this->output( "Finished container '$container', directory '$subDir'.\n" ); @@ -125,15 +164,58 @@ class CopyFileBackend extends Maintenance { } } - $this->output( "Done [$count file(s)].\n" ); + $this->output( "Done.\n" ); } + /** + * @param FileBackend $src + * @param FileBackend $dst + * @param string $backendRel + * @return array (rel paths in $src minus those in $dst) + */ + protected function getListingDiffRel( FileBackend $src, FileBackend $dst, $backendRel ) { + $srcPathsRel = $src->getFileList( array( + 'dir' => $src->getRootStoragePath() . "/$backendRel" ) ); + if ( $srcPathsRel === null ) { + $this->error( "Could not list files in source container.", 1 ); // die + } + $dstPathsRel = $dst->getFileList( array( + 'dir' => $dst->getRootStoragePath() . "/$backendRel" ) ); + if ( $dstPathsRel === null ) { + $this->error( "Could not list files in destination container.", 1 ); // die + } + // Get the list of destination files + $relFilesDstSha1 = array(); + foreach ( $dstPathsRel as $dstPathRel ) { + $relFilesDstSha1[sha1( $dstPathRel )] = 1; + } + unset( $dstPathsRel ); // free + // Get the list of missing files + $missingPathsRel = array(); + foreach ( $srcPathsRel as $srcPathRel ) { + if ( !isset( $relFilesDstSha1[sha1( $srcPathRel )] ) ) { + $missingPathsRel[] = $srcPathRel; + } + } + unset( $srcPathsRel ); // free + + return $missingPathsRel; + } + + /** + * @param array $srcPathsRel + * @param string $backendRel + * @param FileBackend $src + * @param FileBackend $dst + * @return void + */ protected function copyFileBatch( array $srcPathsRel, $backendRel, FileBackend $src, FileBackend $dst ) { $ops = array(); $fsFiles = array(); $copiedRel = array(); // for output message + $wikiId = $src->getWikiId(); // Download the batch of source files into backend cache... if ( $this->hasOption( 'missingonly' ) ) { @@ -144,8 +226,8 @@ class CopyFileBackend extends Maintenance { $t_start = microtime( true ); $fsFiles = $src->getLocalReferenceMulti( array( 'srcs' => $srcPaths, 'latest' => 1 ) ); $ellapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 ); - $this->output( "\nDownloaded these file(s) [{$ellapsed_ms}ms]:\n" . - implode( "\n", $srcPaths ) . "\n\n" ); + $this->output( "\n\tDownloaded these file(s) [{$ellapsed_ms}ms]:\n\t" . + implode( "\n\t", $srcPaths ) . "\n\n" ); } // Determine what files need to be copied over... @@ -153,22 +235,30 @@ class CopyFileBackend extends Maintenance { $srcPath = $src->getRootStoragePath() . "/$backendRel/$srcPathRel"; $dstPath = $dst->getRootStoragePath() . "/$backendRel/$srcPathRel"; if ( $this->hasOption( 'utf8only' ) && !mb_check_encoding( $srcPath, 'UTF-8' ) ) { - $this->error( "Detected illegal (non-UTF8) path for $srcPath." ); + $this->error( "$wikiId: Detected illegal (non-UTF8) path for $srcPath." ); continue; - } elseif ( $this->filesAreSame( $src, $dst, $srcPath, $dstPath ) ) { - $this->output( "Already have $srcPathRel.\n" ); + } elseif ( !$this->hasOption( 'missingonly' ) + && $this->filesAreSame( $src, $dst, $srcPath, $dstPath ) ) + { + $this->output( "\tAlready have $srcPathRel.\n" ); continue; // assume already copied... } $fsFile = array_key_exists( $srcPath, $fsFiles ) ? $fsFiles[$srcPath] : $src->getLocalReference( array( 'src' => $srcPath, 'latest' => 1 ) ); if ( !$fsFile ) { - $this->error( "Could not get local copy of $srcPath.", 1 ); // die + $src->clearCache( array( $srcPath ) ); + if ( $src->fileExists( array( 'src' => $srcPath, 'latest' => 1 ) ) === false ) { + $this->error( "$wikiId: File '$srcPath' was listed but does not exist." ); + } else { + $this->error( "$wikiId: Could not get local copy of $srcPath." ); + } + continue; } elseif ( !$fsFile->exists() ) { // FSFileBackends just return the path for getLocalReference() and paths with // illegal slashes may get normalized to a different path. This can cause the // local reference to not exist...skip these broken files. - $this->error( "Detected possible illegal path for $srcPath." ); + $this->error( "$wikiId: Detected possible illegal path for $srcPath." ); continue; } $fsFiles[] = $fsFile; // keep TempFSFile objects alive as needed @@ -176,7 +266,7 @@ class CopyFileBackend extends Maintenance { $status = $dst->prepare( array( 'dir' => dirname( $dstPath ), 'bypassReadOnly' => 1 ) ); if ( !$status->isOK() ) { $this->error( print_r( $status->getErrorsArray(), true ) ); - $this->error( "Could not copy $srcPath to $dstPath.", 1 ); // die + $this->error( "$wikiId: Could not copy $srcPath to $dstPath.", 1 ); // die } $ops[] = array( 'op' => 'store', 'src' => $fsFile->getPath(), 'dst' => $dstPath, 'overwrite' => 1 ); @@ -193,26 +283,75 @@ class CopyFileBackend extends Maintenance { $ellapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 ); if ( !$status->isOK() ) { $this->error( print_r( $status->getErrorsArray(), true ) ); - $this->error( "Could not copy file batch.", 1 ); // die + $this->error( "$wikiId: Could not copy file batch.", 1 ); // die } elseif ( count( $copiedRel ) ) { - $this->output( "\nCopied these file(s) [{$ellapsed_ms}ms]:\n" . - implode( "\n", $copiedRel ) . "\n\n" ); + $this->output( "\n\tCopied these file(s) [{$ellapsed_ms}ms]:\n\t" . + implode( "\n\t", $copiedRel ) . "\n\n" ); + } + } + + /** + * @param array $dstPathsRel + * @param string $backendRel + * @param FileBackend $dst + * @return void + */ + protected function delFileBatch( + array $dstPathsRel, $backendRel, FileBackend $dst + ) { + $ops = array(); + $deletedRel = array(); // for output message + $wikiId = $dst->getWikiId(); + + // Determine what files need to be copied over... + foreach ( $dstPathsRel as $dstPathRel ) { + $dstPath = $dst->getRootStoragePath() . "/$backendRel/$dstPathRel"; + $ops[] = array( 'op' => 'delete', 'src' => $dstPath ); + $deletedRel[] = $dstPathRel; + } + + // Delete the batch of source files... + $t_start = microtime( true ); + $status = $dst->doQuickOperations( $ops, array( 'bypassReadOnly' => 1 ) ); + if ( !$status->isOK() ) { + sleep( 10 ); // wait and retry copy again + $status = $dst->doQuickOperations( $ops, array( 'bypassReadOnly' => 1 ) ); + } + $ellapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 ); + if ( !$status->isOK() ) { + $this->error( print_r( $status->getErrorsArray(), true ) ); + $this->error( "$wikiId: Could not delete file batch.", 1 ); // die + } elseif ( count( $deletedRel ) ) { + $this->output( "\n\tDeleted these file(s) [{$ellapsed_ms}ms]:\n\t" . + implode( "\n\t", $deletedRel ) . "\n\n" ); } } + /** + * @param FileBackend $src + * @param FileBackend $dst + * @param string $sPath + * @param string $dPath + * @return bool + */ protected function filesAreSame( FileBackend $src, FileBackend $dst, $sPath, $dPath ) { $skipHash = $this->hasOption( 'skiphash' ); + $srcStat = $src->getFileStat( array( 'src' => $sPath ) ); + $dPathSha1 = sha1( $dPath ); + $dstStat = isset( $this->statCache[$dPathSha1] ) + ? $this->statCache[$dPathSha1] + : $dst->getFileStat( array( 'src' => $dPath ) ); return ( - ( $src->fileExists( array( 'src' => $sPath, 'latest' => 1 ) ) - === $dst->fileExists( array( 'src' => $dPath, 'latest' => 1 ) ) // short-circuit - ) && ( $src->getFileSize( array( 'src' => $sPath, 'latest' => 1 ) ) - === $dst->getFileSize( array( 'src' => $dPath, 'latest' => 1 ) ) // short-circuit - ) && ( $skipHash || ( $src->getFileSha1Base36( array( 'src' => $sPath, 'latest' => 1 ) ) + is_array( $srcStat ) // sanity check that source exists + && is_array( $dstStat ) // dest exists + && $srcStat['size'] === $dstStat['size'] + && ( !$skipHash || $srcStat['mtime'] <= $dstStat['mtime'] ) + && ( $skipHash || $src->getFileSha1Base36( array( 'src' => $sPath, 'latest' => 1 ) ) === $dst->getFileSha1Base36( array( 'src' => $dPath, 'latest' => 1 ) ) - ) ) + ) ); } } $maintClass = 'CopyFileBackend'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/copyJobQueue.php b/maintenance/copyJobQueue.php new file mode 100644 index 00000000..e833115b --- /dev/null +++ b/maintenance/copyJobQueue.php @@ -0,0 +1,99 @@ +<?php +/** + * Copy all jobs from one job queue system to another. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Maintenance + */ + +require_once __DIR__ . '/Maintenance.php'; + +/** + * Copy all jobs from one job queue system to another. + * This uses an ad-hoc $wgJobQueueMigrationConfig setting, + * which is a map of queue system names to JobQueue::factory() parameters. + * The parameters should not have wiki or type settings and thus partial. + * + * @ingroup Maintenance + */ +class CopyJobQueue extends Maintenance { + public function __construct() { + parent::__construct(); + $this->mDescription = "Copy jobs from one queue system to another."; + $this->addOption( 'src', 'Key to $wgJobQueueMigrationConfig for source', true, true ); + $this->addOption( 'dst', 'Key to $wgJobQueueMigrationConfig for destination', true, true ); + $this->addOption( 'type', 'Types of jobs to copy (use "all" for all)', true, true ); + $this->setBatchSize( 500 ); + } + + public function execute() { + global $wgJobQueueMigrationConfig; + + $srcKey = $this->getOption( 'src' ); + $dstKey = $this->getOption( 'dst' ); + + if ( !isset( $wgJobQueueMigrationConfig[$srcKey] ) ) { + $this->error( "\$wgJobQueueMigrationConfig not set for '$srcKey'.", 1 ); + } elseif ( !isset( $wgJobQueueMigrationConfig[$dstKey] ) ) { + $this->error( "\$wgJobQueueMigrationConfig not set for '$dstKey'.", 1 ); + } + + $types = ( $this->getOption( 'type' ) === 'all' ) + ? JobQueueGroup::singleton()->getQueueTypes() + : array( $this->getOption( 'type' ) ); + + foreach ( $types as $type ) { + $baseConfig = array( 'type' => $type, 'wiki' => wfWikiID() ); + $src = JobQueue::factory( $baseConfig + $wgJobQueueMigrationConfig[$srcKey] ); + $dst = JobQueue::factory( $baseConfig + $wgJobQueueMigrationConfig[$dstKey] ); + + list( $total, $totalOK ) = $this->copyJobs( $src, $dst, $src->getAllQueuedJobs() ); + $this->output( "Copied $totalOK/$total queued $type jobs.\n" ); + + list( $total, $totalOK ) = $this->copyJobs( $src, $dst, $src->getAllDelayedJobs() ); + $this->output( "Copied $totalOK/$total delayed $type jobs.\n" ); + } + } + + protected function copyJobs( JobQueue $src, JobQueue $dst, $jobs ) { + $total = 0; + $totalOK = 0; + $batch = array(); + foreach ( $jobs as $job ) { + ++$total; + $batch[] = $job; + if ( count( $batch ) >= $this->mBatchSize ) { + if ( $dst->push( $batch ) ) { + $totalOK += count( $batch ); + } + $batch = array(); + $dst->waitForBackups(); + } + } + if ( count( $batch ) ) { + if ( $dst->push( $batch ) ) { + $totalOK += count( $batch ); + } + $dst->waitForBackups(); + } + return array( $total, $totalOK ); + } +} + +$maintClass = 'CopyJobQueue'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/createAndPromote.php b/maintenance/createAndPromote.php index 81fbbb3d..aa25ee60 100644 --- a/maintenance/createAndPromote.php +++ b/maintenance/createAndPromote.php @@ -1,6 +1,6 @@ <?php /** - * Creates an account and grant it administrator rights. + * Creates an account and grants it rights. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,26 +23,26 @@ * @author Pablo Castellano <pablo@anche.no> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** - * Maintenance script to create an account and grant it administrator rights. + * Maintenance script to create an account and grant it rights. * * @ingroup Maintenance */ class CreateAndPromote extends Maintenance { - static $permitRoles = array( 'sysop', 'bureaucrat' ); + static $permitRoles = array( 'sysop', 'bureaucrat', 'bot' ); public function __construct() { parent::__construct(); $this->mDescription = "Create a new user account and/or grant it additional rights"; $this->addOption( "force", "If acccount exists already, just grant it rights or change password." ); - foreach( self::$permitRoles as $role ) { + foreach ( self::$permitRoles as $role ) { $this->addOption( $role, "Add the account to the {$role} group" ); } $this->addArg( "username", "Username of new user" ); - $this->addArg( "password", "Password to set (not required if --force is used)", false); + $this->addArg( "password", "Password to set (not required if --force is used)", false ); } public function execute() { @@ -60,10 +60,10 @@ class CreateAndPromote extends Maintenance { if ( $exists && !$force ) { $this->error( "Account exists. Perhaps you want the --force option?", true ); - } else if ( !$exists && !$password ) { + } elseif ( !$exists && !$password ) { $this->error( "Argument <password> required!", false ); $this->maybeHelp( true ); - } else if ( $exists ) { + } elseif ( $exists ) { $inGroups = $user->getGroups(); } @@ -72,7 +72,7 @@ class CreateAndPromote extends Maintenance { if ( $exists && !$password && count( $promotions ) === 0 ) { $this->output( "Account exists and nothing to do.\n" ); return; - } else if ( count( $promotions ) !== 0 ) { + } elseif ( count( $promotions ) !== 0 ) { $promoText = "User:{$username} into " . implode( ', ', $promotions ) . "...\n"; if ( $exists ) { $this->output( wfWikiID() . ": Promoting $promoText" ); @@ -114,4 +114,4 @@ class CreateAndPromote extends Maintenance { } $maintClass = "CreateAndPromote"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteArchivedFiles.inc b/maintenance/deleteArchivedFiles.inc index 792ee6c6..d58e9a40 100644 --- a/maintenance/deleteArchivedFiles.inc +++ b/maintenance/deleteArchivedFiles.inc @@ -42,7 +42,7 @@ class DeleteArchivedFilesImplementation { $group = $row->fa_storage_group; $id = $row->fa_id; $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key; - if( isset( $row->fa_sha1 ) ) { + if ( isset( $row->fa_sha1 ) ) { $sha1 = $row->fa_sha1; } else { // old row, populate from key diff --git a/maintenance/deleteArchivedFiles.php b/maintenance/deleteArchivedFiles.php index 85ffc23b..ad7b54d0 100644 --- a/maintenance/deleteArchivedFiles.php +++ b/maintenance/deleteArchivedFiles.php @@ -24,8 +24,8 @@ * @author Aaron Schulz */ -require_once( __DIR__ . '/Maintenance.php' ); -require_once( __DIR__ . '/deleteArchivedFiles.inc' ); +require_once __DIR__ . '/Maintenance.php'; +require_once __DIR__ . '/deleteArchivedFiles.inc'; /** * Maintenance script to delete archived (non-current) files from the database. @@ -55,4 +55,4 @@ class DeleteArchivedFiles extends Maintenance { } $maintClass = "DeleteArchivedFiles"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteArchivedRevisions.php b/maintenance/deleteArchivedRevisions.php index 4b658bbb..ffd581c1 100644 --- a/maintenance/deleteArchivedRevisions.php +++ b/maintenance/deleteArchivedRevisions.php @@ -24,8 +24,8 @@ * @author Aaron Schulz */ -require_once( __DIR__ . '/Maintenance.php' ); -require_once( __DIR__ . '/deleteArchivedRevisions.inc' ); +require_once __DIR__ . '/Maintenance.php'; +require_once __DIR__ . '/deleteArchivedRevisions.inc'; /** * Maintenance script to delete archived (deleted from public) revisions @@ -59,4 +59,4 @@ class DeleteArchivedRevisions extends Maintenance { } $maintClass = "DeleteArchivedRevisions"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteBatch.php b/maintenance/deleteBatch.php index 936a52b8..c1cc03cd 100644 --- a/maintenance/deleteBatch.php +++ b/maintenance/deleteBatch.php @@ -28,7 +28,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to delete a batch of pages. @@ -121,4 +121,4 @@ class DeleteBatch extends Maintenance { } $maintClass = "DeleteBatch"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteDefaultMessages.php b/maintenance/deleteDefaultMessages.php index 4ab6d1d9..7d8c80e4 100644 --- a/maintenance/deleteDefaultMessages.php +++ b/maintenance/deleteDefaultMessages.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes all pages in the MediaWiki namespace @@ -51,7 +51,7 @@ class DeleteDefaultMessages extends Maintenance { ) ); - if( $dbr->numRows( $res ) == 0 ) { + if ( $dbr->numRows( $res ) == 0 ) { # No more messages left $this->output( "done.\n" ); return; @@ -86,4 +86,4 @@ class DeleteDefaultMessages extends Maintenance { } $maintClass = "DeleteDefaultMessages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteEqualMessages.php b/maintenance/deleteEqualMessages.php index 7048140b..81758913 100644 --- a/maintenance/deleteEqualMessages.php +++ b/maintenance/deleteEqualMessages.php @@ -19,7 +19,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes all pages in the MediaWiki namespace @@ -41,7 +41,7 @@ class DeleteEqualMessages extends Maintenance { * @param string|bool $langCode See --lang-code option. */ protected function fetchMessageInfo( $langCode, array &$messageInfo ) { - global $wgUser, $wgContLang; + global $wgContLang; if ( $langCode ) { $this->output( "\n... fetching message info for language: $langCode" ); @@ -70,7 +70,13 @@ class DeleteEqualMessages extends Maintenance { $default = wfMessage( $key )->inLanguage( $langCode )->useDatabase( false )->plain(); $messageInfo['relevantPages']++; - if ( $actual === $default ) { + + if ( + // Exclude messages that are empty by default, such as sitenotice, specialpage + // summaries and accesskeys. + $default !== '' && $default !== '-' && + $actual === $default + ) { $hasTalk = isset( $statuses['talks'][$key] ); $messageInfo['results'][] = array( 'title' => $key . $titleSuffix, @@ -152,6 +158,7 @@ class DeleteEqualMessages extends Maintenance { if ( !$user ) { $this->error( "Invalid username", true ); } + global $wgUser; $wgUser = $user; // Hide deletions from RecentChanges @@ -183,4 +190,4 @@ class DeleteEqualMessages extends Maintenance { } $maintClass = "DeleteEqualMessages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteImageMemcached.php b/maintenance/deleteImageMemcached.php index 3c8c5fdd..835de352 100644 --- a/maintenance/deleteImageMemcached.php +++ b/maintenance/deleteImageMemcached.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes image information from the object cache. @@ -59,13 +59,15 @@ class DeleteImageCache extends Maintenance { $total = $this->getImageCount(); foreach ( $res as $row ) { - if ( $i % $this->report == 0 ) + if ( $i % $this->report == 0 ) { $this->output( sprintf( "%s: %13s done (%s)\n", wfWikiID(), "$i/$total", wfPercent( $i / $total * 100 ) ) ); + } $md5 = md5( $row->img_name ); $wgMemc->delete( wfMemcKey( 'Image', $md5 ) ); - if ( $sleep != 0 ) + if ( $sleep != 0 ) { usleep( $sleep ); + } ++$i; } @@ -78,4 +80,4 @@ class DeleteImageCache extends Maintenance { } $maintClass = "DeleteImageCache"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteOldRevisions.php b/maintenance/deleteOldRevisions.php index 114aefd7..847d8634 100644 --- a/maintenance/deleteOldRevisions.php +++ b/maintenance/deleteOldRevisions.php @@ -22,7 +22,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes old (non-current) revisions from the database. @@ -100,4 +100,4 @@ class DeleteOldRevisions extends Maintenance { } $maintClass = "DeleteOldRevisions"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteOrphanedRevisions.php b/maintenance/deleteOrphanedRevisions.php index f0da9a82..f0a96928 100644 --- a/maintenance/deleteOrphanedRevisions.php +++ b/maintenance/deleteOrphanedRevisions.php @@ -24,7 +24,7 @@ * @todo More efficient cleanup of text records */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes revisions which refer to a nonexisting page. @@ -54,8 +54,9 @@ class DeleteOrphanedRevisions extends Maintenance { # Stash 'em all up for deletion (if needed) $revisions = array(); - foreach ( $res as $row ) + foreach ( $res as $row ) { $revisions[] = $row->rev_id; + } $count = count( $revisions ); $this->output( "found {$count}.\n" ); @@ -83,11 +84,12 @@ class DeleteOrphanedRevisions extends Maintenance { * @param $dbw DatabaseBase class (needs to be a master) */ private function deleteRevs( $id, &$dbw ) { - if ( !is_array( $id ) ) + if ( !is_array( $id ) ) { $id = array( $id ); + } $dbw->delete( 'revision', array( 'rev_id' => $id ), __METHOD__ ); } } $maintClass = "DeleteOrphanedRevisions"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteRevision.php b/maintenance/deleteRevision.php index ad6470d9..6bc0f7cd 100644 --- a/maintenance/deleteRevision.php +++ b/maintenance/deleteRevision.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes one or more revisions by moving them @@ -85,4 +85,4 @@ class DeleteRevision extends Maintenance { } $maintClass = "DeleteRevision"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/deleteSelfExternals.php b/maintenance/deleteSelfExternals.php index da220d64..a0976228 100644 --- a/maintenance/deleteSelfExternals.php +++ b/maintenance/deleteSelfExternals.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that deletes self-references to $wgServer @@ -47,10 +47,12 @@ class DeleteSelfExternals extends Maintenance { . $db->buildLike( $wgServer . '/', $db->anyString() ), $this->mBatchSize ); $this->output( "Deleting a batch\n" ); $db->query( $q ); - if ( !$db->affectedRows() ) return; + if ( !$db->affectedRows() ) { + return; + } } } } $maintClass = "DeleteSelfExternals"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/dev/includes/router.php b/maintenance/dev/includes/router.php index 1d5070b1..a3cc0ba3 100644 --- a/maintenance/dev/includes/router.php +++ b/maintenance/dev/includes/router.php @@ -25,8 +25,8 @@ if ( PHP_SAPI != 'cli-server' ) { die( "This script can only be run by php's cli-server sapi." ); } -ini_set('display_errors', 1); -error_reporting(E_ALL); +ini_set( 'display_errors', 1 ); +error_reporting( E_ALL ); if ( isset( $_SERVER["SCRIPT_FILENAME"] ) ) { # Known resource, sometimes a script sometimes a file @@ -58,7 +58,7 @@ if ( $ext == 'php' || $ext == 'php5' ) { # We use require and return true here because when you return false # the php webserver will discard post data and things like login # will not function in the dev environment. - require( $file ); + require $file; return true; } $mime = false; @@ -83,16 +83,16 @@ if ( $mime ) { # This way we can serve things like .svg files that the built-in # PHP webserver doesn't understand. # ;) Nicely enough we just happen to bundle a mime.types file - $f = fopen($file, 'rb'); + $f = fopen( $file, 'rb' ); if ( preg_match( '#^text/#', $mime ) ) { # Text should have a charset=UTF-8 (php's webserver does this too) - header("Content-Type: $mime; charset=UTF-8"); + header( "Content-Type: $mime; charset=UTF-8" ); } else { - header("Content-Type: $mime"); + header( "Content-Type: $mime" ); } - header("Content-Length: " . filesize($file)); + header( "Content-Length: " . filesize( $file ) ); // Stream that out to the browser - fpassthru($f); + fpassthru( $f ); return true; } diff --git a/maintenance/dictionary/mediawiki.dic b/maintenance/dictionary/mediawiki.dic new file mode 100644 index 00000000..164b5b05 --- /dev/null +++ b/maintenance/dictionary/mediawiki.dic @@ -0,0 +1,4556 @@ +ænglisc +ævar +&add +& +&bar +&sim +&url +ABNF +API +Aacute +Aborted +Abuse +Account +Accum +Acirc +Action +Activity +Agrave +All +Allocations +Ancientpages +Anim +Api +Apitestsysop +Apitestuser +Aring +Article +As +Atilde +Auml +Autopromote +BACKCOMPAT +Backlinks +Blacklist +Block +Blocked +Blocks +Bodytext +Broken +COMPUTERNAME +CRLF +CURLOPT +Campaign +Capture +Categories +Category +Ccedil +Central +Changes +Check +Click +Client +Clientfor +Colorer +Compare +Config +Console +Continue +Contribs +Contributions +Conversiontable +Coordinates +Create +Creation +Cview +DDLMODE +DWIM +DWIMD +Daily +Dbkeyform +Deadendpages +Debugtext +Delete +Deletedrevs +Denied +Dfile +Double +Duplicate +EAGAIN +EBML +ECMA +EDITFILTERMERGED +EINPROGRESS +EINTR +EOCDR +ETAG +Eacute +Ecirc +Edit +Editor +Education +Egrave +Ehcache +Elig +Email +Empty +End +English +Enlist +Euml +Eval +Events +Exists +Expand +Expression +Ext +External +Extracts +Extraneous +FFFD +FOLLOWLOCATION +Failure +Featured +Feed +Feedback +Feedbackv +Feeds +Fewestrevisions +Ffile +File +Filearchive +Filedelete +Files +Filter +Filters +Flag +Flagged +GI +GRAPHEME +Gadget +Gadgets +Geo +Get +Global +Groups +HEA +HTM +Hardblock +Help +Helpful +ID +IPTC +IWBacklinks +IWLinks +Iacute +Icirc +Igrave +Illegal +Image +Images +Implict +Import +Info +Invalidateemail +Isarticle +Item +Iuml +LOCALISATIONCACHE +Lang +Lastmod +Links +Linktags +List +Listredirects +Living +Log +Login +Logout +Logs +Lonelypages +Longpages +Love +Ltitle +MSVC +Mark +Match +Matrix +Members +Mesg +Messages +Metatags +Mobile +Mostcategories +Mostimages +Mostinterwikis +Mostlinked +Mostlinkedcategories +Mostlinkedtemplates +Mostrevisions +Move +Mssql +Mwstore +Myuploads +NEWPAGE +NOTIC +Name +Need +No +Noscript +Not +Notalk +Notice +Notification +Ntilde +Oacute +Ocirc +Ograve +Oldreviewedpages +Open +Options +Oslash +Otilde +Ouml +PAGEEDITDATE +PAGEEDITOR +PAGEEDITTIME +PAGEINTRO +PAGEMINOREDIT +PAGESUMMARY +PARSEHUGE +PARSERFIRSTCALLINIT +PHPTAL +PMID +Page +Pages +Param +Parse +Parsers +Pass +Passpass +Patrol +People +Plugin +Possible +Program +Props +Protect +Protected +Protectexpiry +Protectother +Protectreason +Protectreasonother +Purge +Query +Queued +Random +Rapid +Ratings +Raw +Recent +Redirects +Redis +Referer +Refresh +Regexlike +Replacer +Reset +Resursive +Revert +Review +Revisions +Rollback +Rsd +SEGSIZE +STDERR +SYSDBA +Scaron +Scribunto +Search +Section +Set +Shortpages +Site +Siteinfo +Solr +Stabilize +Stash +Stats +Status +Success +Syntax +TMPDIR +TOOLBOXEND +TRANSLIT +Tagging +Tags +Template +Templates +Textform +Tfile +Throttled +Timestamp +Title +Titles +Token +Tokens +Tracking +Transcode +Triage +UNWATCHURL +Uacute +Ucirc +Ugrave +Unblock +Uncategorizedcategories +Uncategorizedimages +Uncategorizedpages +Uncategorizedtemplates +Undelete +Unusedcategories +Unusedimages +Unusedtemplates +Unwatchedpages +Upload +Urlform +Usage +User +Usercreate +Userdir +Userlang +Userrights +Users +Useruser +Ustart +Uuml +Value +Video +View +Visual +WATCHINGUSERNAME +WEBPVP +Wantedcategories +Wantedfiles +Wantedpages +Wantedtemplates +Warning +Watch +Watchingusers +Watchlist +Wiki +Wikibase +Withoutinterwiki +Wrong +XX +Xml +YYYY +YYYYMMDDHHMMSS +Yacute +Yuml +\ +a +aa +aacute +abbrv +abcdefghijklmnopqrstuvwxyz +abf +aboutpage +aboutsite +abusefilter +abusefiltercheckmatch +abusefilterchecksyntax +abusefilterevalexpression +abusefilters +abusefilterunblockautopromote +abuselog +abusive +ac +acad +accel +acceptlang +accessdenied +accesskey +accesskeycache +accesskeys +accessors +acchits +account +accountcreator +accum +acirc +aclimit +acprefix +action +actioncomplete +actionhidden +actions +actiontext +actionthrottled +actionthrottledtext +actiontoken +activeusers +activity +acuxvalidate +add +addablegroups +addbegin +addedline +addedwatchtext +addergroup +addergroups +addin +adding +additional +addr +address +addresses +addsection +addstudent +admin +administrator +adnum +adrelid +adsrc +advancedediting +advancedrc +advancedrendering +advancedsearchoptions +advancedwatchlist +aelig +af +afl +aft +afttest +afvf +age +aggregators +agrave +ahandler +ahttp +ai +aifc +aiff +aiprop +ajaxwatch +al +alefsym +algo +algos +all +all's +allcategories +alldata +alle +allexamples +allhidden +allimages +allimit +alllinks +alllogstext +allmessages +allmonths +allowedctypes +allowedonly +allowemail +allowsduplicates +allowusertalk +allpages +allpagesbadtitle +allpagesprefix +allpagesredirect +allpagessubmit +allrev +alltitles +alltransclusions +allusers +aloption +alprefix +alreadyblocked +alreadydone +alreadyexists +alreadyrolled +alunique +am +anchor +anchorclose +anchorencode +and +andconvert +andtitle +anon +anoneditwarning +anonlogin +anonnotice +anononly +anonpreviewwarning +anontalk +anontalkpagetext +anontoken +anonuserpage +anonymous +anti +antispoof +antivirus +anymap +ap +apcond +apdir +api +api's +apibase +apihelp +apihighlimits +apis +aplimit +apnamespace +apng +apos +appendnotsupported +appendtext +apprefix +approve +aprops +aqbt +aqct +archivename +aren +args +argsarams +aring +arnfjörð +article +articleexists +articlefeedbackv +articleid +articlelink +articlepage +articlepath +articles +aryeh +asc +ascending +asctime +asdf +aspx +assert +astriks +asymp +async +asynccopyuploaddisabled +asyncdownload +at +atend +atext +atid +atilde +atime +atlimit +atoi +atom +atprefix +atthasdef +attibs +attibute +attlen +attname +attnum +attrdef +attrelid +attrib +attribs +attributename +attrs +atttypid +atunique +au +auml +authplugins +autoaccount +autobiography +autoblock +autoblocked +autoblockedtext +autoblocker +autoblockid +autoblocking +autoblockip +autoblocks +autocad +autocomment +autocomments +autocomplete +autoconfirm +autoconfirmed +autocreate +autocreated +autocreation +autodetection +autoflag +autofocus +autogen +autogenerated +autohide +autoload +autoloader +autoloaders +autoloading +automagically +automatic +autonym +autopatrol +autoplay +autopromote +autopromoted +autopromotion +autoreview +autoreviewer +autoreviewrestore +autosumm +autosummaries +autosummary +axto +azərbaycanca +backends +backlink +backlinks +backlinksubtitle +backported +backslashed +backtraces +bad +badaccess +badarticleerror +badcontinue +baddiff +bademail +badfilename +badformat +badgenerator +badhookmsg +badinterwiki +badip +badipaddress +badkey +badmd +badmime +badminpassword +badminuser +badnamespace +badoption +badparams +badport +badretype +badrevids +badsig +badsiglength +badsyntax +badtag +badtimestamp +badtitle +badtitletext +badtoken +badtype +badupload +baduser +badversion +balancer +balancers +banjar +barstein +base +basefont +basename +basepagename +basepagenamee +basetimestamp +bashkir +bashpid +bcancel +bceffd +bcmath +bcompress +bcpio +bdop +bdquo +becampus +beinstructor +belarusian +beonline +bereviewer +berror +bestq +besttype +bg +bgcolor +bgzip +bidi +bigdelete +binhex +bitdepth +bitfield +bitfields +bitmask +bjarmason +bk +bkey +bkinvalidparammix +bkmissingparam +bkusers +bl +blanking +blanknamespace +blankpage +blegh +bleh +blinvalidparammix +blksize +blmissingparam +block +blockable +blocked +blockedasrange +blockedby +blockedbyid +blockedemailuser +blockedexpiry +blockedfrommail +blockednoreason +blockedreason +blockedtext +blockedtitle +blockemail +blockexpiry +blockid +blockinfo +blockip +blocklink +blocklogentry +blocklogpage +blocklogtext +blockme +blockquote +blockreason +blocks +blocktoken +bloggs +blogs +blogspot +bltitle +bluelink +bluelinks +bmwschema +bmysql +bname +bodycontent +boldening +bolding +booksources +bool +boolean +borderhack +bot +botedit +boteditletter +bots +bottom +bottomscripts +bpassword +bpatch +bpchar +bport +bprefix +broeck +brokenlibxml +brokenredirects +brokenredirectstext +browsearchive +brvbar +bserver +bservers +bssl +btestpassword +btestuser +btype +bucket +bucketcount +bugfix +bugfixes +buglist +bugzilla +buildpath +buildpathentry +bulgakov +bulkdelcourses +bulkdelorgs +bureaucrat +buser +by +byemail +byid +bytea +bytesleft +bytesread +bytevalue +cacheable +cached +cachedcount +cachedsidebar +cachedspecial +cachedtimestamp +calimit +callargs +campaign +campus +cancelto +cannotdelete +cannotundelete +canonicalised +canonicalization +canonicalize +canonicalizes +canonicalizing +canremember +canreset +cansecurelogin +cantblock +cantcreate +cantdelete +cantedit +cantexecute +canthide +cantimport +cantmove +cantmovefile +cantopenfile +cantoverwrite +cantrollback +cantsend +cantunblock +cantundelete +capitalizeallnouns +captchaid +captchas +captchaword +cascade +cascadeable +cascadeon +cascadeprotected +cascadeprotectedwarning +cascading +cascadingness +categories +categories's +categorieshtml +category +categoryfinder +categoryinfo +categorylinks +categorymembers +categorypage +categoryviewer +catids +catlinks +catpage +catrope +cattitles +ccedil +ccme +ccmeonemails +cdab +cdel +cdlink +cedil +ceebc +cellpadding +cellspacing +central +centralauth +centralnotice +centralnoticeallocations +centralnoticelogs +centralnoticequerycampaign +cgroup +cgroups +change +change's +changeablegroups +changed +changedby +changedorcreated +changeemail +changelog +changeslist +changing +characters +chardiff +charoff +chars +checkfreq +checkmatrix +checkstatus +checkuser +checkuserlog +chgrp +childs +chillu +chmoding +choicesstring +chrs +chunk +chunked +chunking +ci +cidr +cidrtoobroad +circ +citeseer +ckers +ckey +cl +clamav +clamscan +classname +clcategorie +cldir +cldr +clear +clearable +clearyourcache +clfrom +clickjacking +clicktracking +clientfor +clientpool +cllimit +clober +closed +clto +cm +cminvalidparammix +cmmissingparam +cmnamespace +cmtitle +co +code +codemap +codepoint +codestr +coi +colgroup +collapsable +collectionsaveascommunitypage +collectionsaveasuserpage +colname +cologneblue +colonseparator +colorer +colspan +commafy +commafying +comment +commentedit +commenthidden +comments +commitdiff +commoncssjs +compactpro +compare +compat +complete +cond +condcomment +condeferrable +condeferred +conds +config +confirmdeletetext +confirmed +confirmedittext +confirmemail +confirmrecreate +conflimit +confstr +conkey +conname +conrelid +console +content +contentformat +contenthandler +contentlanguage +contentless +contentmodel +contenttoobig +continue +contribs +contribslink +conttitle +contype +conv +converttitles +convmv +cookieprefix +cooltalk +coord +coordinates +copyrightico +copyrightpage +copyrightwarning +copyuploadbaddomain +copyuploaddisabled +copyvio +copywarn +cors +couldn +counter +countmsg +country +course +courseid +cpio +cprefs +cprotected +crarr +crashbug +create +createaccount +createonly +createpage +createtalk +creationsort +creativecommons +creditspage +crocker +cryptrand +csize +csrf +css +cssclass +csslinks +cssprefs +cta +ctime +ctor +ctype +cu +cul +curation +curdiff +curid +curlink +curren +currentarticle +currentbrowser +currentday +currentdayname +currentdow +currenthour +currentmonth +currentmonthabbrev +currentmonthname +currentmonthnamegen +currentrev +currentrevisionlink +currenttime +currenttimestamp +currentversion +currentweek +currentyear +customcssprotected +customised +customjsprotected +cut +cyber +cygwin +cyrl +d'oh +dadedad +dairiki +danga +danielc +darr +datalen +dataset +datasets +datasize +datatable +datatype +datedefault +dateformat +dateheader +dateopts +daysago +dbcnt +dbconnect +dberrortext +dbg +dbgfm +dbkey +dbkeys +dbks +dbname +dbrepllag +dbsettings +dbtype +dbversion +ddjvu +de +deadend +deadendpagestext +deadenpages +dealies +debughtml +decline +declined +decls +decr +decrease +default +defaultcontentmodel +defaultmessagetext +defaultmissing +defaultns +defaultsort +defaultval +deferr +definite +deflimit +defs +deja +delete +deleteall +deletecomment +deleteconfirm +deleted +deletedhistory +deletedline +deletedonly +deletedrevision +deletedrevs +deletedtext +deletedwhileediting +deleteeducation +deleteglobalaccount +deletelogentry +deleteone +deleteotherreason +deletepage +deletereason +deletereasonotherlist +deleterevision +deleteset +deletethispage +deletetoken +deletion +deletionlog +delim +dellogpage +dellogpagetext +delundel +deprecated +deps +depth +dequeue +dequeued +dequeueing +dequeues +derivatives +desc +descending +description +descriptionmsg +descriptionmsgparams +descriptionurl +deserialization +deserialize +dest +detail +details +devangari +devel +df +dflt +dhtml +diams +didn +diff +diff's +diffchange +diffhist +difflink +diffonly +difftext +diffto +difftocontent +difftotext +dim +dimensions +dir +direction +directionmark +directorycreateerror +directorynotreadableerror +directoryreadonlyerror +dirmark +dirname +disabled +disabledtranscode +disablemail +disablepp +disablesuggest +disclaimerpage +diskussion +displayname +displayrc +displaysearchoptions +displaytitle +displaytitles +displaywatchlist +distclean +distro +djava +djob +djvu +djvudump +djvulibre +djvutoxml +djvutxt +djvuxml +djvuzone +dkjsagfjsgashfajsh +dlen +dltk +dmoz +dnsbl +dnsblacklist +dnumber +docm +docroot +doctype +doctypes +docx +dodiff +doesn +domain +domainnames +domainpart +domainparts +domas +doms +dotdotcount +dotm +dotsc +dotsi +dotsm +dotso +dotwise +dotx +doubleclick +doublequote +doxygen +dpos +dr +dropdown +dump +dumpfm +dupfunc +duplicatefiles +duplicatesoffile +dvips +dwfx +dwhitelist +e +eacute +earth +eauth +ecirc +ecmascript +edit +editbutton +editconflict +editconflicts +editcount +editfont +editform +edithelp +edithelppage +edithelpurl +editingcomment +editinginterface +editingold +editingsection +editinterface +editintro +edititis +editlink +editmyoptions +editmyprivateinfo +editmyusercss +editmyuserjs +editmywatchlist +editnotice +editnotsupported +editondblclick +editor +editownusertalk +editpage +editprotected +editreasons +editredlink +editrestriction +edits +editsection +editsectionhint +editsectiononrightclick +editsemiprotected +editsonly +editthispage +edittime +edittoken +edittools +editurl +editusercss +editusercssjs +edituserjs +edoe +egrave +ehcache +ei +eich +eiinvalidparammix +eimissingparam +eititle +el +elapsedreal +elemname +elink +eltitle +email +emailable +emailaddress +emailauthenticated +emailauthentication +emailauthenticationclass +emailcapture +emailconfirm +emailconfirmed +emailconfirmlink +emaildisabled +emailling +emaillink +emailnotauthenticated +emailtoken +emailuser +embeddedin +empty +emptyfile +emptynewsection +emptypage +emsenhuber +emsp +en +enabled +enabledonly +enableparser +encapsed +enctype +end +endcode +endcond +endian +endid +endl +endsortkey +endsortkeyprefix +endtime +endverbatim +enhancedchanges +enlist +enotif +enotifminoredits +enotifrevealaddr +enotifusertalkpages +enotifwatchlistpages +enqueueing +enroll +ensp +entirewatchlist +entityid +envcmd +enwiki +eocdr +ep +eparticle +epcampus +epcoordinator +epinstructor +eponline +erevoke +errno +error +errorbox +errormessage +errorpagetitle +errors +errorstr +errortext +errorunknown +errstr +es +escapenoentities +escapeshellarg +esearch +español +española +etag +eu +euml +event +eventid +ex +exampleextension +examples +excludegroup +excludepage +excludeuser +executables +exempt +existingwiki +exists +exiv +expandtab +expandtemplates +expandurl +experiment +expertise +expiry +expiryarray +explainconflict +export +exportnowrap +exportxml +expression +exptime +extauth +extendwatchlist +extensionname +extensions +extensiontags +external +externaldberror +externaldiff +externaledit +externaleditor +externallinks +externalstore +extet +extiw +extlink +extlinks +extracts +extradata +extrafields +extraq +extratags +exturlusage +extuser +exxaammppllee +fa +facto +failback +failover +failsafe +fallbacks +false +falsy +fancysig +fastcgi +faux +favicon +fclose +fdef +fdff +feature +featured +featuredfeed +feed +feed's +feedback +feedbackid +feedcontributions +feedformat +feeditems +feedlink +feedlinks +feedurl +feedwatchlist +feff +female +fetchfileerror +fffe +ffff +fffff +ffffff +fieldname +fieldset +fieldsets +file +filearchive +filebackend +filecache +filecopyerror +filedelete +filedeleteerror +fileexists +fileextensions +filehidden +filehist +filehistory +fileinfo +filejournal +filekey +filelinks +filemissing +filemover +filemtime +filename +filenames +filenotfound +filepage +filepath +filerenameerror +filerepo +filerevert +filerevisions +files +filesize +filesort +filesorts +filesystem's +filesystems +filetoc +filetoobig +filetype +filetypemismatch +fileversions +filter +filterbots +filteriw +filterlanglinks +filterlocal +filterredir +filterwatched +findnext +finfo +firefox +firstname +firstrev +firsttime +fishbowl +fixme +fixup +flac +flag +flagconfig +flagged +flags +flagtype +flatlist +flds +float +fmttime +fname +fnof +foldmarker +foldmethod +followpolicy +footericon +footericons +footerlinks +fopen +for +forall +forbidden +forcearticlepath +forcebot +forceditsummary +forceeditsummary +forcelinkupdate +forcetoc +forcontent +formaction +format +formatmodules +formatted +formatters +formatting +formedness +formenctype +formnovalidate +formtype +forupdate +found +founder +fr +frac +frameless +framesets +frasl +fread +freedomdefined +freeform +freenode +frickin +from +fromdb +fromdbmaster +fromid +fromrev +fromrevid +fromtitle +frontends +fseek +fsockopen +fsync +ftp +fullhistory +fullpagename +fullpagenamee +fulluri +fullurl +funcname +functionhooks +functionname +futuresplash +fvalue +ga +gack +gadgetcategories +gadgets +gaid +gaifilterredir +gallerybox +gallerycaption +gallerytext +gapdir +gapfilterredir +gaplimit +gapprefix +garber +gblblock +gblock +gblrights +gc +gcldir +gcllimit +gender +general +generatexml +generator +geocoordinate +geosearch +gerrit +getcookie +getenv +getheader +getimagesize +getlink +getmac +getmarkashelpfulitem +getmypid +getrusage +gettimeofday +gettingstarted +gettoken +getuid +gfdl +ggp +ghostscript +gimpbaseenums +git +gitblit +gitdir +github +global +globalauth +globalblock +globalblocks +globalgroupmembership +globalgrouppermissions +globalgroups +globalsettings +globalunblock +globalusage +globaluserinfo +globe +gmail +gmdate +goodtitle +gopher +graymap +grayscale +greant +greymap +group +groupcounts +groupless +groupmember +grouppage +groupperms +groupprms +groups +growinglink +grxml +gs +gtar +gu +guesstimezone +gui +guid +gunblock +guser +gwicke +gzcompress +gzdeflate +gzencode +gzhandler +gzip +gzipped +gzipping +hacky +hansm +hant +hardblocks +hardcode +hardcoding +harr +hash +hashar +hashcheckfailed +hashsearchdisabled +hashtable +hashtables +hasmatch +hasmsg +hasn +hasrelated +headelement +headerpos +headhtml +headitems +headlinks +headscripts +height +hellip +help +helpful +helppage +helptext +helpurl +helpurls +helpwindow +hexdump +hexstring +hidden +hiddencat +hiddencategories +hiddencats +hide +hideanons +hidebots +hidediff +hideliu +hideminor +hidemyself +hidename +hidepatrolled +hideredirects +hiderevision +hideuser +hidpi +highlimit +highmax +highuse +hilfe +hiphop +histfirst +histlast +historyempty +historysubmit +historywarning +hit +hitcount +hitcounter +hits +hmac +hmtl +hobby +homelink +hookaborted +horohoe +hostnames +hours +hphp +hplist +hpos +hreflang +hslots +htaccess +htcp +html +htmlelements +htmlescaped +htmlform +htmlish +htmllist +htmlnest +htmlpair +htmlpairs +htmlsingle +htmlsingleallowed +htmlsingleonly +htmlspecialchars +htmltidy +http +httpaccept +httpbl +https +i +ia +iabn +iacute +icirc +icononly +iconv +icubench +icutest +id +idanduser +ids +ie's +ieinternals +ietf +iexcl +ifconfig +iframe +igbinary +iges +ignorewarnings +igrave +ii +iicontinue +iiprop +iiurlparam +iiurlwidth +iker +ilfrom +ilto +im +image +imagegetsize +imageinfo +imageinvalidfilename +imagelinks +imagemagick +imagemaxsize +imagenocrossnamespace +imagepage +imagerepository +imagerotate +images +imagesize +imagetype +imagetypemismatch +imageusage +imagick +imgmultigo +imgmultigoto +imgmultipagenext +imgmultipageprev +imgs +imgserv +immobilenamespace +implicitgroups +import +importbadinterwiki +importcantopen +importlogpage +importlogpagetext +importnofile +importtoken +importupload +importuploaderrorpartial +importuploaderrorsize +importuploaderrortemp +in +iname +inbound +includable +include +includecomments +includelocal +includeonly +includexmlnamespace +incr +increase +indefinite +index +indexfield +indexpageids +indexpolicy +indstr +infin +infinite +infiniteblock +info +infoaction +infobox +infoline +infomsg +ingroups +injectjs +inkscape +inlanguagecode +inlined +inno +inputneeded +insb +inser +instantcommons +institution +instructor +int +integer +integeroutofrange +intentionallyblankpage +interlang +interlangs +interlanguage +internal +internaledit +internalerror +interwiki +interwikimap +interwikipage +interwikis +interwikisource +intnull +intoken +intra +intro +intrw +ints +intval +invalid +invalidaction +invalidations +invalidcategory +invaliddomain +invalidemail +invalidemailaddress +invalidexpiry +invalidip +invalidlang +invalidlevel +invalidmode +invalidoldimage +invalidpage +invalidpageid +invalidparameter +invalidparammix +invalidpath +invalidrange +invalidsection +invalidsessiondata +invalidsha +invalidspecialpage +invalidtags +invalidtime +invalidtitle +invalidtoken +invaliduser +invalue +iorm +ip +ipbblocked +ipblock +ipblocks +ipbnounblockself +ipchain +ipedits +iphash +ipinrange +ipusers +iquest +irc +ircs +isam +isapi +isbot +isconnected +iscur +isin +isip +ismap +isminor +ismodsince +ismulti +isnew +ispermalink +isself +isset +istainted +istalk +iswatch +it +item +itemid +itemprop +itemref +itemscope +itemtype +iter +iu +iuinvalidparammix +iumissingparam +iuml +iw +iwbacklinks +iwbl +iwlfrom +iwlinks +iwlprefix +iwltitle +iwprefix +iwtitle +iwurl +javascript +javascripttest +jbartsh +jconds +jdk's +jhtml +jimbo +joaat +jobqueue +jointype +jorsch +journaling +jpeg +jpegtran +jslint +jsmimetype +jsminplus +json +jsonfm +jsparse +jstext +jsvarurl +justthis +kabardian +kangxi +kashubia +kattouw +kblength +kernowek +key +keygen +keylen +keyname +keynames +keytype +khash +kludgy +knownnamespace +konqueror +kpos +kuza +labarga +labelmsg +laggedslavemode +laggy +lang +langbacklinks +langcode +langcodes +langconversion +langlinks +langprop +langs +language +languagelinks +languages +languageshtml +laquo +large +larr +last +lastdiff +lastdot +lastedit +lasteditor +lastedittime +lastlink +lastmod +lastmodifiedat +lastname +lastrevid +lastvisited +latgalian +laxström +lbase +lbl +lcattrib +lceil +lcomments +lcount +lcrocker +ldquo +le +leavemessage +len +length +leprop +lesque +lettercase +level +lfloor +lg +lgname +lgpassword +lgpl +lgtoken +lguserid +lgusername +libcurl +libel +libgimpbase +libketama +libmemcached +libre +libtidy +ligabue +lighttpd +limit +limitable +line +linenumber +linestart +link +linkarr +linkcolour +linkprefix +links +linkstoimage +linktbl +linktext +linktodiffs +linktrail +linktype +linkupdate +list +listable +listadmins +listbots +listfiles +listgrouprights +listinfo +listingcontinuesabbrev +listoutput +listresult +lists +listtags +listuser +listusers +listusersfrom +livepreview +ll +llfrom +lllang +lltitle +lnumber +local +localday +localdayname +localdow +locale +localhour +localmonth +localmonthabbrev +localmonthname +localmonthnamegen +localname +localonly +localsettings +localtimezone +localweek +localyear +lock +lockandhid +lockdb +lockdir +locked +lockmanager +log +logaction +logentry +logevent +logevents +logextract +loggedin +logid +login +loginend +loginerror +loginfo +loginlanguagelinks +loginlink +loginprompt +loginreqlink +loginreqpagetext +loginreqtitle +logins +loginstart +logitem +loglink +loglist +logname +logonly +logopath +logourl +logout +logpage +logtext +logtitle +logtype +longpage +longpageerror +lookie +lookups +loopback +lossless +lossy +lowast +lowercaps +lowercased +lowlimit +lsaquo +lsquo +ltags +ltitle +ltrimmed +lurl +lysator +möller +macr +magicarr +magicfile +magick +magicword +magicwordkey +magicwords +magnus +mahaction +mailerror +mailmypassword +mailnologin +mailparts +mailpassword +mailtext +mailto +mainmodule +mainpage +maintainership +makesafe +male +malloc +manske +manualthumb +mark +markashelpful +markaspatrolledlink +markaspatrolledtext +markbot +markbotedits +markedaspatrollederror +markpatrolled +masse +match +matchcount +mathml +mathtt +matrixes +matroska +max +maxage +maxdim +maxlag +maxlength +maxlifetime +maxqueue +maxresults +maxsize +maxuploadsize +maxwidth +mazeland +mbresponse +mbstring +mckey +mcklmqw +mcrypt +mcvalue +md +mdash +medialink +mediaqueries +mediatype +mediawarning +mediawiki's +mediawikipage +megapixels +member +memberingroups +members +memc +memcache +memcached +memlimit +memoryp +memsw +merge +mergeable +merged +mergehistory +mergelog +mergelogpagetext +message +messagekey +messagename +messagepattern +messages +messagetype +meta +metacharacters +metachars +metadata +metadataversion +metafile +mhash +mhtml +micrblogging +microdata +microsyntaxes +microtime +middot +migurski +millitime +mime +mimer +mimesearchdisabled +mimetype +min +minangkabau +minh +minification +minified +minifier +minifies +minify +minifying +minimal +minor +minordefault +minoredit +minoreditletter +minsize +misconfigured +misermode +mismatch +misresolved +missing +missingcommentheader +missingcommenttext +missingdata +missingparam +missingpermission +missingresult +missingrev +missingsummary +missingtext +missingtitle +missinguser +mituzas +mixedapproval +mkdir +mms +mobile +mobileformat +mobileview +modified +modifiedarticleprotection +modify +modsecurity +modsince +module +moduledisabled +modulename +modules +monitor +monobook +monospace +monospaced +month +monthsall +moodbar +moredotdotdot +morelinkstoimage +morethan +move +movedarticleprotection +moveddeleted +movedto +movefile +movelogpage +movelogpagetext +movenologintext +movenotallowed +movenotallowedfile +moveonly +moveoverredirect +movepage +moves +movestable +movesubpages +movetalk +movethispage +movetoken +mozilla +mpeg +mpegurl +mpga +mplink +mptitle +msdn +msdownload +msec +msexcel +msgid +msgkey +msgs +msgsize +msgsmall +msgtext +msie +msmetafile +mssql +msvideo +msword +mtime +mtype +mullane +multi +multibyte +multicast +multipage +multipageimage +multipageimagenavbox +multipart +multiselect +multisource +multithreaded +multival +multivalue +multpages +munge +musso +mustbeloggedin +mustbeposted +mutator +mutators +muxers +mwdumper +mwfile +mwstore +mwsuggest +mwuser +mxircecho +mycontributions +mycontris +myext +myextension +myisam +mykey +mypage +mypreferences +mysqldump +mytalk +mytext +mywatchlist +nabla +name +namehidden +nameinlowercase +names +namespace +namespacealiases +namespacebanner +namespacee +namespacenotice +namespacenumber +namespaceoptions +namespaceprotected +namespaces +namespacesall +namespaceselector +namespacing +nassert +nbase +nbsp +nbytes +nchanges +ncount +ndash +nearmatch +nedersaksies +nedersaksisch +needreblock +needservers +needtoken +netcdf +netware +never +new +newaddr +newarticletext +newarticletextanon +newer +newerthanrevid +newgroups +newheader +newid +newimages +newlen +newmessagesdifflink +newmessagesdifflinkplural +newmessageslink +newmessageslinkplural +newname +newnames +newnamespace +newpage +newpageletter +newpages +newpageshidepatrolled +newparams +newpass +newpassword +newpos +newquery +newrevid +news +newsectionlink +newsectionsummary +newset +newsfeed +newsize +newtalk +newtalks +newtalkseparator +newtext +newtimestamp +newtitle +newuser +newuserlogpage +newuserlogpagetext +newusers +newwidth +newwindow +nextdiff +nextid +nextlink +nextn +nextpage +nextredirect +nextrevision +nextval +nfkc +nginx +nheight +niklas +nlink +nlinks +nmime +nnnn +nntp +no +noanimatethumb +noanontoken +noapiwrite +noarchivename +noarticle +noarticletext +noarticletextanon +noautopatrol +noblock +nobots +nobucket +nobuffer +nochange +nochanges +noclasses +nocode +nocomment +nocomplete +nocontent +nocontentconvert +nocontinue +noconvertlink +nocookiesfornew +nocopyright +nocourseid +nocreate +nocreatetext +nocredits +nocta +nodata +nodatabase +nodb +nodefault +nodeid +nodeleteablefile +nodeletion +nodelist +nodename +nodirection +nodotdot +noedit +noeditsection +noemail +noemailprefs +noemailtitle +noeventid +noexec +noexpertise +noexpression +nofeed +nofeedbackid +nofile +nofilekey +nofilename +nofilter +noflagtype +noflip +nofollow +nofound +nogallery +nogomatch +nogroup +noheader +noheadings +nohires +noids +noimage +noimageredirect +noimages +noinclude +noindex +noindexing +nointerwikipage +nointerwikiuserrights +noitem +nojs +nolabel +nolang +nolicense +nolimit +nolink +nolinkstoimage +nologging +nologin +nomahaction +nominornewtalk +nomodule +non +noname +nonamespacenumber +nonascii +noncascading +nondefaults +none +nonewsectionlink +nonexistent +nonfile +nonfilenamespace +nonincludable +noninfringement +noninitial +nonlocal +nonote +nonredirects +nonsense +nonunicodebrowser +noobjective +noofexpiries +noofprotections +noop +nooptions +nooverride +nopaction +nopage +nopageid +nopagetext +nopagetitle +noparser +nopathinfo +nopermission +noport +noprefix +noproject +noprop +noprotections +noquestion +noradius +noratelimit +norating +norcid +noread +noreason +noredir +noredirect +norequest +norestrictiontypes +noresult +noreturnto +norev +norevid +noreviewed +normalizedtitle +norole +norollbackdiff +noscale +noschema +noscript +nosearch +nosectiontitle +nosession +noshade +noskipnotif +noslash +nosniff +nosort +nosortdirection +nosource +nospecialpagetext +nost +nosubaction +nosubject +nosubpage +nosubpages +nosuccess +nosuchaction +nosuchactiontext +nosuchdatabase +nosuchlogid +nosuchpageid +nosuchrcid +nosuchrevid +nosuchsection +nosuchsectiontext +nosuchsectiontitle +nosuchspecialpage +nosuchuser +nosuchusershort +nosummary +notacceptable +notag +notaglist +notalk +notallowed +notanarticle +notarget +notcached +notdeleted +note +notempdir +notemplate +notext +nothumb +notif +notificationtimestamp +notificationtimestamps +notin +notitle +notitleconvert +notloggedin +notminor +noto +notoc +notoggle +notoken +notransform +notreviewable +notrustworthy +notspecialpage +notsuspended +notvisiblerev +notwatched +notwikitext +notype +noudp +noupdates +nouploadmodule +nouser +nouserid +nousername +nouserspecified +novalues +noview +nowatchlist +nowellwritten +nowiki +nowlocal +nowserver +nparsing +ns +nsassociated +nsfrom +nsinvert +nslinks +nslist +nsname +nsnum +nspname +nsselect +nstab +nsub +ntfs +ntilde +ntitle +nuke +null +nullable +numauthors +number +numberheadings +numberingroup +numberof +numberofactiveusers +numberofadmins +numberofarticles +numberofedits +numberoffiles +numberofpages +numberofusers +numberofviews +numberofwatchingusers +numedits +numentries +numericized +numgroups +numtalkauthors +numtalkedits +numwatchers +nwidth +oacute +objectcache +objective +ocirc +ocount +oelig +of +officedocument +offset +offsite +ofname +ogevents +ogghandler +ograve +old +oldaddr +oldcountable +older +olderror +oldfile +oldgroups +oldid +oldimage +oldlen +oldnamespace +oldquery +oldrev +oldrevid +oldreviewedpages +oldshared +oldsig +oldsize +oldtext +oldtitle +oldtitlemsg +oline +oname +onkeyup +online +onload +onlyauthor +onlyinclude +onlypst +onlyquery +onsubmit +onthisday +ontop +openbasedir +opendoc +opendocument +opensearch +opensearchdescription +openssl's +openxml +openxmlformats +oplus +oppositedm +optgroup +optgroups +optionname +options +optionstoken +optionvalue +optstack +or +ordertype +ordf +ordm +org +origcategory +ortime +oslash +other +otherlanguages +otherlist +otheroption +otherreason +othertime +otilde +otimes +otitle +ouml +outparam +outputter +outputtype +outreachwiki +over +overridable +override +oversight +oversighted +oversighter +overwrite +overwroteimage +own +owner +paction +page +pagecannotexist +pagecategories +pagecategorieslink +pageclass +pagecontent +pagecount +pagecss +pagedeleted +pagedlinks +pageid +pageids +pageimages +pageinfo +pagelink +pagelinks +pagemerge +pagename +pagenamee +pagenames +pagenum +pageoffset +pagepropnames +pageprops +pagerestrictions +pages +pageselector +pageset +pagesetmodule +pagesincategory +pagesinnamespace +pageswithprop +pagetextmsg +pagetitle +pagetools +pagetriage +pagetriageaction +pagetriagelist +pagetriagestats +pagetriagetagging +pagetriagetemplate +pageurl +pageview +param +parameters +paraminfo +paramlist +paramname +params +paren +parens +parentid +parenttree +parms +parse +parsedcomment +parseddescription +parsedsummary +parseerror +parseinline +parsemag +parser +parsercache +parserfuncs +parserfunctions +parserhook +parserrender +parsetree +parsevalue +parsoid +partialupload +partname +pass's +passthru +password +passwordfor +passwordreset +passwordtooshort +paste +pastexpiry +pathchar +pathinfo +pathname +patrol +patroldisabled +patrolled +patrollink +patrolmarks +patroltoken +pattern +pcache +pcntl +pcomment +pdbk +pdf's +pendingdelta +perc +perfcached +perfcachedts +perm +perma +permalink +permdenied +permil +permissiondenied +permissionerror +permissionserrors +permissionserrorstext +permissiontype +perp +perrow +pgsql +photoshop +php +php's +phpfm +phps +phpsapi +phpunit +phpversion +phpwiki +phrasewise +phtml +pi +pipermail +pixmap +pkey +pkuk +pl +plain +plainlink +plainlinks +plaintext +plfrom +plink +pllimit +plns +plpgsql +pltitle +pltitles +plusminus +plusmn +pname +pnmtojpeg +pnmtopng +poolcounter +popts +popularpages +portlet +portlets +posplus +possible +postcomment +postgre +postsep +potd +potm +potx +poweredby +poweredbyico +powersearch +pp +ppam +ppsm +ppsx +pptm +pptx +precaching +precompiled +preferences +preferencestoken +prefill +prefilled +prefix +prefixindex +prefixsearchdisabled +prefs +prefsection +prefsnologin +prefsnologintext +prefsubmit +preload +preloads +preloadtitle +prepending +prependtext +preprocess +preprocessing +preprocessors +presentationml +presep +prevchar +prevdiff +previd +previewconflict +previewhead +previewheader +previewnote +previewonfirst +previewontop +previewtext +previousrevision +prevlink +prevn +prexpiry +prfiltercascade +prfx +primary +printableversion +printfooter +printurl +privacypage +private +privs +prlevel +probabalistically +probs +proc +processings +procs +prodromou +profession +profileinfo +programmatically +project +projectpage +promotion +prop +properties +property +propname +props +prot +protect +protectcomment +protectedarticle +protectedinterface +protectednamespace +protectedpage +protectedpages +protectedpagetext +protectedpagewarning +protectedtitle +protectedtitles +protection +protections +protectlevel +protectlogpage +protectlogtext +protectthispage +protecttoken +proto +protocol +protocols +protos +proxied +proxyblocker +proxyblockreason +proxyunbannable +prtype +psir +pst +psttext +psychedelix +pt +ptext +ptool +pubdate +publicsuffix +publishfailed +punycode +purge +purged +qabardjajəbza +qbar +qbsettings +qmoicj +qp +quasit +query +querycache +querycachetwo +querycur +querydiff +querykey +querymodule +querymodules +querypage +querypages +querystring +querytype +question +queuefull +quickbar +quicktemplate +quicktime +qunit +quux +qvalues +rabdiff +radic +radius +raggett +raii +raimond +random +randompage +randomredirect +randstr +range +rangeblock +rangeblocks +rangedisabled +rangeend +rangestart +raquo +rarr +rarticle +rasterizations +rasterize +rasterized +rasterizer +ratelimited +ratelimits +rating +ratings +raw +rawfm +rawrow +rbspan +rc +rcdays +rceil +rcfeed +rcid +rcids +rclimit +rcoptions +rcpatroldisabled +rctitle +rctoken +rdev +rdfa +rdfrom +rdftype +rdquo +read +readable +readapidenied +readarray +reader +readline +readonlyreason +readonlytext +readonlywarning +readrequired +readrights +realaudio +realllly +realname +realpath +reason +reasonlist +reasonstr +reblock +rebuildtextindex +recache +recached +recaching +recalc +recentchange +recentchanges +recentchangescount +recentchangesdays +recentchangeslinked +recentchangestext +recenteditcount +recentedits +recip +recips +recreate +recurse +recurses +redir +redirect +redirectable +redirectcreated +redirectedfrom +redirections +redirectpagesub +redirectparams +redirects +redirectsnippet +redirectstofile +redirecttitle +redirectto +redirid +redirlinks +redirs +redis +redlink +redlinks +redocument +reedyboy +reenables +reencode +reference +refetch +refresheducation +refreshlinks +regexes +regexlike +region +registered +registration +registrationdate +reimport +reindexation +reindexed +releasenotes +relevance +relevant +relicense +relimit +relkind +relname +relnamespace +remarticle +remembermypassword +rememberpassword +removablegroups +removal +remove +removed +removedwatchtext +removetags +remreviewer +remstudent +renameuser +renaming +renderable +renormalized +repeating +repl +replaceafter +replacer +replacers +replag +replyto +reporttime +repos +request +requested +requestid +requeue +required +rerender +rerendered +rescnt +researcher +resends +reset +resetkinds +resetlink +resetpass +resized +resolutioninfo +resolutionunit +resolve +resolved +resourceloader +responsecode +restore +restorelink +restoreprefs +restricted +result +resultset +resultsperpage +retrievedfrom +returnto +returntoquery +retval +reupload +revalidate +revalidation +revdel +revdelete +revdelete'd +revdelundel +revert +reverting +revertpage +reverts +revid +revids +review +reviewactivity +reviewed +reviewer +reviewing +revision +revisionasof +revisionday +revisiondelete +revisionid +revisionmonth +revisions +revisiontext +revisiontimestamp +revisionuser +revisionyear +revlink +revwrongpage +rfloor +rgba +richtext +rights +rightscode +rightsinfo +rightslog +rightslogtext +rked +rmdir +rn +rnlimit +robotstxt +roff +role +rollback +rollbacker +rollbacklink +rollbacklinkcount +rollbacktoken +rootpage +rootuserpages +rowcount +rown +rownum +rowsarr +rowset +rowspan +rowspans +rsaquo +rsargs +rsd +rsdf +rsquo +rss +rsvg +ruleset +rulesets +rusyn +rv +rvcontinue +rvdiffto +rvlimit +rvparse +rvprop +rvstart +rvstartid +rvtoken +sabino +safemode +safesubst +sais +sameorigin +samp +sansserif +save +savearticle +savedprefs +saveprefs +saveusergroups +sawfish +sbin +sbquo +scaler +scalers +scaron +score +screensize +scribunto +scriptable +scriptbuilder +scriptpath +scrolltop +sdot +search +search's +searchaction +searcharticle +searchboxes +searchbutton +searcheverything +searchform +searchindex +searchinfo +searchlimit +searchmenu +searchnamespaces +searchoptions +searchresulttext +searchstring +searchtitle +secondary +section +sectionanchor +sectionedit +sectioneditnotsupported +sectionformat +sectionnumber +sectionprop +sections +sectionsnippet +sectionsnotsupported +sectiontitle +securelogin +seiten +selectandother +selectorother +self +selflink +selfmove +semiglobal +semiprotected +semiprotectedpagewarning +sendemail +sendmail +sentences +serialize +servedby +servername +servertime +serverurl +sess +session +sessionfailure +sessionid +sessionkey +setchange +setcookie +setemail +setext +setglobalaccountstatus +setnewtype +setnotificationtimestamp +setopt +setrename +setrlimit +setstatus +sha +shar +sharding +shared +shareddescriptionfollows +sharedfile +sharedrepo +sharedupload +shellscript +shiftwidth +shockwave +short +shorturl +shouldn +shouting +show +showalldb +showbots +showdeleted +showdiff +showdifflinks +showfilename +showhiddencats +showhideminor +showhooks +showingresults +showinitializer +showjumplinks +showlinkedto +showme +showmeta +shownavigation +shownumberswatching +showpreview +showredirs +showreviewed +showsizediff +showtoc +showtoolbar +showunreviewed +shtml +si +siebrand +sighhhh +sigkill +sigmaf +signup +sigsegv +sigterm +sii +siit +siiurlwidth +simplesearch +singlegroup +singularthey +sinumberingroup +siprop +site +siteadmin +sitecsspreview +sitedir +siteinfo +sitejspreview +sitemap +sitemaps +sitematrix +sitename +sitenotice +siteprop +sitesearch +sitestats +sitestatsupdate +siteuser +sitewide +size +sizediff +sizediffdisabled +sizes +skey +skinclass +skinkey +skinname +skinnameclass +skins +skipcache +skipcaptcha +skipnotif +skname +sktemplate +slideshow +sm +smaxage +smil +smtp +snippet +sodipodi +softtabstop +solaris +somecontent +somefeed +someuser +sorani +sorbs +sorbsreason +sort +sortdirection +sortkey +sortkeyprefix +sortkeys +source +soxred +spam +spamdetected +spamprotected +spamprotectionmatch +spamprotectiontext +spamprotectiontitle +spcontent +special +specialpage +specialpagealiases +specialpageattributes +specialpagegroup +specialpages +specialprotected +speedtip +speedy +speex +spekking +spellcheck +spezial +spoofable +spreadsheetml +sprefs +sprintf +sprotected +sql's +sqlite +sqltotal +sr +srchres +srcset +srgs +srprop +srwhat +stabilize +stable +stablesettings +stansvik +start +startid +startime +startsortkey +startsortkeyprefix +starttime +starttimestamp +stash +stashfailed +stashimageinfo +state +staticredirect +statistics +statline +status +statuskey +stdclass +stdout +steward +stopwords +storedversion +strcasecmp +strcmp +string +stripos +stripslashes +strlen +strpos +strrpos +strtime +strtok +strtolower +strtotime +strtr +struct +strval +stubthreshold +student +studies +stuffit +stxt +stylename +stylepath +styleversion +subaction +subarray +subcat +subcats +subclassing +subcond +subconds +subdir +subdomain +subdomains +sube +subelement +subelements +subfunction +subfunctions +subimages +subitem +subitems +subject +subjectid +subjectids +subjectpagename +subjectpagenamee +subjectspace +subjectspacee +subkey +subkeys +sublevels +submatch +submodule +submodule's +submodules +subnet +subpage +subpagename +subpagenamee +subpages +subpagestr +subparents +subprocesses +subsql +substr +succ +success +successbox +suckage +suggest +suggestion +suhosin +suhosin's +summ +summary +summarymissed +summaryrequired +supe +superdomain +superglobals +superset +suppress +suppressed +suppressedredirect +suppressionlog +suppressionlogtext +suppressredirect +suppressrevision +svgs +svn +svnroot +sybase +symlinked +syms +sysinfo +sysop +system +systemnachrichten +szdiff +szlig +szymon +t +tabindex +tablealign +tablecell +tablename +tablesorter +tablestack +tabletags +tabletype +tabstop +tag +tagfilter +tagline +taglist +tags +tagset +tagstack +tailorings +talk +talkable +talkfrom +talkid +talkids +talkmove +talkmoveoverredirect +talkpage +talkpageheader +talkpagelinktext +talkpagename +talkpagenamee +talkpagetext +talkspace +talkspacee +talkto +taraškievica +tarask +target +tb +tbase +tbody +tboverride +tcount +tcsh +tddate +tdtime +teardown +telnet +temp +tempdir +template +templatelinks +templatepage +templates +templatesused +templatesusedpreview +templatesusedsection +tempname +tempout +test +testclean +testdata +testmailuser +testpass +testrunner +testswarm +testuser +testutf +texi +texinfo +text +textarea +textareas +textares +textbox +textboxsize +texthidden +textid +textlink +textmissing +textoverride +textsf +textsize +textvector +texvc +tfoot +tful +tg +that'll +thead +thelink +theora +thetasym +thinsp +thisisdeleted +thispage +thumbborder +thumbcaption +thumberror +thumbheight +thumbhtml +thumbimage +thumbinner +thumbmime +thumbnail +thumbnailing +thumbnailsize +thumbname +thumbsize +thumbtext +thumburl +thumbwidth +timeago +timeanddate +timecond +timecorrection +timeframe +timekey +timeoffset +timep +timespans +timestamp +timestamps +timestamptz +timezonelegend +timezoneregion +timezoneuseoffset +timezoneuseserverdefault +tino +title +titleblacklist +titleconversion +titleexists +titlemsg +titleprefixeddbkey +titleprotected +titleprotectedwarning +titles +titlesnippet +titletext +titlevector +tl +tllimit +tltemplates +tmpfile +to +toclevel +tocline +tocnumber +tocsection +toctext +toctitle +tofragment +toggle +toid +token +tokenname +tokens +tolang +tongminh +toobig +toofewexpiries +toohigh +toolarray +toolbarparent +toolboxend +toolboxlink +toolong +toolow +tooltiponly +tooshort +top +toparse +topbar +toplevel +toplinks +toponly +torev +torevid +tornevall +torunblocked +totalcnt +totalcount +totalhits +totalmemory +totaltime +totitle +touched +tplarg +transcludable +transclude +transcluded +transcluding +transclusion +transclusions +transcode +transcodekey +transcoder +transcodereset +transcodestatus +transcoding +translatewiki +transstat +transwiki +troff +true +truespeed +trustworthy +truthy +tsearch +tsquery +tuple +tweakblogs +tweakers +txt +txtfm +type +typemustmatch +typeof +typname +tzstring +uacute +uarr +uc +ucfirst +ucirc +udpprofile +ufffd +ugrave +ui +uint +ulimit +ulink +ulinks +uname +unanchored +unapprove +unary +unattached +unauthenticate +unavailable +unblock +unblocklogentry +unblockself +unblocktoken +unbuffered +uncacheable +uncached +uncategorized +unclosable +uncompress +undel +undelete +undeleted +undeletion +undo +undoafter +undofailure +undorev +unescape +unescaped +unfeature +unfeatured +unflag +ungrouped +unhelpful +unhidden +unhide +unidata +unindent +unindexed +uniq +unique +universaleditbutton +unixtime +unknown +unknownerror +unknownnamespace +unlock +unlockdb +unlogged +unmakesafe +unmark +unmerge +unmodified +unoversight +unoversighted +unpadded +unpatrolled +unpatrolledletter +unprefixed +unprintables +unprotect +unprotectedarticle +unprotection +unprotectthispage +unredacted +unrequest +unrequested +unresolve +unresolved +unreviewed +unreviewedpages +unsanitized +unseed +unserialization +unserialize +unserialized +unserializing +unsetting +unstub +unstubbed +unstubbing +unstubs +unsupportednamespace +unsupportedrepo +untaint +untracked +untrustworthiness +unused +unusual +unversioned +unviewable +unviewed +unwatch +unwatched +unwatchedpages +unwatching +unwatchthispage +unwikified +unwritable +upconvert +updateddate +updatedtime +updatelog +upgradedoc +upgrader +upload +upload's +uploaddisabled +uploadedimage +uploadjava +uploadlogpage +uploadlogpagetext +uploadnewversion +uploadnologintext +uploadpage +uploadscripted +uploadsource +uploadstash +uploadvirus +uppercased +upsih +urandom +url +url's +urlaction +urldecode +urldecoded +urlencode +urlencoded +urlheight +urlparam +urlparm +urlpath +urlvar +urlwidth +ursh +us +usedomain +useemail +uselang +uselivepreview +usemod +usemsgcache +usenewrc +user +useragent +useragents +userblock +usercan +usercontribs +usercreate +usercreated +usercss +usercsspreview +usercssyoucanpreview +userdailycontribs +userdir +userdoesnotexist +usereditcount +useredits +useremail +userexists +usergroup +usergroups +userhidden +userid +userinfo +userinvalidcssjstitle +userips +userjs +userjsprev +userjspreview +userjsyoucanpreview +userlang +userlangattributes +userlink +userlinks +userlogin +userloginlink +userloginprompt +userlogout +usermaildisabled +usermessage +username +usernameless +usernames +userpage +userpages +userpageurl +userprefix +userrights +userrightstoken +users +usersbody +userspace +usertalk +usertalklink +usertext +usertoollinks +useskin +useto +usort +ustar +ustoken +utfnormal +uuml +validate +validationbuilder +valign +vals +value +values +vandal +vandalism +variables +variant +variantarticlepath +varlang +varname +vars +varval +vasiliev +vasilvv +vbase +vbscript +vcount +vcsize +venema's +verbosify +version +versioning +versionlink +versionlog +versionrequired +versionrequiredtext +very +vhost +vi +vibber +videoinfo +view +viewcount +viewdeleted +viewhelppage +viewmyprivateinfo +viewmywatchlist +viewprevnext +viewsource +viewsourcelink +viewsourcetext +viewvc +viewyourtext +visible +visualeditor +viurlwidth +voff +vofp +voicexml +vorbis +vpad +vrml +vslow +vvcv +vxml +wais +wait +wakeup +walltime +warmup +warning +wasdeleted +wasn +watch +watchcreations +watchdefault +watchdeletion +watched +watchlist +watchlistdays +watchlisthideanons +watchlisthidebots +watchlisthideliu +watchlisthideminor +watchlisthideown +watchlisthidepatrolled +watchlistraw +watchlists +watchlisttoken +watchmoves +watchthis +watchthispage +watchtoken +watchuser +wb +wbmp +wbxml +wddx +wddxfm +weblog +webm +webp +webrequest +webserver +weeks +weierp +weight +wellwritten +werdna +wget +what +whatlinkshere +whatwg +wheely +wheter +whitelist +whitelisted +whitelistedittext +whitelisting +whois +wicke +width +widthx +wierkosz +wietse +wiki +wiki'd +wiki's +wikia +wikiadmin +wikibase +wikibits +wikibooks +wikidb +wikifarm +wikiid +wikilink +wikilinks +wikilove +wikiloveimagelog +wikimedia +wikimediacommons +wikipage +wikipedia +wikipedian +wikipedias +wikis +wikisyntax +wikitable +wikitables +wikitech +wikitext +wikiuser +wiktionary +wincache +wininet +withaccess +withaction +witheditsonly +withlanglinks +withoutlanglinks +wl +wlallrev +wldir +wlend +wlexcludeuser +wllimit +wlowner +wlprop +wltoken +wmf's +wml +wmlc +wmls +wmlsc +wmlscript +wmlscriptc +wordcount +wordprocessingml +wordwg +workalike +worldwind +wouldn +wr +writeapi +writeapidenied +writedisabled +writerequired +writerights +wrongpassword +x +xbitmap +xcache +xcancel +xdebug +xdiff +xdomain +xdomains +xff +xhtmldefaultnamespace +xhtmlnamespaces +xiff +xlam +xlsb +xlsm +xlsx +xltm +xltx +xml +xmldoublequote +xmlfm +xmlimport +xmlns +xmlsafe +xmlselect +xor +xpinstall +xpixmap +xpsdocument +xtended +xwindowdump +xxxx +xxxxx +yacute +yaml +yamlfm +year +yes +youhavenewmessages +youhavenewmessagesfromusers +youhavenewmessagesmanyusers +youhavenewmessagesmulti +yourdiff +yourdomainname +youremail +yourgender +yourinternal +yourlanguage +yourname +yournick +yourpassword +yourrealname +yourtext +yourvariant +yourwiki +yuml +yyyymmddhhiiss +zhdaemon +zhengzhu +zhtable +zijdel +zlib +zoffset +zwnj diff --git a/maintenance/doMaintenance.php b/maintenance/doMaintenance.php index 15b00167..3bd508cb 100644 --- a/maintenance/doMaintenance.php +++ b/maintenance/doMaintenance.php @@ -34,7 +34,7 @@ if ( !defined( 'RUN_MAINTENANCE_IF_MAIN' ) ) { // Wasn't included from the file scope, halt execution (probably wanted the class) // If a class is using commandLine.inc (old school maintenance), they definitely // cannot be included and will proceed with execution -if( !Maintenance::shouldExecute() && $maintClass != 'CommandLineInc' ) { +if ( !Maintenance::shouldExecute() && $maintClass != 'CommandLineInc' ) { return; } @@ -53,27 +53,29 @@ $maintenance->setup(); // to $maintenance->mSelf. Keep that here for b/c $self = $maintenance->getName(); -// Detect compiled mode -if ( isset( $_SERVER['MW_COMPILED'] ) ) { - define( 'MW_COMPILED', 1 ); -} else { - # Get the MWInit class - require_once( "$IP/includes/Init.php" ); - require_once( "$IP/includes/AutoLoader.php" ); -} - +# Start the autoloader, so that extensions can derive classes from core files +require_once "$IP/includes/AutoLoader.php"; # Stub the profiler -require_once( MWInit::compiledPath( 'includes/profiler/Profiler.php' ) ); +require_once "$IP/includes/profiler/Profiler.php"; + +# Start the profiler +$wgProfiler = array(); +if ( file_exists( "$IP/StartProfiler.php" ) ) { + require "$IP/StartProfiler.php"; +} // Some other requires -if ( !defined( 'MW_COMPILED' ) ) { - require_once( "$IP/includes/Defines.php" ); +require_once "$IP/includes/Defines.php"; +require_once "$IP/includes/DefaultSettings.php"; + +# Load composer's autoloader if present +if ( is_readable( "$IP/vendor/autoload.php" ) ) { + require_once "$IP/vendor/autoload.php"; } -require_once( MWInit::compiledPath( 'includes/DefaultSettings.php' ) ); if ( defined( 'MW_CONFIG_CALLBACK' ) ) { # Use a callback function to configure MediaWiki - MWFunction::call( MW_CONFIG_CALLBACK ); + call_user_func( MW_CONFIG_CALLBACK ); } else { if ( file_exists( "$IP/../wmf-config/wikimedia-mode" ) ) { // Load settings, using wikimedia-mode if needed @@ -82,25 +84,26 @@ if ( defined( 'MW_CONFIG_CALLBACK' ) ) { # Maybe a hook? global $cluster; $cluster = 'pmtpa'; - require( MWInit::interpretedPath( '../wmf-config/wgConf.php' ) ); + require "$IP/../wmf-config/wgConf.php"; } // Require the configuration (probably LocalSettings.php) - require( $maintenance->loadSettings() ); + require $maintenance->loadSettings(); } if ( $maintenance->getDbType() === Maintenance::DB_ADMIN && is_readable( "$IP/AdminSettings.php" ) ) { - require( MWInit::interpretedPath( 'AdminSettings.php' ) ); + require "$IP/AdminSettings.php"; } if ( $maintenance->getDbType() === Maintenance::DB_NONE ) { - if ( $wgLocalisationCacheConf['storeClass'] === false && ( $wgLocalisationCacheConf['store'] == 'db' || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) ) ) + if ( $wgLocalisationCacheConf['storeClass'] === false && ( $wgLocalisationCacheConf['store'] == 'db' || ( $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory ) ) ) { $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null'; + } } $maintenance->finalSetup(); // Some last includes -require_once( MWInit::compiledPath( 'includes/Setup.php' ) ); +require_once "$IP/includes/Setup.php"; // Much much faster startup than creating a title object $wgTitle = null; @@ -123,6 +126,6 @@ try { $factory->commitMasterChanges(); $factory->shutdown(); } catch ( MWException $mwe ) { - echo( $mwe->getText() ); + echo $mwe->getText(); exit( 1 ); } diff --git a/maintenance/dumpBackup.php b/maintenance/dumpBackup.php index c9546c60..25a777cd 100644 --- a/maintenance/dumpBackup.php +++ b/maintenance/dumpBackup.php @@ -27,10 +27,10 @@ $originalDir = getcwd(); -$optionsWithArgs = array( 'pagelist', 'start', 'end', 'revstart', 'revend'); +$optionsWithArgs = array( 'pagelist', 'start', 'end', 'revstart', 'revend' ); -require_once( __DIR__ . '/commandLine.inc' ); -require_once( __DIR__ . '/backup.inc' ); +require_once __DIR__ . '/commandLine.inc'; +require_once __DIR__ . '/backup.inc'; $dumper = new BackupDumper( $argv ); @@ -44,8 +44,8 @@ if ( isset( $options['pagelist'] ) ) { $pages = file( $options['pagelist'] ); chdir( $olddir ); if ( $pages === false ) { - echo( "Unable to open file {$options['pagelist']}\n" ); - die(1); + echo "Unable to open file {$options['pagelist']}\n"; + die( 1 ); } $pages = array_map( 'trim', $pages ); $dumper->pages = array_filter( $pages, create_function( '$x', 'return $x !== "";' ) ); @@ -79,7 +79,7 @@ if ( isset( $options['full'] ) ) { $dumper->dump( WikiExporter::STABLE, $textMode ); } elseif ( isset( $options['logs'] ) ) { $dumper->dump( WikiExporter::LOGS ); -} elseif ( isset($options['revrange'] ) ) { +} elseif ( isset( $options['revrange'] ) ) { $dumper->dump( WikiExporter::RANGE, $textMode ); } else { $dumper->progress( <<<ENDS diff --git a/maintenance/dumpIterator.php b/maintenance/dumpIterator.php index 870d6321..dd468a9f 100644 --- a/maintenance/dumpIterator.php +++ b/maintenance/dumpIterator.php @@ -26,7 +26,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Base class for interating over a dump. @@ -47,13 +47,13 @@ abstract class DumpIterator extends Maintenance { } public function execute() { - if (! ( $this->hasOption('file') ^ $this->hasOption('dump') ) ) { - $this->error("You must provide a file or dump", true); + if ( !( $this->hasOption( 'file' ) ^ $this->hasOption( 'dump' ) ) ) { + $this->error( "You must provide a file or dump", true ); } $this->checkOptions(); - if ( $this->hasOption('file') ) { + if ( $this->hasOption( 'file' ) ) { $revision = new WikiRevision; $revision->setText( file_get_contents( $this->getOption( 'file' ) ) ); @@ -64,10 +64,10 @@ abstract class DumpIterator extends Maintenance { $this->startTime = microtime( true ); - if ( $this->getOption('dump') == '-' ) { + if ( $this->getOption( 'dump' ) == '-' ) { $source = new ImportStreamSource( $this->getStdin() ); } else { - $this->error("Sorry, I don't support dump filenames yet. Use - and provide it on stdin on the meantime.", true); + $this->error( "Sorry, I don't support dump filenames yet. Use - and provide it on stdin on the meantime.", true ); } $importer = new WikiImporter( $source ); @@ -81,9 +81,10 @@ abstract class DumpIterator extends Maintenance { $this->conclusions(); $delta = microtime( true ) - $this->startTime; - $this->error( "Done {$this->count} revisions in " . round($delta, 2) . " seconds " ); - if ($delta > 0) - $this->error( round($this->count / $delta, 2) . " pages/sec" ); + $this->error( "Done {$this->count} revisions in " . round( $delta, 2 ) . " seconds " ); + if ( $delta > 0 ) { + $this->error( round( $this->count / $delta, 2 ) . " pages/sec" ); + } # Perform the memory_get_peak_usage() when all the other data has been output so there's no damage if it dies. # It is only available since 5.2.0 (since 5.2.1 if you haven't compiled with --enable-memory-limit) @@ -96,7 +97,7 @@ abstract class DumpIterator extends Maintenance { if ( $this->getDbType() == Maintenance::DB_NONE ) { global $wgUseDatabaseMessages, $wgLocalisationCacheConf, $wgHooks; $wgUseDatabaseMessages = false; - $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null'; + $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null'; $wgHooks['InterwikiLoadPrefix'][] = 'DumpIterator::disableInterwikis'; } } @@ -122,9 +123,10 @@ abstract class DumpIterator extends Maintenance { $this->count++; if ( isset( $this->from ) ) { - if ( $this->from != $title ) + if ( $this->from != $title ) { return; - $this->output( "Skipped " . ($this->count - 1) . " pages\n" ); + } + $this->output( "Skipped " . ( $this->count - 1 ) . " pages\n" ); $this->count = 1; $this->from = null; @@ -175,4 +177,4 @@ class SearchDump extends DumpIterator { } $maintClass = "SearchDump"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/dumpLinks.php b/maintenance/dumpLinks.php index 08aae295..be0b4633 100644 --- a/maintenance/dumpLinks.php +++ b/maintenance/dumpLinks.php @@ -30,7 +30,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that generates a plaintext link dump. @@ -63,16 +63,17 @@ class DumpLinks extends Maintenance { $this->output( "\n" ); } $page = Title::makeTitle( $row->page_namespace, $row->page_title ); - $this->output( $page->getPrefixedUrl() ); + $this->output( $page->getPrefixedURL() ); $lastPage = $row->page_id; } $link = Title::makeTitle( $row->pl_namespace, $row->pl_title ); - $this->output( " " . $link->getPrefixedUrl() ); + $this->output( " " . $link->getPrefixedURL() ); } - if ( isset( $lastPage ) ) + if ( isset( $lastPage ) ) { $this->output( "\n" ); + } } } $maintClass = "DumpLinks"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/dumpSisterSites.php b/maintenance/dumpSisterSites.php index e05e154e..5f0c5b7c 100644 --- a/maintenance/dumpSisterSites.php +++ b/maintenance/dumpSisterSites.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that generates a page name dump for SisterSites usage. @@ -43,14 +43,15 @@ class DumpSisterSites extends Maintenance { $dbr->bufferResults( false ); $result = $dbr->select( 'page', array( 'page_namespace', 'page_title' ), - array( 'page_namespace' => NS_MAIN, - 'page_is_redirect' => 0, + array( + 'page_namespace' => NS_MAIN, + 'page_is_redirect' => 0, ), __METHOD__ ); foreach ( $result as $row ) { $title = Title::makeTitle( $row->page_namespace, $row->page_title ); - $url = $title->getFullUrl(); + $url = $title->getFullURL(); $text = $title->getPrefixedText(); $this->output( "$url $text\n" ); } @@ -58,4 +59,4 @@ class DumpSisterSites extends Maintenance { } $maintClass = "DumpSisterSites"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/dumpTextPass.php b/maintenance/dumpTextPass.php index 2e0d03b1..5d783cb9 100644 --- a/maintenance/dumpTextPass.php +++ b/maintenance/dumpTextPass.php @@ -26,8 +26,8 @@ $originalDir = getcwd(); -require_once( __DIR__ . '/commandLine.inc' ); -require_once( __DIR__ . '/backupTextPass.inc' ); +require_once __DIR__ . '/commandLine.inc'; +require_once __DIR__ . '/backupTextPass.inc'; $dumper = new TextPassDumper( $argv ); diff --git a/maintenance/dumpUploads.php b/maintenance/dumpUploads.php index 0d0dfcf3..1a9293cb 100644 --- a/maintenance/dumpUploads.php +++ b/maintenance/dumpUploads.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to dump a the list of files uploaded, @@ -125,4 +125,4 @@ By default, outputs relative paths against the parent directory of \$wgUploadDir } $maintClass = "UploadDumper"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/edit.php b/maintenance/edit.php index 93fc3e79..7c24f0fa 100644 --- a/maintenance/edit.php +++ b/maintenance/edit.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to make a page edit. @@ -52,6 +52,8 @@ class EditCLI extends Maintenance { $noRC = $this->hasOption( 'no-rc' ); $wgUser = User::newFromName( $userName ); + $context = RequestContext::getMain(); + $context->setUser( $wgUser ); if ( !$wgUser ) { $this->error( "Invalid username", true ); } @@ -63,6 +65,7 @@ class EditCLI extends Maintenance { if ( !$wgTitle ) { $this->error( "Invalid title", true ); } + $context->setTitle( $wgTitle ); $page = WikiPage::factory( $wgTitle ); @@ -92,4 +95,4 @@ class EditCLI extends Maintenance { } $maintClass = "EditCLI"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/eraseArchivedFile.php b/maintenance/eraseArchivedFile.php new file mode 100644 index 00000000..1c3f0376 --- /dev/null +++ b/maintenance/eraseArchivedFile.php @@ -0,0 +1,119 @@ +<?php +/** + * Delete archived (non-current) files from storage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Maintenance + * @author Aaron Schulz + */ + +require_once __DIR__ . '/Maintenance.php'; + +/** + * Maintenance script to delete archived (non-current) files from storage. + * + * @TODO: Maybe add some simple logging + * + * @ingroup Maintenance + * @since 1.22 + */ +class EraseArchivedFile extends Maintenance { + public function __construct() { + parent::__construct(); + $this->mDescription = "Erases traces of deleted files."; + $this->addOption( 'delete', 'Perform the deletion' ); + $this->addOption( 'filename', 'File name', false, true ); + $this->addOption( 'filekey', 'File storage key (with extension) or "*"', true, true ); + } + + public function execute() { + if ( !$this->hasOption( 'delete' ) ) { + $this->output( "Use --delete to actually confirm this script\n" ); + } + + $filekey = $this->getOption( 'filekey' ); + $filename = $this->getOption( 'filename' ); + + if ( $filekey === '*' ) { // all versions by name + if ( !strlen( $filename ) ) { + $this->error( "Missing --filename parameter.", 1 ); + } + $afile = false; + } else { // specified version + $dbw = wfGetDB( DB_MASTER ); + $row = $dbw->selectRow( 'filearchive', '*', + array( 'fa_storage_group' => 'deleted', 'fa_storage_key' => $filekey ), + __METHOD__ ); + if ( !$row ) { + $this->error( "No deleted file exists with key '$filekey'.", 1 ); + } + $filename = $row->fa_name; + $afile = ArchivedFile::newFromRow( $row ); + } + + $file = wfLocalFile( $filename ); + if ( $file->exists() ) { + $this->error( "File '$filename' is still a public file, use the delete form.\n", 1 ); + } + + $this->output( "Purging all thumbnails for file '$filename'..." ); + $file->purgeCache(); + $file->purgeHistory(); + $this->output( "done.\n" ); + + if ( $afile instanceof ArchivedFile ) { + $this->scrubVersion( $afile ); + } else { + $this->output( "Finding deleted versions of file '$filename'...\n" ); + $this->scrubAllVersions( $filename ); + $this->output( "Done\n" ); + } + } + + protected function scrubAllVersions( $name ) { + $dbw = wfGetDB( DB_MASTER ); + $res = $dbw->select( 'filearchive', '*', + array( 'fa_name' => $name, 'fa_storage_group' => 'deleted' ), + __METHOD__ ); + foreach ( $res as $row ) { + $this->scrubVersion( ArchivedFile::newFromRow( $row ) ); + } + } + + protected function scrubVersion( ArchivedFile $archivedFile ) { + $key = $archivedFile->getStorageKey(); + $name = $archivedFile->getName(); + $ts = $archivedFile->getTimestamp(); + $repo = RepoGroup::singleton()->getLocalRepo(); + $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key; + if ( $this->hasOption( 'delete' ) ) { + $status = $repo->getBackend()->delete( array( 'src' => $path ) ); + if ( $status->isOK() ) { + $this->output( "Deleted version '$key' ($ts) of file '$name'\n" ); + } else { + $this->output( "Failed to delete version '$key' ($ts) of file '$name'\n" ); + $this->output( print_r( $status->getErrorsArray(), true ) ); + } + } else { + $this->output( "Would delete version '{$key}' ({$ts}) of file '$name'\n" ); + } + } +} + +$maintClass = "EraseArchivedFile"; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/eval.php b/maintenance/eval.php index 95f46ffa..abedc61a 100644 --- a/maintenance/eval.php +++ b/maintenance/eval.php @@ -34,7 +34,7 @@ $optionsWithArgs = array( 'd' ); /** */ -require_once( __DIR__ . "/commandLine.inc" ); +require_once __DIR__ . "/commandLine.inc"; if ( isset( $options['d'] ) ) { $d = $options['d']; diff --git a/maintenance/fetchText.php b/maintenance/fetchText.php index a705bcca..05470d30 100644 --- a/maintenance/fetchText.php +++ b/maintenance/fetchText.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script used to fetch page text in a subprocess. @@ -45,7 +45,7 @@ class FetchText extends Maintenance { * * note that that the text string itself is *not* followed by newline */ - public function execute() { + public function execute() { $db = wfGetDB( DB_SLAVE ); $stdin = $this->getStdin(); while ( !feof( $stdin ) ) { @@ -56,12 +56,12 @@ class FetchText extends Maintenance { } $textId = intval( $line ); $text = $this->doGetText( $db, $textId ); - if ($text === false) { + if ( $text === false ) { # actual error, not zero-length text $textLen = "-1"; } else { - $textLen = strlen($text); + $textLen = strlen( $text ); } $this->output( $textId . "\n" . $textLen . "\n" . $text ); } @@ -88,4 +88,4 @@ class FetchText extends Maintenance { } $maintClass = "FetchText"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fileOpPerfTest.php b/maintenance/fileOpPerfTest.php index 008d7686..9dba8183 100644 --- a/maintenance/fileOpPerfTest.php +++ b/maintenance/fileOpPerfTest.php @@ -21,10 +21,8 @@ * @ingroup Maintenance */ -$wgProfiler = array( 'class' => 'ProfilerSimpleText' ); error_reporting( E_ALL ); - -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to test fileop performance. @@ -44,6 +42,8 @@ class TestFileOpPerformance extends Maintenance { } public function execute() { + Profiler::setInstance( new ProfilerSimpleText( array() ) ); // clear + $backend = FileBackendGroup::singleton()->get( $this->getOption( 'b1' ) ); $this->doPerfTest( $backend ); @@ -52,10 +52,8 @@ class TestFileOpPerformance extends Maintenance { $this->doPerfTest( $backend ); } - $profiler = Profiler::instance(); - $profiler->setTemplated( true ); - - //NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php. + Profiler::instance()->setTemplated( true ); + // NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php. } protected function doPerfTest( FileBackend $backend ) { @@ -79,7 +77,7 @@ class TestFileOpPerformance extends Maintenance { $this->output( "Using '$dirname/$file' in operations.\n" ); $dst = $baseDir . '/' . wfBaseName( $file ); $ops1[] = array( 'op' => 'store', - 'src' => "$dirname/$file", 'dst' => $dst, 'overwrite' => 1); + 'src' => "$dirname/$file", 'dst' => $dst, 'overwrite' => 1 ); $ops2[] = array( 'op' => 'copy', 'src' => "$dst", 'dst' => "$dst-1", 'overwrite' => 1 ); $ops3[] = array( 'op' => 'move', @@ -106,7 +104,7 @@ class TestFileOpPerformance extends Maintenance { $e = ( microtime( true ) - $start ) * 1000; if ( $status->getErrorsArray() ) { print_r( $status->getErrorsArray() ); - exit(0); + exit( 0 ); } $this->output( $backend->getName() . ": Stored " . count( $ops1 ) . " files in $e ms.\n" ); @@ -115,7 +113,7 @@ class TestFileOpPerformance extends Maintenance { $e = ( microtime( true ) - $start ) * 1000; if ( $status->getErrorsArray() ) { print_r( $status->getErrorsArray() ); - exit(0); + exit( 0 ); } $this->output( $backend->getName() . ": Copied " . count( $ops2 ) . " files in $e ms.\n" ); @@ -124,7 +122,7 @@ class TestFileOpPerformance extends Maintenance { $e = ( microtime( true ) - $start ) * 1000; if ( $status->getErrorsArray() ) { print_r( $status->getErrorsArray() ); - exit(0); + exit( 0 ); } $this->output( $backend->getName() . ": Moved " . count( $ops3 ) . " files in $e ms.\n" ); @@ -133,7 +131,7 @@ class TestFileOpPerformance extends Maintenance { $e = ( microtime( true ) - $start ) * 1000; if ( $status->getErrorsArray() ) { print_r( $status->getErrorsArray() ); - exit(0); + exit( 0 ); } $this->output( $backend->getName() . ": Deleted " . count( $ops4 ) . " files in $e ms.\n" ); @@ -142,11 +140,11 @@ class TestFileOpPerformance extends Maintenance { $e = ( microtime( true ) - $start ) * 1000; if ( $status->getErrorsArray() ) { print_r( $status->getErrorsArray() ); - exit(0); + exit( 0 ); } $this->output( $backend->getName() . ": Deleted " . count( $ops5 ) . " files in $e ms.\n" ); } } $maintClass = "TestFileOpPerformance"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/findHooks.php b/maintenance/findHooks.php index 778da5a1..373170ff 100644 --- a/maintenance/findHooks.php +++ b/maintenance/findHooks.php @@ -34,7 +34,7 @@ * @author Antoine Musso <hashar at free dot fr> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that compares documented and actually present mismatches. @@ -248,4 +248,4 @@ class FindHooks extends Maintenance { } $maintClass = 'FindHooks'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fixDoubleRedirects.php b/maintenance/fixDoubleRedirects.php index 19b97777..523be7ef 100644 --- a/maintenance/fixDoubleRedirects.php +++ b/maintenance/fixDoubleRedirects.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fixes double redirects. @@ -134,4 +134,4 @@ class FixDoubleRedirects extends Maintenance { } $maintClass = "FixDoubleRedirects"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fixExtLinksProtocolRelative.php b/maintenance/fixExtLinksProtocolRelative.php index 2403ec68..55fbd9a3 100644 --- a/maintenance/fixExtLinksProtocolRelative.php +++ b/maintenance/fixExtLinksProtocolRelative.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fixes any entriy for protocol-relative URLs @@ -85,4 +85,4 @@ class FixExtLinksProtocolRelative extends LoggedUpdateMaintenance { } $maintClass = "FixExtLinksProtocolRelative"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fixSlaveDesync.php b/maintenance/fixSlaveDesync.php index ab7603de..e4e557fe 100644 --- a/maintenance/fixSlaveDesync.php +++ b/maintenance/fixSlaveDesync.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fixes erroneous page_latest values @@ -106,10 +106,10 @@ class FixSlaveDesync extends Maintenance { $db = wfGetDB( $i ); /* if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) { - $this->output( "Slave is too lagged, aborting\n" ); - $dbw->commit( __METHOD__ ); - sleep(10); - return; + $this->output( "Slave is too lagged, aborting\n" ); + $dbw->commit( __METHOD__ ); + sleep(10); + return; }*/ $latest = $db->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), __METHOD__ ); $max = $db->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ ); @@ -213,4 +213,4 @@ class FixSlaveDesync extends Maintenance { } $maintClass = "FixSlaveDesync"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fixTimestamps.php b/maintenance/fixTimestamps.php index 84d08d39..b0609d17 100644 --- a/maintenance/fixTimestamps.php +++ b/maintenance/fixTimestamps.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fixes timestamp corruption caused by one or @@ -125,4 +125,4 @@ class FixTimestamps extends Maintenance { } $maintClass = "FixTimestamps"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fixUserRegistration.php b/maintenance/fixUserRegistration.php index 91d42a5d..097936c9 100644 --- a/maintenance/fixUserRegistration.php +++ b/maintenance/fixUserRegistration.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fixes the user_registration field. @@ -58,4 +58,4 @@ class FixUserRegistration extends Maintenance { } $maintClass = "FixUserRegistration"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/formatInstallDoc.php b/maintenance/formatInstallDoc.php index 691ed80c..e2b3c419 100644 --- a/maintenance/formatInstallDoc.php +++ b/maintenance/formatInstallDoc.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ .'/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that formats RELEASE-NOTE file to wiki text or HTML markup. @@ -75,4 +75,4 @@ class MaintenanceFormatInstallDoc extends Maintenance { } $maintClass = 'MaintenanceFormatInstallDoc'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/fuzz-tester.php b/maintenance/fuzz-tester.php index 4c039807..548bb2f2 100644 --- a/maintenance/fuzz-tester.php +++ b/maintenance/fuzz-tester.php @@ -118,7 +118,6 @@ Wiki configuration for testing: // Enable weird and wonderful options: // Increase default error reporting level. error_reporting (E_ALL); // At a later date could be increased to E_ALL | E_STRICT - $wgBlockOpenProxies = true; // Some block pages require this to be true in order to test. $wgEnableUploads = true; // enable uploads. $wgDBerrorLog = "/root/mediawiki-db-error-log.txt"; // log DB errors, replace with suitable path. $wgShowSQLErrors = true; // Show SQL errors (instead of saying the query was hidden). @@ -127,17 +126,17 @@ Wiki configuration for testing: $wgEnableWriteAPI = true; // enable API. // Install & enable Parser Hook extensions to increase code coverage. E.g.: - require_once("extensions/ParserFunctions/ParserFunctions.php"); - require_once("extensions/Cite/Cite.php"); - require_once("extensions/inputbox/inputbox.php"); - require_once("extensions/Sort/Sort.php"); - require_once("extensions/wikihiero/wikihiero.php"); - require_once("extensions/CharInsert/CharInsert.php"); - require_once("extensions/FixedImage/FixedImage.php"); + require_once "extensions/ParserFunctions/ParserFunctions.php"; + require_once "extensions/Cite/Cite.php"; + require_once "extensions/inputbox/inputbox.php"; + require_once "extensions/Sort/Sort.php"; + require_once "extensions/wikihiero/wikihiero.php"; + require_once "extensions/CharInsert/CharInsert.php"; + require_once "extensions/FixedImage/FixedImage.php"; // Install & enable Special Page extensions to increase code coverage. E.g.: - require_once("extensions/Cite/SpecialCite.php"); - require_once("extensions/Renameuser/SpecialRenameuser.php"); + require_once "extensions/Cite/SpecialCite.php"; + require_once "extensions/Renameuser/SpecialRenameuser.php"; // --------- End --------- If you want to try E_STRICT error logging, add this to the above: @@ -181,7 +180,7 @@ TODO: // ///////////////////////// COMMAND LINE HELP //////////////////////////////////// // This is a command line script, load MediaWiki env (gives command line options); -require_once( __DIR__ . '/commandLine.inc' ); +require_once __DIR__ . '/commandLine.inc'; // if the user asked for an explanation of command line options. if ( isset( $options["help"] ) ) { @@ -657,6 +656,7 @@ class wikiFuzz { "}}", "{{INT:googlesearch|", "}}", + "{{ROOTPAGENAME}}", "{{BASEPAGENAME}}", "{{CONTENTLANGUAGE}}", "{{PAGESINNAMESPACE:}}", @@ -1482,24 +1482,6 @@ class watchlistTest extends pageTest { } } - -/** - ** a page test for "Special:Blockme" - */ -class specialBlockmeTest extends pageTest { - function __construct() { - $this->pagePath = "index.php?title=Special:Blockme"; - - $this->params = array (); - - // sometimes we specify "ip", and sometimes we don't. - if ( wikiFuzz::randnum( 1 ) == 0 ) { - $this->params["ip"] = wikiFuzz::chooseInput( array( "10.12.41.213", wikiFuzz::randnum( 8134, -10 ), wikiFuzz::makeFuzz( 2 ) ) ); - } - } -} - - /** ** a page test for "Special:Movepage" */ @@ -1972,7 +1954,7 @@ class specialChemicalsourcesTest extends pageTest { ** returns the help screen - so currently a lot of the tests aren't actually doing much ** because something wasn't right in the query. ** - ** @todo: Incomplete / unfinished; Runs too fast (suggests not much testing going on). + ** @todo Incomplete / unfinished; Runs too fast (suggests not much testing going on). */ class api extends pageTest { @@ -2160,7 +2142,7 @@ class GeSHi_Test extends pageTest { /** ** selects a page test to run. * @param $count - * @return \api|\confirmEmail|\contributionsTest|\editPageTest|\imagelistTest|\imagepageTest|\ipblocklistTest|\listusersTest|\mimeSearchTest|\newImagesTest|\pageDeletion|\pageHistoryTest|\pageProtectionForm|\prefixindexTest|\profileInfo|\recentchangesTest|\redirectTest|\searchTest|\specialAllmessagesTest|\specialAllpagesTest|\specialBlockip|\specialBlockmeTest|\specialBooksourcesTest|\specialCategoryTree|\specialChemicalsourcesTest|\specialCitePageTest|\specialExportTest|\specialFilepathPageTest|\specialImportPageTest|\specialLinksearch|\specialLockdbPageTest|\specialLogTest|\specialMovePage|\specialNewpagesPageTest|\specialRenameuserPageTest|\specialRevisionDeletePageTest|\specialUndeletePageTest|\specialUnlockdbPageTest|\specialUserrights|\successfulUserLoginTest|\thumbTest|\userLoginTest|\viewPageTest|\watchlistTest + * @return \api|\confirmEmail|\contributionsTest|\editPageTest|\imagelistTest|\imagepageTest|\ipblocklistTest|\listusersTest|\mimeSearchTest|\newImagesTest|\pageDeletion|\pageHistoryTest|\pageProtectionForm|\prefixindexTest|\profileInfo|\recentchangesTest|\redirectTest|\searchTest|\specialAllmessagesTest|\specialAllpagesTest|\specialBlockip|\specialBooksourcesTest|\specialCategoryTree|\specialChemicalsourcesTest|\specialCitePageTest|\specialExportTest|\specialFilepathPageTest|\specialImportPageTest|\specialLinksearch|\specialLockdbPageTest|\specialLogTest|\specialMovePage|\specialNewpagesPageTest|\specialRenameuserPageTest|\specialRevisionDeletePageTest|\specialUndeletePageTest|\specialUnlockdbPageTest|\specialUserrights|\successfulUserLoginTest|\thumbTest|\userLoginTest|\viewPageTest|\watchlistTest */ function selectPageTest( $count ) { @@ -2196,7 +2178,6 @@ function selectPageTest( $count ) { case 20: return new redirectTest(); case 21: return new confirmEmail(); case 22: return new watchlistTest(); - case 23: return new specialBlockmeTest(); case 24: return new specialUndeletePageTest(); case 25: return new specialMovePage(); case 26: return new specialUnlockdbPageTest(); @@ -2542,7 +2523,7 @@ function runWikiTest( pageTest $test, &$testname, $can_overwrite = false ) { if ( !$valid ) print "\nW3C web validation failed - view details with: html2text " . DIRECTORY . "/" . $testname . ".validator_output.html"; } - // Get tidy to check the page, unless we already know it produces non-XHTML output. + // Get tidy to check the page, unless we already know it produces non-(X)HTML output. if ( $test->tidyValidate() ) { $valid = tidyCheckFile( $testname . HTML_FILE ) && $valid; } diff --git a/maintenance/generateSitemap.php b/maintenance/generateSitemap.php index adea97ea..0b21a1fe 100644 --- a/maintenance/generateSitemap.php +++ b/maintenance/generateSitemap.php @@ -26,7 +26,7 @@ * @see http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that generates a sitemap for the site. @@ -167,7 +167,7 @@ class GenerateSitemap extends Maintenance { } $this->identifier = $this->getOption( 'identifier', wfWikiID() ); $this->compress = $this->getOption( 'compress', 'yes' ) !== 'no'; - $this->skipRedirects = $this->getOption( 'skip-redirects', false ) !== false ; + $this->skipRedirects = $this->getOption( 'skip-redirects', false ) !== false; $this->dbr = wfGetDB( DB_SLAVE ); $this->generateNamespaces(); $this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() ); @@ -231,7 +231,7 @@ class GenerateSitemap extends Maintenance { wfMkdirParents( $fspath, null, __METHOD__ ) or die( "Can not create directory $fspath.\n" ); } - return realpath( $fspath ) . DIRECTORY_SEPARATOR ; + return realpath( $fspath ) . DIRECTORY_SEPARATOR; } /** @@ -255,8 +255,9 @@ class GenerateSitemap extends Maintenance { ) ); - foreach ( $res as $row ) + foreach ( $res as $row ) { $this->namespaces[] = $row->page_namespace; + } } /** @@ -319,7 +320,7 @@ class GenerateSitemap extends Maintenance { $this->output( "$namespace ($fns)\n" ); $skippedRedirects = 0; // Number of redirects skipped for that namespace foreach ( $res as $row ) { - if ($this->skipRedirects && $row->page_is_redirect ) { + if ( $this->skipRedirects && $row->page_is_redirect ) { $skippedRedirects++; continue; } @@ -346,7 +347,9 @@ class GenerateSitemap extends Maintenance { if ( $wgContLang->hasVariants() ) { $variants = $wgContLang->getVariants(); foreach ( $variants as $vCode ) { - if ( $vCode == $wgContLang->getCode() ) continue; // we don't want default variant + if ( $vCode == $wgContLang->getCode() ) { + continue; // we don't want default variant + } $entry = $this->fileEntry( $title->getCanonicalURL( '', $vCode ), $date, $this->priority( $namespace ) ); $length += strlen( $entry ); $this->write( $this->file, $entry ); @@ -354,7 +357,7 @@ class GenerateSitemap extends Maintenance { } } - if ($this->skipRedirects && $skippedRedirects > 0) { + if ( $this->skipRedirects && $skippedRedirects > 0 ) { $this->output( " skipped $skippedRedirects redirect(s)\n" ); } @@ -374,8 +377,8 @@ class GenerateSitemap extends Maintenance { */ function open( $file, $flags ) { $resource = $this->compress ? gzopen( $file, $flags ) : fopen( $file, $flags ); - if( $resource === false ) { - wfDebugDieBacktrace( __METHOD__ . " error opening file $file with flags $flags. Check permissions?" ); + if ( $resource === false ) { + throw new MWException( __METHOD__ . " error opening file $file with flags $flags. Check permissions?" ); } return $resource; } @@ -384,23 +387,25 @@ class GenerateSitemap extends Maintenance { * gzwrite() / fwrite() wrapper */ function write( &$handle, $str ) { - if( $handle === true || $handle === false ) { - wfDebugDieBacktrace( __METHOD__ . " was passed a boolean as a file handle.\n" ); + if ( $handle === true || $handle === false ) { + throw new MWException( __METHOD__ . " was passed a boolean as a file handle.\n" ); } - if ( $this->compress ) + if ( $this->compress ) { gzwrite( $handle, $str ); - else + } else { fwrite( $handle, $str ); + } } /** * gzclose() / fclose() wrapper */ function close( &$handle ) { - if ( $this->compress ) + if ( $this->compress ) { gzclose( $handle ); - else + } else { fclose( $handle ); + } } /** @@ -485,7 +490,8 @@ class GenerateSitemap extends Maintenance { function fileEntry( $url, $date, $priority ) { return "\t<url>\n" . - "\t\t<loc>$url</loc>\n" . + // bug 34666: $url may contain bad characters such as ampersands. + "\t\t<loc>" . htmlspecialchars( $url ) . "</loc>\n" . "\t\t<lastmod>$date</lastmod>\n" . "\t\t<priority>$priority</priority>\n" . "\t</url>\n"; @@ -516,4 +522,4 @@ class GenerateSitemap extends Maintenance { } $maintClass = "GenerateSitemap"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/getConfiguration.php b/maintenance/getConfiguration.php index 83b5b029..5a5eb587 100644 --- a/maintenance/getConfiguration.php +++ b/maintenance/getConfiguration.php @@ -1,6 +1,6 @@ <?php /** - * Print serialized output of MediaWiki config vars + * Print serialized output of MediaWiki config vars. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,10 +20,10 @@ * @file * @ingroup Maintenance * @author Tim Starling - * @author Antoine Musso + * @author Antoine Musso <hashar@free.fr> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Print serialized output of MediaWiki config vars @@ -31,33 +31,123 @@ require_once( __DIR__ . '/Maintenance.php' ); * @ingroup Maintenance */ class GetConfiguration extends Maintenance { + + protected $regex = null; + + protected $settings_list = array(); + + /** + * List of format output internally supported. + * Each item MUST be lower case. + */ + protected static $outFormats = array( + 'json', + 'php', + 'serialize', + 'vardump', + ); + public function __construct() { parent::__construct(); $this->mDescription = "Get serialized MediaWiki site configuration"; - $this->addOption( 'settings', 'Space-separated list of wg* variables', true, true ); - $this->addOption( 'format', 'PHP or JSON', true, true ); - $this->addOption( 'wiki', 'Wiki ID', true, true ); + $this->addOption( 'regex', 'regex to filter variables with', false, true ); + $this->addOption( 'iregex', 'same as --regex but case insensitive', false, true ); + $this->addOption( 'settings', 'Space-separated list of wg* variables', false, true ); + $this->addOption( 'format', join( ', ', self::$outFormats ), false, true ); + } + + protected function validateParamsAndArgs() { + $error_out = false; + + # Get the format and make sure it is set to a valid default value + $format = strtolower( $this->getOption( 'format', 'PHP' ) ); + + $validFormat = in_array( $format, self::$outFormats ); + if ( ! $validFormat ) { + $this->error( "--format set to an unrecognized format", 0 ); + $error_out = true; + } + + if ( $this->getOption( 'regex' ) && $this->getOption( 'iregex' ) ) { + $this->error( "Can only use either --regex or --iregex" ); + $error_out = true; + } + + parent::validateParamsAndArgs(); + + if ( $error_out ) { + # Force help and quit + $this->maybeHelp( true ); + } + } + + /** + * finalSetup() since we need MWException + */ + public function finalSetup() { + parent::finalSetup(); + + $this->regex = $this->getOption( 'regex' ) ? : $this->getOption( 'iregex' ); + if ( $this->regex ) { + $this->regex = '/' . $this->regex . '/'; + if ( $this->hasOption( 'iregex' ) ) { + $this->regex .= 'i'; # case insensitive regex + } + } + + if ( $this->hasOption( 'settings' ) ) { + $this->settings_list = explode( ' ', $this->getOption( 'settings' ) ); + # Values validation + foreach ( $this->settings_list as $name ) { + if ( !preg_match( '/^wg[A-Z]/', $name ) ) { + throw new MWException( "Variable '$name' does start with 'wg'." ); + } elseif ( !isset( $GLOBALS[$name] ) ) { + throw new MWException( "Variable '$name' is not set." ); + } elseif ( !$this->isAllowedVariable( $GLOBALS[$name] ) ) { + throw new MWException( "Variable '$name' includes non-array, non-scalar, items." ); + } + } + } } public function execute() { + // Settings we will display $res = array(); - foreach ( explode( ' ', $this->getOption( 'settings' ) ) as $name ) { - if ( !preg_match( '/^wg[A-Z]/', $name ) ) { - throw new MWException( "Variable '$name' does start with 'wg'." ); - } elseif ( !isset( $GLOBALS[$name] ) ) { - throw new MWException( "Variable '$name' is not set." ); - } elseif ( !$this->isAllowedVariable( $GLOBALS[$name] ) ) { - throw new MWException( "Variable '$name' includes non-array, non-scalar, items." ); + + # Sane default: dump any wg / wmg variable + if ( ! $this->regex && ! $this->getOption( 'settings' ) ) { + $this->regex = '/^wm?g/'; + } + + # Filter out globals based on the regex + if ( $this->regex ) { + $res = array(); + foreach ( $GLOBALS as $name => $value ) { + if ( preg_match( $this->regex, $name ) ) { + $res[$name] = $value; + } } - $res[$name] = $GLOBALS[$name]; } + # Explicitly dumps a list of provided global names + if ( $this->settings_list ) { + foreach ( $this->settings_list as $name ) { + $res[$name] = $GLOBALS[$name]; + } + } + + ksort( $res ); + $out = null; - switch( $this->getOption( 'format' ) ) { - case 'PHP': + switch ( strtolower( $this->getOption( 'format' ) ) ) { + case 'serialize': + case 'php': $out = serialize( $res ); break; - case 'JSON': + case 'vardump': + $out = $this->formatVarDump( $res ); + break; + case 'json': $out = FormatJson::encode( $res ); break; default: @@ -67,7 +157,22 @@ class GetConfiguration extends Maintenance { throw new MWException( "Failed to serialize the requested settings." ); } - $this->output( $out . "\n" ); + if ( $out ) { + $this->output( $out . "\n" ); + } + } + + protected function formatVarDump( $res ) { + $ret = ''; + foreach ( $res as $key => $value ) { + ob_start(); # intercept var_dump() output + print "\${$key} = "; + var_dump( $value ); + # grab var_dump() output and discard it from the output buffer + $ret .= trim( ob_get_clean() ) . ";\n"; + } + + return trim( $ret, "\n" ); } private function isAllowedVariable( $value ) { @@ -86,4 +191,4 @@ class GetConfiguration extends Maintenance { } $maintClass = "GetConfiguration"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/getLagTimes.php b/maintenance/getLagTimes.php index 72b1d48a..7365a2ee 100644 --- a/maintenance/getLagTimes.php +++ b/maintenance/getLagTimes.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that displays replication lag times. @@ -39,7 +39,7 @@ class GetLagTimes extends Maintenance { if ( $lb->getServerCount() == 1 ) { $this->error( "This script dumps replication lag times, but you don't seem to have\n" - . "a multi-host db server configuration." ); + . "a multi-host db server configuration." ); } else { $lags = $lb->getLagTimes(); foreach ( $lags as $n => $lag ) { @@ -59,4 +59,4 @@ class GetLagTimes extends Maintenance { } $maintClass = "GetLagTimes"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/getSlaveServer.php b/maintenance/getSlaveServer.php index ec9ed20a..d618825f 100644 --- a/maintenance/getSlaveServer.php +++ b/maintenance/getSlaveServer.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that reports the hostname of a slave server. @@ -51,4 +51,4 @@ class GetSlaveServer extends Maintenance { } $maintClass = "GetSlaveServer"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/getText.php b/maintenance/getText.php index f6adfe2b..9c4bdfb8 100644 --- a/maintenance/getText.php +++ b/maintenance/getText.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that outputs page text to stdout. @@ -62,4 +62,4 @@ class GetTextMaint extends Maintenance { } $maintClass = "GetTextMaint"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/hiphop/compiler.conf b/maintenance/hiphop/compiler.conf deleted file mode 100644 index 3e01640d..00000000 --- a/maintenance/hiphop/compiler.conf +++ /dev/null @@ -1,5 +0,0 @@ -GenerateSourceInfo = true -EnableEval = 2 -AllDynamic = true -EnableHipHopSyntax = true -EnableHipHopExperimentalSyntax = true diff --git a/maintenance/hiphop/extra-files b/maintenance/hiphop/extra-files deleted file mode 100644 index f07f7c7c..00000000 --- a/maintenance/hiphop/extra-files +++ /dev/null @@ -1,34 +0,0 @@ -img_auth.php -includes/AutoLoader.php -includes/DefaultSettings.php -includes/Defines.php -includes/GlobalFunctions.php -includes/ImageFunctions.php -includes/OutputHandler.php -includes/ProxyTools.php -includes/SeleniumWebSettings.php -includes/Setup.php -includes/StreamFile.php -includes/WebStart.php -includes/filerepo/NullRepo.php -includes/normal/UtfNormalDefines.php -includes/normal/UtfNormalUtil.php -index.php -languages/Names.php -load.php -maintenance/Maintenance.php -maintenance/commandLine.inc -maintenance/doMaintenance.php -maintenance/eval.php -opensearch_desc.php -profileinfo.php -redirect.php -resources/Resources.php -serialized/serialize.php -skins/MonoBook.deps.php -skins/MonoBook.php -skins/Vector.deps.php -skins/Vector.php -thumb.php -trackback.php - diff --git a/maintenance/hiphop/make b/maintenance/hiphop/make deleted file mode 100644 index 13e3163a..00000000 --- a/maintenance/hiphop/make +++ /dev/null @@ -1,311 +0,0 @@ -#!/usr/bin/hphpi -f -<?php - -define( 'MW_CONFIG_CALLBACK', 'MakeHipHop::noConfigNeeded' ); -require( __DIR__ . '/../Maintenance.php' ); - -class MakeHipHop extends Maintenance { - function noConfigNeeded() {} - - function execute() { - global $wgHipHopBuildDirectory; - - $startTime = time(); - - $thisDir = realpath( __DIR__ ); - $IP = realpath( "$thisDir/../.." ); - if ( strval( $wgHipHopBuildDirectory ) !== '' ) { - $buildDir = $wgHipHopBuildDirectory; - } else { - $buildDir = "$thisDir/build"; - } - $extensionsDir = realpath( MWInit::getExtensionsDirectory() ); - $outDir = "$buildDir/hiphop-output"; - $persistentDir = "$buildDir/persistent"; - - if ( !is_dir( $buildDir ) ) { - mkdir( $buildDir, 0777, true ); - } - if ( !is_dir( $persistentDir ) ) { - mkdir( $persistentDir, 0777, true ); - } - - if ( realpath( "$IP/../phase3" ) !== $IP - || realpath( "$IP/../extensions" ) !== $extensionsDir ) - { - # Set up a fake source directory with the correct layout - $sourceBase = "$buildDir/source"; - $this->setupFakeSourceBase( $IP, $extensionsDir, $sourceBase ); - } else { - $sourceBase = realpath( "$IP/.." ); - unlink( "$buildDir/source" ); - } - - # With the CentOS RPMs, you just get g++44, no g++, so we have to - # use the environment - if ( isset( $_ENV['CXX'] ) ) { - $cxx = $_ENV['CXX']; - } else { - $cxx = 'g++'; - } - - # Create a function that provides the HipHop compiler version, and - # doesn't exist when MediaWiki is invoked in interpreter mode. - $version = str_replace( PHP_EOL, ' ', trim( `hphp --version` ) ); - file_put_contents( - "$buildDir/HipHopCompilerVersion.php", - "<" . "?php\n" . - "function wfHipHopCompilerVersion() {\n" . - "return " . var_export( $version, true ) . ";\n" . - "}\n" - ); - - # Generate the file list - $files = $this->getFileList(); - file_put_contents( - "$buildDir/file-list", - implode( "\n", $files ) . "\n" ); - - # Generate the C++ - passthru( - 'hphp' . - ' --target=cpp' . - ' --format=file' . - ' --input-dir=' . wfEscapeShellArg( $sourceBase ) . - ' --input-list=' . wfEscapeShellArg( "$buildDir/file-list" ) . - ' --inputs=' . wfEscapeShellArg( "$buildDir/HipHopCompilerVersion.php" ) . - ' -c ' . wfEscapeShellArg( "$thisDir/compiler.conf" ) . - ' --parse-on-demand=false' . - ' --program=mediawiki-hphp' . - ' --output-dir=' . wfEscapeShellArg( $outDir ) . - ' --log=3', $ret ); - - if ( $ret ) { - $this->error( "hphp hit an error. Stopping build.\n" ); - exit( 1 ); - } - - # Sanity check, quickly make sure we've got an output directory - if( !is_dir( $outDir ) ) { - $this->error( "No output directory", true ); - } - - # Warn about volatile classes - $this->checkVolatileClasses( $outDir ); - - # Copy the generated C++ files into the source directory for cmake - $iter = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( $outDir ), - RecursiveIteratorIterator::SELF_FIRST ); - $sourceFiles = array(); - $regenerateMakefile = false; - $numFiles = 0; - $numFilesChanged = 0; - foreach ( $iter as $sourcePath => $file ) { - $name = substr( $sourcePath, strlen( $outDir ) + 1 ); - $sourceFiles[$name] = true; - $destPath = "$persistentDir/$name"; - if ( $file->isDir() ) { - if ( !is_dir( $destPath ) ) { - mkdir( $destPath ); - } - continue; - } - - $numFiles++; - # Remove any files that weren't touched, these may have been removed - # from file-list, we should not compile them - if ( $file->getMTime() < $startTime ) { - if ( file_exists( $destPath ) ) { - unlink( $destPath ); - # Files removed, regenerate the makefile - $regenerateMakefile = true; - } - unlink( $sourcePath ); - $numFilesChanged++; - continue; - } - - if ( file_exists( $destPath ) ) { - $sourceHash = md5( file_get_contents( $sourcePath ) ); - $destHash = md5( file_get_contents( $destPath ) ); - if ( $sourceHash == $destHash ) { - continue; - } - } else { - # New files added, regenerate the makefile - $regenerateMakefile = true; - } - $numFilesChanged++; - copy( $sourcePath, $destPath ); - } - - echo "MediaWiki: $numFilesChanged files changed out of $numFiles\n"; - - if ( !file_exists( "$persistentDir/CMakeLists.txt" ) ) { - # Run cmake for the first time - $regenerateMakefile = true; - } - - # Do our own version of $HPHP_HOME/bin/run.sh, which isn't so broken. - # HipHop's RELEASE mode seems to be stuck always on, so symbols get - # stripped. Also we will try keeping the generated .o files instead of - # throwing away hours of CPU time every time you make a typo. - - chdir( $persistentDir ); - - if ( $regenerateMakefile ) { - copy( $_ENV['HPHP_HOME'] . '/bin/CMakeLists.base.txt', - "$persistentDir/CMakeLists.txt" ); - - if ( file_exists( "$persistentDir/CMakeCache.txt" ) ) { - unlink( "$persistentDir/CMakeCache.txt" ); - } - - $cmd = 'cmake' . - " -D CMAKE_BUILD_TYPE:string=" . wfEscapeShellArg( $GLOBALS['wgHipHopBuildType'] ) . - ' -D PROGRAM_NAME:string=mediawiki-hphp'; - - if ( file_exists( '/usr/bin/ccache' ) ) { - $cmd .= ' -D CMAKE_CXX_COMPILER:string=ccache' . - ' -D CMAKE_CXX_COMPILER_ARG1:string=' . wfEscapeShellArg( $cxx ); - } - - $cmd .= ' .'; - echo "$cmd\n"; - passthru( $cmd ); - } - - # Determine appropriate make concurrency - # Compilation can take a lot of memory, let's assume that that is limiting. - $procs = $this->getNumProcs(); - - # Run make. This is the slow step. - passthru( 'make -j' . wfEscapeShellArg( $procs ) ); - - $elapsed = time() - $startTime; - - echo "Completed in "; - if ( $elapsed >= 3600 ) { - $hours = floor( $elapsed / 3600 ); - echo $hours . 'h '; - $elapsed -= $hours * 3600; - } - if ( $elapsed >= 60 ) { - $minutes = floor( $elapsed / 60 ); - echo $minutes . 'm '; - $elapsed -= $minutes * 60; - } - echo $elapsed . "s\n"; - echo "The MediaWiki executable is at $buildDir/persistent/mediawiki-hphp\n"; - } - - function checkVolatileClasses( $dir ) { - $lines = file( "$dir/sys/dynamic_table_class.cpp" ); - $classes = array(); - foreach ( $lines as $line ) { - if ( preg_match( '/^\s+\(const char \*\)"([^"]*)", \(const char \*\)-1/', $line, $m ) ) { - $classes[] = $m[1]; - } - } - if ( !count( $classes ) ) { - print "No volatile classes found\n"; - return; - } - sort( $classes ); - $classes = array_unique( $classes ); - print "WARNING: The following classes are volatile: " . implode( ', ', $classes ) . "\n"; - } - - function getNumProcs() { - global $wgHipHopCompilerProcs; - if ( $wgHipHopCompilerProcs !== 'detect' ) { - return intval( $wgHipHopCompilerProcs ); - } - - if ( !file_exists( '/proc/meminfo' ) ) { - return 1; - } - $mem = false; - foreach ( file( '/proc/meminfo' ) as $line ) { - if ( preg_match( '/^MemTotal:\s+(\d+)\s+kB/', $line, $m ) ) { - $mem = intval( $m[1] ); - break; - } - } - if ( $mem ) { - // At least one process - return max( 1, floor( $mem / 1000000 ) ); - } else { - return 1; - } - } - - function setupFakeSourceBase( $phase3, $extensions, $dest ) { - if ( !file_exists( $dest ) ) { - mkdir( $dest, 0777, true ); - } - - $this->forceCreateLink( "$dest/phase3", $phase3 ); - $this->forceCreateLink( "$dest/extensions", $extensions ); - } - - function forceCreateLink( $target, $link ) { - if ( file_exists( $target ) ) { - if ( readlink( $target ) === $link ) { - return; - } - unlink( $target ); - } - symlink( $target, $link ); - } - - function getFileList() { - global $wgAutoloadClasses, $wgAutoloadLocalClasses, $wgCompiledFiles; - $inputFiles = array_merge( - array_values( $wgAutoloadClasses ), - array_values( $wgAutoloadLocalClasses ), - $wgCompiledFiles - ); - $processedFiles = array(); - foreach ( $inputFiles as $file ) { - if ( substr( $file, 0, 1 ) === '/' ) { - $processedFiles[] = $this->absoluteToRelative( $file ); - } elseif ( preg_match( '/^extensions/', $file ) ) { - $processedFiles[] = $file; - } else { - $processedFiles[] = "phase3/$file"; - } - } - - $extraCoreFiles = array_map( 'trim', file( __DIR__ . '/extra-files' ) ); - foreach ( $extraCoreFiles as $file ) { - if ( $file === '' ) { - continue; - } - $processedFiles[] = "phase3/$file"; - } - return array_unique( $processedFiles ); - } - - function absoluteToRelative( $file ) { - global $IP; - - $coreBase = realpath( $IP ) . '/'; - $extBase = realpath( MWInit::getExtensionsDirectory() ) . '/'; - $file = realpath( $file ); - - if ( substr( $file, 0, strlen( $extBase ) ) === $extBase ) { - return 'extensions/' . substr( $file, strlen( $extBase ) ); - } elseif ( substr( $file, 0, strlen( $coreBase ) ) === $coreBase ) { - return 'phase3/' . substr( $file, strlen( $coreBase ) ); - } else { - $this->error( "The following file is registered for compilation but is not in \$IP or " . - "\$wgExtensionsDirectory: $file \n" ); - exit( 1 ); - } - } -} - -$maintClass = 'MakeHipHop'; -require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/maintenance/hiphop/run-server b/maintenance/hiphop/run-server index 1adfe29f..2d71b871 100644 --- a/maintenance/hiphop/run-server +++ b/maintenance/hiphop/run-server @@ -1,68 +1,21 @@ -#!/usr/bin/hphpi -f +#!/usr/bin/hhvm -f <?php -require( __DIR__ . '/../Maintenance.php' ); +require __DIR__ . '/../Maintenance.php'; class RunHipHopServer extends Maintenance { function __construct() { parent::__construct(); - $this->addOption( 'interpret', 'Run in interpreted mode' ); } function execute() { - if ( $this->hasOption( 'interpret' ) ) { - $this->runInterpreted(); - } else { - $this->runCompiled(); - } - } - - function runCompiled() { - global $wgHipHopBuildDirectory; - $thisDir = realpath( __DIR__ ); - $IP = realpath( "$thisDir/../.." ); - if ( strval( $wgHipHopBuildDirectory ) !== '' ) { - $buildDir = $wgHipHopBuildDirectory; - } else { - $buildDir = "$thisDir/build"; - } - - if ( file_exists( "$buildDir/source" ) ) { - $sourceBase = "$buildDir/source"; - } else { - $sourceBase = realpath( "$IP/.." ); - } - - passthru( - 'cd ' . wfEscapeShellArg( $sourceBase ) . " && " . - 'MW_INSTALL_PATH=' . wfEscapeShellArg( $IP ) . ' ' . - wfEscapeShellArg( - "$buildDir/persistent/mediawiki-hphp", - '-c', "$thisDir/server.conf", - '-v', "Server.SourceRoot=$sourceBase", - '-v', "Server.IncludeSearchPaths.0=$sourceBase", - '-v', 'ServerVariables.MW_COMPILED=1', - '--mode=server', - '--port=8080' - ), - $ret - ); - exit( $ret ); - } - - function runInterpreted() { - $thisDir = realpath( __DIR__ ); - $IP = realpath( "$thisDir/../.." ); - $sourceBase = realpath( "$IP/.." ); + global $IP; passthru( - 'cd ' . wfEscapeShellArg( $sourceBase ) . " && " . - 'MW_INSTALL_PATH=' . wfEscapeShellArg( $IP ) . ' ' . + 'cd ' . wfEscapeShellArg( $IP ) . " && " . wfEscapeShellArg( - 'hphpi', - '-c', "$thisDir/server.conf", - '-v', "Server.SourceRoot=$sourceBase", - '-v', "Server.IncludeSearchPaths.0=$sourceBase", + 'hhvm', + '-c', __DIR__."/server.conf", '--mode=server', '--port=8080' ), @@ -72,4 +25,4 @@ class RunHipHopServer extends Maintenance { } } $maintClass = 'RunHipHopServer'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/hiphop/server.conf b/maintenance/hiphop/server.conf index 16af0f2f..558bdad8 100644 --- a/maintenance/hiphop/server.conf +++ b/maintenance/hiphop/server.conf @@ -12,7 +12,7 @@ Debug { } Server { EnableStaticContentCache = false - EnableStaticContentFromDisk = false + EnableStaticContentFromDisk = true AlwaysUseRelativePath = true } VirtualHost { @@ -22,7 +22,7 @@ VirtualHost { RewriteRules { * { pattern = ^/wiki/(.*)$ - to = /phase3/index.php?title=$1 + to = /index.php?title=$1 qsa = true } } diff --git a/maintenance/importDump.php b/maintenance/importDump.php index 904b6247..1f47cf12 100644 --- a/maintenance/importDump.php +++ b/maintenance/importDump.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that imports XML dump files into the current wiki. @@ -34,16 +34,16 @@ require_once( __DIR__ . '/Maintenance.php' ); class BackupReader extends Maintenance { public $reportingInterval = 100; public $pageCount = 0; - public $revCount = 0; - public $dryRun = false; - public $uploads = false; + public $revCount = 0; + public $dryRun = false; + public $uploads = false; public $imageBasePath = false; - public $nsFilter = false; + public $nsFilter = false; function __construct() { parent::__construct(); - $gz = in_array('compress.zlib', stream_get_wrappers()) ? 'ok' : '(disabled; requires PHP zlib module)'; - $bz2 = in_array('compress.bzip2', stream_get_wrappers()) ? 'ok' : '(disabled; requires PHP bzip2 module)'; + $gz = in_array( 'compress.zlib', stream_get_wrappers() ) ? 'ok' : '(disabled; requires PHP zlib module)'; + $bz2 = in_array( 'compress.bzip2', stream_get_wrappers() ) ? 'ok' : '(disabled; requires PHP bzip2 module)'; $this->mDescription = <<<TEXT This script reads pages from an XML file as produced from Special:Export or @@ -73,7 +73,7 @@ TEXT; } public function execute() { - if( wfReadOnly() ) { + if ( wfReadOnly() ) { $this->error( "Wiki is in read-only mode; you'll need to disable it for import to work.", true ); } @@ -91,7 +91,7 @@ TEXT; $this->setNsfilter( explode( '|', $this->getOption( 'namespaces' ) ) ); } - if( $this->hasArg() ) { + if ( $this->hasArg() ) { $this->importFromFile( $this->getArg() ); } else { $this->importFromStdin(); @@ -247,7 +247,7 @@ TEXT; function importFromStdin() { $file = fopen( 'php://stdin', 'rt' ); - if( self::posix_isatty( $file ) ) { + if ( self::posix_isatty( $file ) ) { $this->maybeHelp( true ); } return $this->importFromHandle( $file ); @@ -259,14 +259,14 @@ TEXT; $source = new ImportStreamSource( $handle ); $importer = new WikiImporter( $source ); - if( $this->hasOption( 'debug' ) ) { + if ( $this->hasOption( 'debug' ) ) { $importer->setDebug( true ); } if ( $this->hasOption( 'no-updates' ) ) { $importer->setNoUpdates( true ); } $importer->setPageCallback( array( &$this, 'reportPage' ) ); - $this->importCallback = $importer->setRevisionCallback( + $this->importCallback = $importer->setRevisionCallback( array( &$this, 'handleRevision' ) ); $this->uploadCallback = $importer->setUploadCallback( array( &$this, 'handleUpload' ) ); @@ -288,4 +288,4 @@ TEXT; } $maintClass = 'BackupReader'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/importImages.inc b/maintenance/importImages.inc index 2b3d5514..5ae6d6be 100644 --- a/maintenance/importImages.inc +++ b/maintenance/importImages.inc @@ -99,7 +99,9 @@ function findAuxFile( $file, $auxExtension, $maxStrip = 1 ) { } $idx = strrpos( $n, '.' ); - if ( !$idx ) break; + if ( !$idx ) { + break; + } $n = substr( $n, 0, $idx ); $maxStrip -= 1; diff --git a/maintenance/importImages.php b/maintenance/importImages.php index 782f502d..54fd4e2d 100644 --- a/maintenance/importImages.php +++ b/maintenance/importImages.php @@ -35,11 +35,11 @@ $optionsWithArgs = array( 'extensions', 'comment', 'comment-file', 'comment-ext', 'summary', 'user', 'license', 'sleep', 'limit', 'from', 'source-wiki-url', 'timestamp', ); -require_once( __DIR__ . '/commandLine.inc' ); -require_once( __DIR__ . '/importImages.inc' ); +require_once __DIR__ . '/commandLine.inc'; +require_once __DIR__ . '/importImages.inc'; $processed = $added = $ignored = $skipped = $overwritten = $failed = 0; -echo( "Import Images\n\n" ); +echo "Import Images\n\n"; # Need a path if ( count( $args ) == 0 ) { @@ -104,15 +104,15 @@ if ( $limit ) { $timestamp = isset( $options['timestamp'] ) ? $options['timestamp'] : false; # Get the upload comment. Provide a default one in case there's no comment given. -$comment = 'Importing image file'; +$comment = 'Importing file'; if ( isset( $options['comment-file'] ) ) { - $comment = file_get_contents( $options['comment-file'] ); + $comment = file_get_contents( $options['comment-file'] ); if ( $comment === false || $comment === null ) { die( "failed to read comment file: {$options['comment-file']}\n" ); } } elseif ( isset( $options['comment'] ) ) { - $comment = $options['comment']; + $comment = $options['comment']; } $commentExt = isset( $options['comment-ext'] ) ? $options['comment-ext'] : false; @@ -132,7 +132,7 @@ if ( $count > 0 ) { # Validate a title $title = Title::makeTitleSafe( NS_FILE, $base ); if ( !is_object( $title ) ) { - echo( "{$base} could not be imported; a valid title cannot be produced\n" ); + echo "{$base} could not be imported; a valid title cannot be produced\n"; continue; } @@ -148,7 +148,7 @@ if ( $count > 0 ) { if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) { $user->clearInstanceCache( 'name' ); // reload from DB! if ( $user->isBlocked() ) { - echo( $user->getName() . " was blocked! Aborting.\n" ); + echo $user->getName() . " was blocked! Aborting.\n"; break; } } @@ -157,10 +157,10 @@ if ( $count > 0 ) { $image = wfLocalFile( $title ); if ( $image->exists() ) { if ( isset( $options['overwrite'] ) ) { - echo( "{$base} exists, overwriting..." ); + echo "{$base} exists, overwriting..."; $svar = 'overwritten'; } else { - echo( "{$base} exists, skipping\n" ); + echo "{$base} exists, skipping\n"; $skipped++; continue; } @@ -172,23 +172,24 @@ if ( $count > 0 ) { $dupes = $repo->findBySha1( $sha1 ); if ( $dupes ) { - echo( "{$base} already exists as " . $dupes[0]->getName() . ", skipping\n" ); + echo "{$base} already exists as " . $dupes[0]->getName() . ", skipping\n"; $skipped++; continue; } } - echo( "Importing {$base}..." ); + echo "Importing {$base}..."; $svar = 'added'; } if ( isset( $options['source-wiki-url'] ) ) { /* find comment text directly from source wiki, through MW's API */ $real_comment = getFileCommentFromSourceWiki( $options['source-wiki-url'], $base ); - if ( $real_comment === false ) + if ( $real_comment === false ) { $commentText = $comment; - else + } else { $commentText = $real_comment; + } /* find user directly from source wiki, through MW's API */ $real_user = getFileUserFromSourceWiki( $options['source-wiki-url'], $base ); @@ -198,7 +199,7 @@ if ( $count > 0 ) { $wgUser = User::newFromName( $real_user ); if ( $wgUser === false ) { # user does not exist in target wiki - echo ( "failed: user '$real_user' does not exist in target wiki." ); + echo "failed: user '$real_user' does not exist in target wiki."; continue; } } @@ -209,11 +210,11 @@ if ( $count > 0 ) { if ( $commentExt ) { $f = findAuxFile( $file, $commentExt ); if ( !$f ) { - echo( " No comment file with extension {$commentExt} found for {$file}, using default comment. " ); + echo " No comment file with extension {$commentExt} found for {$file}, using default comment. "; } else { $commentText = file_get_contents( $f ); if ( !$commentText ) { - echo( " Failed to load comment file {$f}, using default comment. " ); + echo " Failed to load comment file {$f}, using default comment. "; } } } @@ -225,28 +226,37 @@ if ( $count > 0 ) { # Import the file if ( isset( $options['dry'] ) ) { - echo( " publishing {$file} by '" . $wgUser->getName() . "', comment '$commentText'... " ); + echo " publishing {$file} by '" . $wgUser->getName() . "', comment '$commentText'... "; } else { - $archive = $image->publish( $file ); + $props = FSFile::getPropsFromPath( $file ); + $flags = 0; + $publishOptions = array(); + $handler = MediaHandler::getHandler( $props['mime'] ); + if ( $handler ) { + $publishOptions['headers'] = $handler->getStreamHeaders( $props['metadata'] ); + } else { + $publishOptions['headers'] = array(); + } + $archive = $image->publish( $file, $flags, $publishOptions ); if ( !$archive->isGood() ) { - echo( "failed. (" . + echo "failed. (" . $archive->getWikiText() . - ")\n" ); + ")\n"; $failed++; continue; } } $commentText = SpecialUpload::getInitialPageText( $commentText, $license ); - if ( !$summary ) { + if ( !isset( $options['summary'] ) ) { $summary = $commentText; } if ( isset( $options['dry'] ) ) { - echo( "done.\n" ); - } elseif ( $image->recordUpload2( $archive->value, $summary, $commentText, false, $timestamp ) ) { + echo "done.\n"; + } elseif ( $image->recordUpload2( $archive->value, $summary, $commentText, $props, $timestamp ) ) { # We're done! - echo( "done.\n" ); + echo "done.\n"; $doProtect = false; @@ -269,21 +279,21 @@ if ( $count > 0 ) { sleep( 2.0 ); # Why this sleep? wfWaitForSlaves(); - echo( "\nSetting image restrictions ... " ); + echo "\nSetting image restrictions ... "; $cascade = false; $restrictions = array(); - foreach( $title->getRestrictionTypes() as $type ) { + foreach ( $title->getRestrictionTypes() as $type ) { $restrictions[$type] = $protectLevel; } $page = WikiPage::factory( $title ); $status = $page->doUpdateRestrictions( $restrictions, array(), $cascade, '', $user ); - echo( ( $status->isOK() ? 'done' : 'failed' ) . "\n" ); + echo ( $status->isOK() ? 'done' : 'failed' ) . "\n"; } } else { - echo( "failed. (at recordUpload stage)\n" ); + echo "failed. (at recordUpload stage)\n"; $svar = 'failed'; } @@ -300,23 +310,24 @@ if ( $count > 0 ) { } # Print out some statistics - echo( "\n" ); + echo "\n"; foreach ( array( 'count' => 'Found', 'limit' => 'Limit', 'ignored' => 'Ignored', 'added' => 'Added', 'skipped' => 'Skipped', 'overwritten' => 'Overwritten', 'failed' => 'Failed' ) as $var => $desc ) { - if ( $$var > 0 ) - echo( "{$desc}: {$$var}\n" ); + if ( $$var > 0 ) { + echo "{$desc}: {$$var}\n"; + } } } else { - echo( "No suitable files could be found for import.\n" ); + echo "No suitable files could be found for import.\n"; } exit( 0 ); function showUsage( $reason = false ) { if ( $reason ) { - echo( $reason . "\n" ); + echo $reason . "\n"; } echo <<<TEXT @@ -336,7 +347,7 @@ Options: --sleep=<sec> Sleep between files. Useful mostly for debugging. --user=<username> Set username of uploader, default 'Maintenance script' --check-userblock Check if the user got blocked during import. ---comment=<text> Set file description, default 'Importing image file'. +--comment=<text> Set file description, default 'Importing file'. --comment-file=<file> Set description to the content of <file>. --comment-ext=<ext> Causes the description for each file to be loaded from a file with the same name but the extension <ext>. If a global description is also given, it is appended. diff --git a/maintenance/importSiteScripts.php b/maintenance/importSiteScripts.php index fabc6dc6..fd768b34 100644 --- a/maintenance/importSiteScripts.php +++ b/maintenance/importSiteScripts.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to import all scripts in the MediaWiki namespace from a @@ -105,4 +105,4 @@ class ImportSiteScripts extends Maintenance { } $maintClass = 'ImportSiteScripts'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/importTextFile.php b/maintenance/importTextFile.php index c04989c0..e081c20b 100644 --- a/maintenance/importTextFile.php +++ b/maintenance/importTextFile.php @@ -24,15 +24,15 @@ $options = array( 'help', 'nooverwrite', 'norc' ); $optionsWithArgs = array( 'title', 'user', 'comment' ); -require_once( __DIR__ . '/commandLine.inc' ); -echo( "Import Text File\n\n" ); +require_once __DIR__ . '/commandLine.inc'; +echo "Import Text File\n\n"; if ( count( $args ) < 1 || isset( $options['help'] ) ) { showHelp(); } else { $filename = $args[0]; - echo( "Using {$filename}..." ); + echo "Using {$filename}..."; if ( is_file( $filename ) ) { $title = isset( $options['title'] ) ? $options['title'] : titleFromFilename( $filename ); @@ -40,7 +40,7 @@ if ( count( $args ) < 1 || isset( $options['help'] ) ) { if ( is_object( $title ) ) { - echo( "\nUsing title '" . $title->getPrefixedText() . "'..." ); + echo "\nUsing title '" . $title->getPrefixedText() . "'..."; if ( !$title->exists() || !isset( $options['nooverwrite'] ) ) { $text = file_get_contents( $filename ); @@ -49,31 +49,31 @@ if ( count( $args ) < 1 || isset( $options['help'] ) ) { if ( is_object( $user ) ) { - echo( "\nUsing username '" . $user->getName() . "'..." ); + echo "\nUsing username '" . $user->getName() . "'..."; $wgUser =& $user; $comment = isset( $options['comment'] ) ? $options['comment'] : 'Importing text file'; $flags = 0 | ( isset( $options['norc'] ) ? EDIT_SUPPRESS_RC : 0 ); - echo( "\nPerforming edit..." ); + echo "\nPerforming edit..."; $page = WikiPage::factory( $title ); $content = ContentHandler::makeContent( $text, $title ); $page->doEditContent( $content, $comment, $flags, false, $user ); - echo( "done.\n" ); + echo "done.\n"; } else { - echo( "invalid username.\n" ); + echo "invalid username.\n"; } } else { - echo( "page exists.\n" ); + echo "page exists.\n"; } } else { - echo( "invalid title.\n" ); + echo "invalid title.\n"; } } else { - echo( "does not exist.\n" ); + echo "does not exist.\n"; } } diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php index 3135b4c7..4b046835 100644 --- a/maintenance/initEditCount.php +++ b/maintenance/initEditCount.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; class InitEditCount extends Maintenance { public function __construct() { @@ -107,4 +107,4 @@ in the load balancer, usually indicating a replication environment.' ); } $maintClass = "InitEditCount"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/initSiteStats.php b/maintenance/initSiteStats.php index 19906592..92268b3e 100644 --- a/maintenance/initSiteStats.php +++ b/maintenance/initSiteStats.php @@ -23,7 +23,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to re-initialise or update the site statistics table @@ -48,7 +48,7 @@ class InitSiteStats extends Maintenance { $edits = $counter->edits(); $this->output( "{$edits}\nCounting number of articles..." ); - $good = $counter->articles(); + $good = $counter->articles(); $this->output( "{$good}\nCounting total pages..." ); $pages = $counter->pages(); @@ -85,4 +85,4 @@ class InitSiteStats extends Maintenance { } $maintClass = "InitSiteStats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/install.php b/maintenance/install.php index 935a2966..d118747a 100644 --- a/maintenance/install.php +++ b/maintenance/install.php @@ -22,14 +22,14 @@ */ if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.3.2' ) < 0 ) ) { - require_once( dirname( __FILE__ ) . '/../includes/PHPVersionError.php' ); + require_once dirname( __FILE__ ) . '/../includes/PHPVersionError.php'; wfPHPVersionError( 'cli' ); } define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' ); define( 'MEDIAWIKI_INSTALL', true ); -require_once( dirname( __DIR__ )."/maintenance/Maintenance.php" ); +require_once dirname( __DIR__ ) . "/maintenance/Maintenance.php"; /** * Maintenance script to install and configure MediaWiki @@ -41,7 +41,7 @@ class CommandLineInstaller extends Maintenance { parent::__construct(); global $IP; - $this->addArg( 'name', 'The name of the wiki', true); + $this->addArg( 'name', 'The name of the wiki', true ); $this->addArg( 'admin', 'The username of the wiki administrator (WikiSysop)', true ); $this->addOption( 'pass', 'The password for the wiki administrator.', false, true ); @@ -109,13 +109,13 @@ class CommandLineInstaller extends Maintenance { InstallerOverrides::getCliInstaller( $siteName, $adminName, $this->mOptions ); $status = $installer->doEnvironmentChecks(); - if( $status->isGood() ) { + if ( $status->isGood() ) { $installer->showMessage( 'config-env-good' ); } else { $installer->showStatusMessage( $status ); return; } - if( !$this->hasOption( 'env-checks' ) ) { + if ( !$this->hasOption( 'env-checks' ) ) { $installer->execute(); $installer->writeConfigurationFile( $this->getOption( 'confpath', $IP ) ); } @@ -130,4 +130,4 @@ class CommandLineInstaller extends Maintenance { $maintClass = "CommandLineInstaller"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/jsduck/MetaTags.rb b/maintenance/jsduck/MetaTags.rb index 84e40213..83cc0884 100644 --- a/maintenance/jsduck/MetaTags.rb +++ b/maintenance/jsduck/MetaTags.rb @@ -3,6 +3,22 @@ # - https://github.com/senchalabs/jsduck/wiki/Custom-tags require 'jsduck/meta_tag' +class SourceTag < JsDuck::MetaTag + def initialize + # This defines the name of the @tag + @name = 'source' + end + + # Generate HTML output for this tag. + # One can make use of the #format method to easily support + # Markdown and {@link} tags inside the contents of the tag. + # + # @param tags All matches of this tag on one class. + def to_html(tags) + '<h3 class="pa">Source</h3>' + tags.map {|tag| format(tag) }.join("\n") + end +end + class ContextTag < JsDuck::MetaTag def initialize @name = 'context' diff --git a/maintenance/jsduck/categories.json b/maintenance/jsduck/categories.json index 4a8ba8c3..f96902d8 100644 --- a/maintenance/jsduck/categories.json +++ b/maintenance/jsduck/categories.json @@ -9,21 +9,30 @@ "mw.Map", "mw.Message", "mw.loader", + "mw.log", "mw.html", "mw.html.Cdata", - "mw.html.Raw" + "mw.html.Raw", + "mw.hook" ] }, { "name": "General", "classes": [ "mw.Title", + "mw.inspect", + "mw.inspect.reports", "mw.notification", + "mw.user", "mw.util", - "mw.plugin.notify" + "mw.plugin.*" ] }, { + "name": "Actions", + "classes": ["mw.toolbar"] + }, + { "name": "API", "classes": ["mw.Api*"] } @@ -33,20 +42,20 @@ "name": "jQuery", "groups": [ { - "name": "Core", - "classes": ["jQuery", "jQuery.Event", "jQuery.Promise", "jQuery.Deferred", "jQuery.jqXHR"] - }, - { "name": "Plugins", "classes": ["jQuery.plugin.*"] } ] }, { - "name": "Misc", + "name": "Upstream", "groups": [ { - "name": "Native", + "name": "jQuery", + "classes": ["jQuery", "jQuery.Event", "jQuery.Callbacks", "jQuery.Promise", "jQuery.Deferred", "jQuery.jqXHR", "QUnit"] + }, + { + "name": "JavaScript", "classes": ["Array", "Boolean", "Date", "Function", "Number", "Object", "RegExp", "String"] } ] diff --git a/maintenance/jsduck/config.json b/maintenance/jsduck/config.json index c4705d8f..e6e0f658 100644 --- a/maintenance/jsduck/config.json +++ b/maintenance/jsduck/config.json @@ -1,18 +1,27 @@ { - "--title": "MediaWiki Code Documentation", + "--title": "MediaWiki core - Documentation", + "--footer": "Documentation for MediaWiki core. Generated on {DATE} by {JSDUCK} {VERSION}.", "--categories": "./categories.json", "--meta-tags": "./MetaTags.rb", + "--eg-iframe": "./eg-iframe.html", "--warnings": ["-no_doc"], "--builtin-classes": true, "--output": "../../docs/js", "--": [ "./external.js", "../../resources/mediawiki/mediawiki.js", + "../../resources/mediawiki/mediawiki.log.js", "../../resources/mediawiki/mediawiki.util.js", "../../resources/mediawiki/mediawiki.Title.js", + "../../resources/mediawiki/mediawiki.inspect.js", "../../resources/mediawiki/mediawiki.notify.js", "../../resources/mediawiki/mediawiki.notification.js", + "../../resources/mediawiki/mediawiki.user.js", + "../../resources/mediawiki.action/mediawiki.action.edit.js", + "../../resources/mediawiki.action/mediawiki.action.view.postEdit.js", + "../../resources/mediawiki.page/mediawiki.page.startup.js", "../../resources/mediawiki.api", - "../../resources/jquery/jquery.localize.js" + "../../resources/jquery/jquery.localize.js", + "../../resources/jquery/jquery.spinner.js" ] -}
\ No newline at end of file +} diff --git a/maintenance/jsduck/eg-iframe.html b/maintenance/jsduck/eg-iframe.html index f53b4044..86eae4b6 100644 --- a/maintenance/jsduck/eg-iframe.html +++ b/maintenance/jsduck/eg-iframe.html @@ -2,19 +2,87 @@ <html> <head> <meta charset="utf-8"> - <title>MediaWiki Examples</title> + <title>MediaWiki Code Example</title> + <script src="modules/startup.js"></script> <script> - function loadInlineExample(code, options, callback) { + function startUp() { + mw.config = new mw.Map(); + } + </script> + <script src="modules/jquery/jquery.js"></script> + <script src="modules/mediawiki/mediawiki.js"></script> + <style> + .mw-jsduck-log { + position: relative; + min-height: 3em; + margin-top: 2em; + background: #f7f7f7; + border: 1px solid #e4e4e4; + } + + .mw-jsduck-log::after { + position: absolute; + bottom: 100%; + right: -1px; + padding: 0.5em; + background: #fff; + border: 1px solid #e4e4e4; + border-bottom: 0; + border-radius: 0.5em 0.5em 0 0; + font: normal 0.5em sans-serif; + content: 'console'; + } + + .mw-jsduck-log-line { + padding: 0.2em 0.5em; + white-space: pre-wrap; + } + + .mw-jsduck-log-line:nth-child(odd) { + background: #fff; + } + </style> +</head> +<body> + <script> + /** + * Basic log console for the example iframe in documentation pages. + */ + ( function () { + var pre; + mw.log = function () { + var str, i, len, line; + if ( !pre ) { + pre = document.createElement( 'pre' ); + pre.className = 'mw-jsduck-log'; + document.body.appendChild( pre ); + } + str = []; + for ( i = 0, len = arguments.length; i < len; i++ ) { + str.push( String( arguments[ i ] ) ); + } + line = document.createElement( 'div' ); + line.className = 'mw-jsduck-log-line'; + line.appendChild( + document.createTextNode( str.join( ' , ' ) + '\n' ) + ); + pre.appendChild( line ); + }; + }() ); + + /** + * Method called by jsduck to execute the example code. + */ + function loadInlineExample( code, options, callback ) { try { - document.body.innerHTML = ''; - eval(code); - callback && callback(true); + eval( code ); + callback && callback( true ); } catch (e) { - document.body.innerHTML = document.createTextNode(e); - callback && callback(false, e); + mw.log( 'Uncaught exception: ' + e ); + callback && callback( false, e ); + throw e; } } </script> -</head> -<body></body> +</body> </html> diff --git a/maintenance/jsduck/external.js b/maintenance/jsduck/external.js index 8ab102f4..4bb83694 100644 --- a/maintenance/jsduck/external.js +++ b/maintenance/jsduck/external.js @@ -1,26 +1,44 @@ /** * @class jQuery + * @source <http://api.jquery.com/> */ /** * @method ajax + * @static + * @source <http://api.jquery.com/jQuery.ajax/> * @return {jqXHR} */ /** * @class jQuery.Event + * @source <http://api.jquery.com/Types/#Event> + */ + +/** + * @class jQuery.Callbacks + * @source <http://api.jquery.com/jQuery.Callbacks/> */ /** * @class jQuery.Promise + * @source <http://api.jquery.com/Types/#Promise> */ /** * @class jQuery.Deferred * @mixins jQuery.Promise + * @source <http://api.jquery.com/jQuery.Deferred/> */ /** * @class jQuery.jqXHR + * @source <http://api.jquery.com/Types/#jqXHR> * @alternateClassName jqXHR */ + + +/** + * @class QUnit + * @source <http://api.qunitjs.com/> + */ diff --git a/maintenance/jsparse.php b/maintenance/jsparse.php index 1a2e121c..3f0a9ba7 100644 --- a/maintenance/jsparse.php +++ b/maintenance/jsparse.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to do test JavaScript validity parses using jsmin+'s parser @@ -50,7 +50,7 @@ class JSParseHelper extends Maintenance { wfSuppressWarnings(); $js = file_get_contents( $filename ); wfRestoreWarnings(); - if ($js === false) { + if ( $js === false ) { $this->output( "$filename ERROR: could not read file\n" ); $this->errs++; continue; @@ -58,7 +58,7 @@ class JSParseHelper extends Maintenance { try { $parser->parse( $js, $filename, 1 ); - } catch (Exception $e) { + } catch ( Exception $e ) { $this->errs++; $this->output( "$filename ERROR: " . $e->getMessage() . "\n" ); continue; @@ -67,11 +67,11 @@ class JSParseHelper extends Maintenance { $this->output( "$filename OK\n" ); } - if ($this->errs > 0) { - exit(1); + if ( $this->errs > 0 ) { + exit( 1 ); } } } $maintClass = "JSParseHelper"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/lag.php b/maintenance/lag.php index 3df11692..410bf756 100644 --- a/maintenance/lag.php +++ b/maintenance/lag.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to show database lag. @@ -68,4 +68,4 @@ class DatabaseLag extends Maintenance { } $maintClass = "DatabaseLag"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/StatOutputs.php b/maintenance/language/StatOutputs.php index 20fb4778..e9d8c86d 100644 --- a/maintenance/language/StatOutputs.php +++ b/maintenance/language/StatOutputs.php @@ -1,5 +1,7 @@ <?php -if ( !defined( 'MEDIAWIKI' ) ) die(); +if ( !defined( 'MEDIAWIKI' ) ) { + die(); +} /** * Statistic output classes. * @@ -52,9 +54,9 @@ class wikiStatsOutput extends statsOutput { echo "'''Note:''' These statistics can be generated by running <code>php maintenance/language/transstat.php</code>.\n\n"; echo "For additional information on specific languages (the message names, the actual problems, etc.), run <code>php maintenance/language/checkLanguage.php --lang=foo</code>.\n\n"; echo 'English (en) is excluded because it is the default localization'; - if( is_array( $wgDummyLanguageCodes ) ) { + if ( is_array( $wgDummyLanguageCodes ) ) { $dummyCodes = array(); - foreach( $wgDummyLanguageCodes as $dummyCode => $correctCode ) { + foreach ( $wgDummyLanguageCodes as $dummyCode => $correctCode ) { $dummyCodes[] = Language::fetchLanguageName( $dummyCode ) . ' (' . $dummyCode . ')'; } echo ', as well as the following languages that are not intended for system message translations, usually because they redirect to other language codes: ' . implode( ', ', $dummyCodes ); @@ -80,7 +82,9 @@ class wikiStatsOutput extends statsOutput { # Weigh reverse with factor 20 so coloring takes effect more quickly as # this option is used solely for reporting 'bad' percentages. $v = $v * 20; - if ( $v > 255 ) $v = 255; + if ( $v > 255 ) { + $v = 255; + } $v = 255 - $v; } if ( $v < 128 ) { diff --git a/maintenance/language/alltrans.php b/maintenance/language/alltrans.php index 8caf8677..d0e6e849 100644 --- a/maintenance/language/alltrans.php +++ b/maintenance/language/alltrans.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that gets all messages as defined by the @@ -44,4 +44,4 @@ class AllTrans extends Maintenance { } $maintClass = "AllTrans"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/checkDupeMessages.php b/maintenance/language/checkDupeMessages.php index 6abf7b44..381ddae1 100644 --- a/maintenance/language/checkDupeMessages.php +++ b/maintenance/language/checkDupeMessages.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../commandLine.inc' ); +require_once __DIR__ . '/../commandLine.inc'; $messagesDir = __DIR__ . '/../../languages/messages/'; $runTest = false; $run = false; @@ -52,7 +52,7 @@ Options: * mode: Output format, can be either: * text: Text output on the console (default) * wiki: Wiki format, with * at beginning of each line - * php: Output text as PHP syntax in a array $dupeMessages + * php: Output text as PHP syntax in an array named \$dupeMessages * raw: Raw output for duplicates TEXT; } @@ -80,35 +80,37 @@ if ( $run ) { } elseif ( !strcmp( $runMode, 'raw' ) ) { $runMode = 'raw'; } - include( $messagesFile ); + include $messagesFile; $messageExist = isset( $messages ); - if ( $messageExist ) + if ( $messageExist ) { $wgMessages[$langCode] = $messages; - include( $messagesFileC ); + } + include $messagesFileC; $messageCExist = isset( $messages ); - if ( $messageCExist ) + if ( $messageCExist ) { $wgMessages[$langCodeC] = $messages; + } $count = 0; if ( ( $messageExist ) && ( $messageCExist ) ) { if ( !strcmp( $runMode, 'php' ) ) { - print( "<?php\n" ); - print( '$dupeMessages = array(' . "\n" ); + print "<?php\n"; + print '$dupeMessages = array(' . "\n"; } foreach ( $wgMessages[$langCodeC] as $key => $value ) { foreach ( $wgMessages[$langCode] as $ckey => $cvalue ) { if ( !strcmp( $key, $ckey ) ) { if ( ( !strcmp( $key, $ckey ) ) && ( !strcmp( $value, $cvalue ) ) ) { if ( !strcmp( $runMode, 'raw' ) ) { - print( "$key\n" ); + print "$key\n"; } elseif ( !strcmp( $runMode, 'php' ) ) { - print( "'$key' => '',\n" ); + print "'$key' => '',\n"; } elseif ( !strcmp( $runMode, 'wiki' ) ) { $uKey = ucfirst( $key ); - print( "* MediaWiki:$uKey/$langCode\n" ); + print "* MediaWiki:$uKey/$langCode\n"; } else { - print( "* $key\n" ); + print "* $key\n"; } $count++; } @@ -116,7 +118,7 @@ if ( $run ) { } } if ( !strcmp( $runMode, 'php' ) ) { - print( ");\n" ); + print ");\n"; } if ( !strcmp( $runMode, 'text' ) ) { if ( $count == 1 ) { @@ -126,9 +128,11 @@ if ( $run ) { } } } else { - if ( !$messageExist ) + if ( !$messageExist ) { echo "There are no messages defined in $langCode.\n"; - if ( !$messageCExist ) + } + if ( !$messageCExist ) { echo "There are no messages defined in $langCodeC.\n"; + } } } diff --git a/maintenance/language/checkExtensions.php b/maintenance/language/checkExtensions.php index ebc62b60..79a4dd98 100644 --- a/maintenance/language/checkExtensions.php +++ b/maintenance/language/checkExtensions.php @@ -21,14 +21,14 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../commandLine.inc' ); -require_once( 'languages.inc' ); -require_once( 'checkLanguage.inc' ); +require_once __DIR__ . '/../commandLine.inc'; +require_once 'languages.inc'; +require_once 'checkLanguage.inc'; if ( !class_exists( 'MessageGroups' ) || !class_exists( 'PremadeMediawikiExtensionGroups' ) ) { echo <<<TEXT Please add the Translate extension to LocalSettings.php, and enable the extension groups: - require_once( 'extensions/Translate/Translate.php' ); + require_once 'extensions/Translate/Translate.php'; \$wgTranslateEC = array_keys( \$wgTranslateAC ); If you still get this message, update Translate to its latest version. diff --git a/maintenance/language/checkLanguage.inc b/maintenance/language/checkLanguage.inc index 1860f4a5..4b49ada3 100644 --- a/maintenance/language/checkLanguage.inc +++ b/maintenance/language/checkLanguage.inc @@ -25,7 +25,7 @@ * @ingroup MaintenanceLanguage */ class CheckLanguageCLI { - protected $code = null; + protected $code = null; protected $level = 2; protected $doLinks = false; protected $linksPrefix = ''; @@ -46,7 +46,7 @@ class CheckLanguageCLI { public function __construct( array $options ) { if ( isset( $options['help'] ) ) { echo $this->help(); - exit(1); + exit( 1 ); } if ( isset( $options['lang'] ) ) { @@ -134,24 +134,24 @@ class CheckLanguageCLI { protected function getChecks() { return array( 'untranslated' => 'getUntranslatedMessages', - 'duplicate' => 'getDuplicateMessages', - 'obsolete' => 'getObsoleteMessages', - 'variables' => 'getMessagesWithMismatchVariables', - 'plural' => 'getMessagesWithoutPlural', - 'empty' => 'getEmptyMessages', - 'whitespace' => 'getMessagesWithWhitespace', - 'xhtml' => 'getNonXHTMLMessages', - 'chars' => 'getMessagesWithWrongChars', - 'links' => 'getMessagesWithDubiousLinks', - 'unbalanced' => 'getMessagesWithUnbalanced', - 'namespace' => 'getUntranslatedNamespaces', - 'projecttalk' => 'getProblematicProjectTalks', - 'magic' => 'getUntranslatedMagicWords', - 'magic-old' => 'getObsoleteMagicWords', - 'magic-over' => 'getOverridingMagicWords', - 'magic-case' => 'getCaseMismatchMagicWords', - 'special' => 'getUntraslatedSpecialPages', - 'special-old' => 'getObsoleteSpecialPages', + 'duplicate' => 'getDuplicateMessages', + 'obsolete' => 'getObsoleteMessages', + 'variables' => 'getMessagesWithMismatchVariables', + 'plural' => 'getMessagesWithoutPlural', + 'empty' => 'getEmptyMessages', + 'whitespace' => 'getMessagesWithWhitespace', + 'xhtml' => 'getNonXHTMLMessages', + 'chars' => 'getMessagesWithWrongChars', + 'links' => 'getMessagesWithDubiousLinks', + 'unbalanced' => 'getMessagesWithUnbalanced', + 'namespace' => 'getUntranslatedNamespaces', + 'projecttalk' => 'getProblematicProjectTalks', + 'magic' => 'getUntranslatedMagicWords', + 'magic-old' => 'getObsoleteMagicWords', + 'magic-over' => 'getOverridingMagicWords', + 'magic-case' => 'getCaseMismatchMagicWords', + 'special' => 'getUntraslatedSpecialPages', + 'special-old' => 'getObsoleteSpecialPages', ); } @@ -163,14 +163,14 @@ class CheckLanguageCLI { */ protected function getTotalCount() { return array( - 'namespace' => array( 'getNamespaceNames', 'en' ), - 'projecttalk' => null, - 'magic' => array( 'getMagicWords', 'en' ), - 'magic-old' => array( 'getMagicWords', null ), - 'magic-over' => array( 'getMagicWords', null ), - 'magic-case' => array( 'getMagicWords', null ), - 'special' => array( 'getSpecialPageAliases', 'en' ), - 'special-old' => array( 'getSpecialPageAliases', null ), + 'namespace' => array( 'getNamespaceNames', 'en' ), + 'projecttalk' => null, + 'magic' => array( 'getMagicWords', 'en' ), + 'magic-old' => array( 'getMagicWords', null ), + 'magic-over' => array( 'getMagicWords', null ), + 'magic-case' => array( 'getMagicWords', null ), + 'special' => array( 'getSpecialPageAliases', 'en' ), + 'special-old' => array( 'getSpecialPageAliases', null ), ); } @@ -181,24 +181,24 @@ class CheckLanguageCLI { protected function getDescriptions() { return array( 'untranslated' => '$1 message(s) of $2 are not translated to $3, but exist in en:', - 'duplicate' => '$1 message(s) of $2 are translated the same in en and $3:', - 'obsolete' => '$1 message(s) of $2 do not exist in en or are in the ignore list, but exist in $3:', - 'variables' => '$1 message(s) of $2 in $3 don\'t match the variables used in en:', - 'plural' => '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:', - 'empty' => '$1 message(s) of $2 in $3 are empty or -:', - 'whitespace' => '$1 message(s) of $2 in $3 have trailing whitespace:', - 'xhtml' => '$1 message(s) of $2 in $3 contain illegal XHTML:', - 'chars' => '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:', - 'links' => '$1 message(s) of $2 in $3 have problematic link(s):', - 'unbalanced' => '$1 message(s) of $2 in $3 have unbalanced {[]}:', - 'namespace' => '$1 namespace name(s) of $2 are not translated to $3, but exist in en:', - 'projecttalk' => '$1 namespace name(s) and alias(es) in $3 are project talk namespaces without the parameter:', - 'magic' => '$1 magic word(s) of $2 are not translated to $3, but exist in en:', - 'magic-old' => '$1 magic word(s) of $2 do not exist in en, but exist in $3:', - 'magic-over' => '$1 magic word(s) of $2 in $3 do not contain the original en word(s):', - 'magic-case' => '$1 magic word(s) of $2 in $3 change the case-sensitivity of the original en word:', - 'special' => '$1 special page alias(es) of $2 are not translated to $3, but exist in en:', - 'special-old' => '$1 special page alias(es) of $2 do not exist in en, but exist in $3:', + 'duplicate' => '$1 message(s) of $2 are translated the same in en and $3:', + 'obsolete' => '$1 message(s) of $2 do not exist in en or are in the ignore list, but exist in $3:', + 'variables' => '$1 message(s) of $2 in $3 don\'t match the variables used in en:', + 'plural' => '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:', + 'empty' => '$1 message(s) of $2 in $3 are empty or -:', + 'whitespace' => '$1 message(s) of $2 in $3 have trailing whitespace:', + 'xhtml' => '$1 message(s) of $2 in $3 contain illegal XHTML:', + 'chars' => '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:', + 'links' => '$1 message(s) of $2 in $3 have problematic link(s):', + 'unbalanced' => '$1 message(s) of $2 in $3 have unbalanced {[]}:', + 'namespace' => '$1 namespace name(s) of $2 are not translated to $3, but exist in en:', + 'projecttalk' => '$1 namespace name(s) and alias(es) in $3 are project talk namespaces without the parameter:', + 'magic' => '$1 magic word(s) of $2 are not translated to $3, but exist in en:', + 'magic-old' => '$1 magic word(s) of $2 do not exist in en, but exist in $3:', + 'magic-over' => '$1 magic word(s) of $2 in $3 do not contain the original en word(s):', + 'magic-case' => '$1 magic word(s) of $2 in $3 change the case-sensitivity of the original en word:', + 'special' => '$1 special page alias(es) of $2 are not translated to $3, but exist in en:', + 'special-old' => '$1 special page alias(es) of $2 do not exist in en, but exist in $3:', ); } @@ -222,7 +222,7 @@ Parameters: --links: Link the message values (default off). --prefix: prefix to add to links. --wikilang: For the links, what is the content language of the wiki to display the output in (default en). - --noexif: Do not check for EXIF messages (a bit hard and boring to translate), if you know + --noexif: Do not check for Exif messages (a bit hard and boring to translate), if you know that they are currently not translated and want to focus on other problems (default off). --whitelist: Do only the following checks (form: code,code). --blacklist: Do not do the following checks (form: code,code). @@ -299,6 +299,7 @@ ENDS; */ protected function getCheckBlacklist() { global $checkBlacklist; + return $checkBlacklist; } @@ -313,6 +314,7 @@ ENDS; $results = array(); if ( $this->level === 0 ) { $this->L->getMessages( $code ); + return $results; } @@ -320,7 +322,8 @@ ENDS; $checkBlacklist = $this->getCheckBlacklist(); foreach ( $this->checks as $check ) { if ( isset( $checkBlacklist[$code] ) && - in_array( $check, $checkBlacklist[$code] ) ) { + in_array( $check, $checkBlacklist[$code] ) + ) { $results[$check] = array(); continue; } @@ -384,7 +387,7 @@ ENDS; echo "[messages are hidden]\n"; } else { foreach ( $messages as $key => $value ) { - if( !in_array( $check, $this->nonMessageChecks() ) ) { + if ( !in_array( $check, $this->nonMessageChecks() ) ) { $key = $this->formatKey( $key, $code ); } if ( $this->level == 2 || empty( $value ) ) { @@ -411,7 +414,7 @@ ENDS; $problems = 0; $detailTextForLangChecks = array(); foreach ( $results as $check => $messages ) { - if( in_array( $check, $this->nonMessageChecks() ) ) { + if ( in_array( $check, $this->nonMessageChecks() ) ) { continue; } $count = count( $messages ); @@ -427,7 +430,6 @@ ENDS; } else { $numbers[] = $count; } - } if ( count( $detailTextForLangChecks ) ) { @@ -463,13 +465,14 @@ EOL; * @return bool True if there are any results, false if not. */ protected function isEmpty() { - foreach( $this->results as $results ) { - foreach( $results as $messages ) { - if( !empty( $messages ) ) { + foreach ( $this->results as $results ) { + foreach ( $results as $messages ) { + if ( !empty( $messages ) ) { return false; } } } + return true; } } @@ -488,7 +491,7 @@ class CheckExtensionsCLI extends CheckLanguageCLI { public function __construct( array $options, $extension ) { if ( isset( $options['help'] ) ) { echo $this->help(); - exit(1); + exit( 1 ); } if ( isset( $options['lang'] ) ) { @@ -645,16 +648,16 @@ ENDS; * @throws MWException */ protected function checkLanguage( $code ) { - foreach( $this->extensions as $extension ) { + foreach ( $this->extensions as $extension ) { $this->L = $extension; $this->results = array(); $this->results[$code] = parent::checkLanguage( $code ); - if( !$this->isEmpty() ) { + if ( !$this->isEmpty() ) { echo $extension->name() . ":\n"; - if( $this->level > 0 ) { - switch( $this->output ) { + if ( $this->level > 0 ) { + switch ( $this->output ) { case 'plain': $this->outputText(); break; @@ -675,48 +678,49 @@ ENDS; # Blacklist some checks for some languages $checkBlacklist = array( #'code' => array( 'check1', 'check2' ... ) -'az' => array( 'plural' ), -'bo' => array( 'plural' ), -'dz' => array( 'plural' ), -'id' => array( 'plural' ), -'fa' => array( 'plural' ), -'gan' => array( 'plural' ), -'gan-hans' => array( 'plural' ), -'gan-hant' => array( 'plural' ), -'gn' => array( 'plural' ), -'hak' => array( 'plural' ), -'hu' => array( 'plural' ), -'ja' => array( 'plural' ), // Does not use plural -'jv' => array( 'plural' ), -'ka' => array( 'plural' ), -'kk-arab' => array( 'plural' ), -'kk-cyrl' => array( 'plural' ), -'kk-latn' => array( 'plural' ), -'km' => array( 'plural' ), -'kn' => array( 'plural' ), -'ko' => array( 'plural' ), -'lzh' => array( 'plural' ), -'mn' => array( 'plural' ), -'ms' => array( 'plural' ), -'my' => array( 'plural', 'chars' ), // Uses a lot zwnj -'sah' => array( 'plural' ), -'sq' => array( 'plural' ), -'tet' => array( 'plural' ), -'th' => array( 'plural' ), -'to' => array( 'plural' ), -'tr' => array( 'plural' ), -'vi' => array( 'plural' ), -'wuu' => array( 'plural' ), -'xmf' => array( 'plural' ), -'yo' => array( 'plural' ), -'yue' => array( 'plural' ), -'zh' => array( 'plural' ), -'zh-classical' => array( 'plural' ), -'zh-cn' => array( 'plural' ), -'zh-hans' => array( 'plural' ), -'zh-hant' => array( 'plural' ), -'zh-hk' => array( 'plural' ), -'zh-sg' => array( 'plural' ), -'zh-tw' => array( 'plural' ), -'zh-yue' => array( 'plural' ), + 'az' => array( 'plural' ), + 'bo' => array( 'plural' ), + 'cdo' => array( 'plural' ), + 'dz' => array( 'plural' ), + 'id' => array( 'plural' ), + 'fa' => array( 'plural' ), + 'gan' => array( 'plural' ), + 'gan-hans' => array( 'plural' ), + 'gan-hant' => array( 'plural' ), + 'gn' => array( 'plural' ), + 'hak' => array( 'plural' ), + 'hu' => array( 'plural' ), + 'ja' => array( 'plural' ), // Does not use plural + 'jv' => array( 'plural' ), + 'ka' => array( 'plural' ), + 'kk-arab' => array( 'plural' ), + 'kk-cyrl' => array( 'plural' ), + 'kk-latn' => array( 'plural' ), + 'km' => array( 'plural' ), + 'kn' => array( 'plural' ), + 'ko' => array( 'plural' ), + 'lzh' => array( 'plural' ), + 'mn' => array( 'plural' ), + 'ms' => array( 'plural' ), + 'my' => array( 'plural', 'chars' ), // Uses a lot zwnj + 'sah' => array( 'plural' ), + 'sq' => array( 'plural' ), + 'tet' => array( 'plural' ), + 'th' => array( 'plural' ), + 'to' => array( 'plural' ), + 'tr' => array( 'plural' ), + 'vi' => array( 'plural' ), + 'wuu' => array( 'plural' ), + 'xmf' => array( 'plural' ), + 'yo' => array( 'plural' ), + 'yue' => array( 'plural' ), + 'zh' => array( 'plural' ), + 'zh-classical' => array( 'plural' ), + 'zh-cn' => array( 'plural' ), + 'zh-hans' => array( 'plural' ), + 'zh-hant' => array( 'plural' ), + 'zh-hk' => array( 'plural' ), + 'zh-sg' => array( 'plural' ), + 'zh-tw' => array( 'plural' ), + 'zh-yue' => array( 'plural' ), ); diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php index 99ba4e98..ec6e1226 100644 --- a/maintenance/language/checkLanguage.php +++ b/maintenance/language/checkLanguage.php @@ -21,9 +21,9 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../commandLine.inc' ); -require_once( 'checkLanguage.inc' ); -require_once( 'languages.inc' ); +require_once __DIR__ . '/../commandLine.inc'; +require_once 'checkLanguage.inc'; +require_once 'languages.inc'; $cli = new CheckLanguageCLI( $options ); diff --git a/maintenance/language/countMessages.php b/maintenance/language/countMessages.php index 5058a549..95a7154b 100644 --- a/maintenance/language/countMessages.php +++ b/maintenance/language/countMessages.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that counts how many messages we have defined @@ -59,7 +59,7 @@ class CountMessages extends Maintenance { private function getNumMessages( $file ) { // Separate function to limit scope - require( $file ); + require $file; if ( isset( $messages ) ) { return count( $messages ); } else { @@ -69,4 +69,4 @@ class CountMessages extends Maintenance { } $maintClass = "CountMessages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/date-formats.php b/maintenance/language/date-formats.php index ed12b786..14634185 100644 --- a/maintenance/language/date-formats.php +++ b/maintenance/language/date-formats.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that tests various language time and date functions. @@ -79,4 +79,4 @@ class DateFormats extends Maintenance { } $maintClass = "DateFormats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/digit2html.php b/maintenance/language/digit2html.php index 9d4cbe7e..a6e0456a 100644 --- a/maintenance/language/digit2html.php +++ b/maintenance/language/digit2html.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that check digit transformation. @@ -49,7 +49,7 @@ class Digit2Html extends Maintenance { $filename = Language::getMessagesFileName( $code ); $this->output( "Loading language [$code] ... " ); unset( $digitTransformTable ); - require_once( $filename ); + require_once $filename; if ( !isset( $digitTransformTable ) ) { $this->error( "\$digitTransformTable not found for lang: $code" ); continue; @@ -66,4 +66,4 @@ class Digit2Html extends Maintenance { } $maintClass = "Digit2Html"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/dumpMessages.php b/maintenance/language/dumpMessages.php index 0292d314..a72e25b8 100644 --- a/maintenance/language/dumpMessages.php +++ b/maintenance/language/dumpMessages.php @@ -23,7 +23,7 @@ * @todo Make this more useful, right now just dumps $wgContLang */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that dumps an entire language, using the keys from English. @@ -49,4 +49,4 @@ class DumpMessages extends Maintenance { } $maintClass = "DumpMessages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/generateCollationData.php b/maintenance/language/generateCollationData.php index 12823c0c..fcf2c960 100644 --- a/maintenance/language/generateCollationData.php +++ b/maintenance/language/generateCollationData.php @@ -21,7 +21,7 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ .'/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Generate first letter data files for Collation.php @@ -102,7 +102,7 @@ class GenerateCollationData extends Maintenance { $error .= "You are using outdated version of ICU ($icuVersion), intended for " . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" ) . "; this file might not be avalaible for it, and it's not supported by MediaWiki. " - ." You are on your own; consider upgrading PHP's intl extension or try " + . " You are on your own; consider upgrading PHP's intl extension or try " . "one of the files available at:"; } elseif ( version_compare( $icuVersion, "51.0", ">=" ) ) { // Extra recent version @@ -386,7 +386,7 @@ class UcdXmlReader { $this->xml = new XMLReader; $this->xml->open( $this->fileName ); if ( !$this->xml ) { - throw new MWException( __METHOD__.": unable to open {$this->fileName}" ); + throw new MWException( __METHOD__ . ": unable to open {$this->fileName}" ); } while ( $this->xml->name !== 'ucd' && $this->xml->read() ); $this->xml->read(); @@ -466,4 +466,4 @@ class UcdXmlReader { } $maintClass = 'GenerateCollationData'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/generateNormalizerData.php b/maintenance/language/generateNormalizerData.php index c03162c4..216445e4 100644 --- a/maintenance/language/generateNormalizerData.php +++ b/maintenance/language/generateNormalizerData.php @@ -21,9 +21,9 @@ * @ingroup MaintenanceLanguage */ -require_once( __DIR__ . '/../../includes/normal/UtfNormalUtil.php' ); +require_once __DIR__ . '/../../includes/normal/UtfNormalUtil.php'; -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Generates normalizer data files for Arabic and Malayalam. @@ -156,4 +156,4 @@ class GenerateNormalizerData extends Maintenance { } $maintClass = 'GenerateNormalizerData'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/langmemusage.php b/maintenance/language/langmemusage.php index ad29efb2..14485f98 100644 --- a/maintenance/language/langmemusage.php +++ b/maintenance/language/langmemusage.php @@ -22,8 +22,8 @@ */ /** This is a command line script */ -require_once( __DIR__ . '/../Maintenance.php' ); -require_once( __DIR__ . '/languages.inc' ); +require_once __DIR__ . '/../Maintenance.php'; +require_once __DIR__ . '/languages.inc'; /** * Maintenance script that tries to get the memory usage for each language file. @@ -39,8 +39,9 @@ class LangMemUsage extends Maintenance { } public function execute() { - if ( !function_exists( 'memory_get_usage' ) ) + if ( !function_exists( 'memory_get_usage' ) ) { $this->error( "You must compile PHP with --enable-memory-limit", true ); + } $langtool = new languages(); $memlast = $memstart = memory_get_usage(); @@ -61,4 +62,4 @@ class LangMemUsage extends Maintenance { } $maintClass = "LangMemUsage"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc index dcd9b9b4..6070f4ab 100644 --- a/maintenance/language/languages.inc +++ b/maintenance/language/languages.inc @@ -43,10 +43,10 @@ class languages { * Load the list of languages: all the Messages*.php * files in the languages directory. * - * @param $exif bool Treat the EXIF messages? + * @param $exif bool Treat the Exif messages? */ function __construct( $exif = true ) { - require( __DIR__ . '/messageTypes.inc' ); + require __DIR__ . '/messageTypes.inc'; $this->mIgnoredMessages = $wgIgnoredMessages; if ( $exif ) { $this->mOptionalMessages = array_merge( $wgOptionalMessages ); @@ -107,7 +107,7 @@ class languages { $this->mSpecialPageAliases[$code] = array(); $filename = Language::getMessagesFileName( $code ); if ( file_exists( $filename ) ) { - require( $filename ); + require $filename; if ( isset( $messages ) ) { $this->mRawMessages[$code] = $messages; } @@ -154,7 +154,7 @@ class languages { if ( isset( $this->mGeneralMessages['required'][$key] ) ) { $this->mMessages[$code]['required'][$key] = $value; $this->mMessages[$code]['translated'][$key] = $value; - } else if ( isset( $this->mGeneralMessages['optional'][$key] ) ) { + } elseif ( isset( $this->mGeneralMessages['optional'][$key] ) ) { $this->mMessages[$code]['optional'][$key] = $value; $this->mMessages[$code]['translated'][$key] = $value; } else { @@ -184,7 +184,7 @@ class languages { foreach ( $this->mGeneralMessages['all'] as $key => $value ) { if ( in_array( $key, $this->mIgnoredMessages ) ) { $this->mGeneralMessages['ignored'][$key] = $value; - } else if ( in_array( $key, $this->mOptionalMessages ) ) { + } elseif ( in_array( $key, $this->mOptionalMessages ) ) { $this->mGeneralMessages['optional'][$key] = $value; $this->mGeneralMessages['translatable'][$key] = $value; } else { @@ -466,11 +466,11 @@ class languages { '[POP]' => "\xE2\x80\xAC", '[LRO]' => "\xE2\x80\xAD", '[RLO]' => "\xE2\x80\xAB", - '[ZWSP]'=> "\xE2\x80\x8B", - '[NBSP]'=> "\xC2\xA0", - '[WJ]' => "\xE2\x81\xA0", + '[ZWSP]' => "\xE2\x80\x8B", + '[NBSP]' => "\xC2\xA0", + '[WJ]' => "\xE2\x81\xA0", '[BOM]' => "\xEF\xBB\xBF", - '[FFFD]'=> "\xEF\xBF\xBD", + '[FFFD]' => "\xEF\xBF\xBD", ); $wrongRegExp = '/(' . implode( '|', array_values( $wrongChars ) ) . ')/sDu'; $wrongCharsMessages = array(); @@ -500,8 +500,8 @@ class languages { foreach ( $this->mMessages[$code]['translated'] as $key => $value ) { $matches = array(); preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $value, $matches ); - for ($i = 0; $i < count($matches[0]); $i++ ) { - if ( preg_match( "/.*project.*/isDu", $matches[1][$i] ) ) { + for ( $i = 0; $i < count( $matches[0] ); $i++ ) { + if ( preg_match( "/.*project.*/isDu", $matches[1][$i] ) ) { $messages[$key][] = $matches[0][$i]; } } @@ -563,7 +563,9 @@ class languages { $this->loadFile( 'en' ); $this->loadFile( $code ); $namespacesDiff = array_diff_key( $this->mNamespaceNames['en'], $this->mNamespaceNames[$code] ); - if ( isset( $namespacesDiff[NS_MAIN] ) ) unset( $namespacesDiff[NS_MAIN] ); + if ( isset( $namespacesDiff[NS_MAIN] ) ) { + unset( $namespacesDiff[NS_MAIN] ); + } return $namespacesDiff; } @@ -579,7 +581,7 @@ class languages { $namespaces = array(); # Check default namespace name - if( isset( $this->mNamespaceNames[$code][NS_PROJECT_TALK] ) ) { + if ( isset( $this->mNamespaceNames[$code][NS_PROJECT_TALK] ) ) { $default = $this->mNamespaceNames[$code][NS_PROJECT_TALK]; if ( strpos( $default, '$1' ) === false ) { $namespaces[$default] = 'default'; @@ -587,7 +589,7 @@ class languages { } # Check namespace aliases - foreach( $this->mNamespaceAliases[$code] as $key => $value ) { + foreach ( $this->mNamespaceAliases[$code] as $key => $value ) { if ( $value == NS_PROJECT_TALK && strpos( $key, '$1' ) === false ) { $namespaces[$key] = ''; } @@ -758,9 +760,9 @@ class extensionLanguages extends languages { * @param $code string The language code. */ protected function loadFile( $code ) { - if( !isset( $this->mRawMessages[$code] ) ) { + if ( !isset( $this->mRawMessages[$code] ) ) { $this->mRawMessages[$code] = $this->mMessageGroup->load( $code ); - if( empty( $this->mRawMessages[$code] ) ) { + if ( empty( $this->mRawMessages[$code] ) ) { $this->mRawMessages[$code] = array(); } } diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 66cc1dcc..8676d741 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -96,7 +96,6 @@ $wgIgnoredMessages = array( 'talkpageheader', 'anonnotice', 'autoblock_whitelist', - 'searchmenu-help', 'searchmenu-new-nocreate', 'googlesearch', 'opensearch-desc', @@ -142,6 +141,7 @@ $wgIgnoredMessages = array( 'statistics-footer', 'talkpagetext', 'uploadfooter', + 'upload-default-description', 'listgrouprights-link', 'search-interwiki-custom', 'allpages-summary', @@ -224,6 +224,8 @@ $wgIgnoredMessages = array( 'deletedarticle', // 'uploadedimage', // 'overwroteimage', + 'createacct-helpusername', + 'createacct-imgcaptcha-help', 'userlogout-summary', 'changeemail-summary', 'changepassword-summary', @@ -242,18 +244,29 @@ $wgIgnoredMessages = array( 'version-summary', 'tags-summary', 'comparepages-summary', + 'resettokens-summary', 'version-entrypoints-index-php', 'version-entrypoints-api-php', 'version-entrypoints-load-php', 'ipb-default-expiry', 'pageinfo-header', 'pageinfo-footer', + 'createacct-benefit-head1', + 'createacct-benefit-icon1', + 'createacct-benefit-head2', + 'createacct-benefit-icon2', + 'createacct-benefit-head3', + 'createacct-benefit-icon3', + 'today-at', + 'redirect-text', + 'edithelppage', + 'autocomment-prefix', + 'move-redirect-text', ); /** Optional messages, which may be translated only if changed in the target language. */ $wgOptionalMessages = array( 'linkprefix', - 'editsection-brackets', 'feed-atom', 'feed-rss', 'unit-pixel', @@ -297,40 +310,24 @@ $wgOptionalMessages = array( 'resetpass_text', 'image_sample', 'media_sample', - 'skinname-standard', - 'skinname-nostalgia', 'skinname-cologneblue', 'skinname-monobook', - 'skinname-myskin', - 'skinname-chick', - 'skinname-simple', 'skinname-modern', 'skinname-vector', 'common.css', - 'standard.css', - 'nostalgia.css', 'cologneblue.css', 'monobook.css', - 'myskin.css', - 'chick.css', - 'simple.css', 'modern.css', 'vector.css', 'print.css', - 'handheld.css', 'noscript.css', 'group-autoconfirmed.css', 'group-bot.css', 'group-sysop.css', 'group-bureaucrat.css', 'common.js', - 'standard.js', - 'nostalgia.js', 'cologneblue.js', 'monobook.js', - 'myskin.js', - 'chick.js', - 'simple.js', 'modern.js', 'vector.js', 'group-autoconfirmed.js', @@ -460,7 +457,6 @@ $wgOptionalMessages = array( 'percent', 'parentheses', 'brackets', - 'autocomment-prefix', 'listgrouprights-right-display', 'listgrouprights-right-revoked', 'timezone-utc', @@ -485,9 +481,14 @@ $wgOptionalMessages = array( 'pageinfo-redirects-value', 'created', // @deprecated. Remove in MediaWiki 1.23. 'changed', // @deprecated. Remove in MediaWiki 1.23. + 'limitreport-ppvisitednodes-value', + 'limitreport-ppgeneratednodes-value', + 'limitreport-expansiondepth-value', + 'limitreport-expensivefunctioncount-value', + 'tooltip-iwiki', ); -/** EXIF messages, which may be set as optional in several checks, but are generally mandatory */ +/** Exif messages, which may be set as optional in several checks, but are generally mandatory */ $wgEXIFMessages = array( 'exif-imagewidth', 'exif-imagelength', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index c2d5847d..5e8e9744 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -56,9 +56,6 @@ $wgMessageStructure = array( 'tog-shownumberswatching', 'tog-oldsig', 'tog-fancysig', - 'tog-externaleditor', - 'tog-externaldiff', - 'tog-showjumplinks', 'tog-uselivepreview', 'tog-forceeditsummary', 'tog-watchlisthideown', @@ -72,6 +69,8 @@ $wgMessageStructure = array( 'tog-showhiddencats', 'tog-noconvertlink', 'tog-norollbackdiff', + 'tog-useeditwarning', + 'tog-prefershttps' ), 'underline' => array( 'underline-always', @@ -136,6 +135,18 @@ $wgMessageStructure = array( 'oct', 'nov', 'dec', + 'january-date', + 'february-date', + 'march-date', + 'april-date', + 'may-date', + 'june-date', + 'july-date', + 'august-date', + 'september-date', + 'october-date', + 'november-date', + 'december-date', ), 'categorypages' => array( 'pagecategories', @@ -226,6 +237,7 @@ $wgMessageStructure = array( 'create-this-page', 'delete', 'deletethispage', + 'undeletethispage', 'undelete_short', 'viewdeleted_short', 'protect', @@ -313,7 +325,6 @@ $wgMessageStructure = array( 'youhavenewmessagesmulti', 'newtalkseparator', 'editsection', - 'editsection-brackets', 'editold', 'viewsourceold', 'editlink', @@ -366,8 +377,11 @@ $wgMessageStructure = array( 'errors' => array( 'error', 'databaseerror', - 'dberrortext', - 'dberrortextcl', + 'databaseerror-text', + 'databaseerror-textcl', + 'databaseerror-query', + 'databaseerror-function', + 'databaseerror-error', 'laggedslavemode', 'readonly', 'enterlockreason', @@ -392,6 +406,7 @@ $wgMessageStructure = array( 'cannotdelete', 'cannotdelete-title', 'delete-hook-aborted', + 'no-null-revision', 'badtitle', 'badtitletext', 'perfcached', @@ -407,11 +422,14 @@ $wgMessageStructure = array( 'viewyourtext', 'protectedinterface', 'editinginterface', - 'sqlhidden', 'cascadeprotected', 'namespaceprotected', 'customcssprotected', 'customjsprotected', + 'mycustomcssprotected', + 'mycustomjsprotected', + 'myprivateinfoprotected', + 'mypreferencesprotected', 'ns-specialprotected', 'titleprotected', 'filereadonlyerror', @@ -430,10 +448,20 @@ $wgMessageStructure = array( 'welcomeuser', 'welcomecreation-msg', 'yourname', + 'userlogin-yourname', + 'userlogin-yourname-ph', + 'createacct-another-username-ph', + 'createacct-helpusername', 'yourpassword', + 'userlogin-yourpassword', + 'userlogin-yourpassword-ph', + 'createacct-yourpassword-ph', 'yourpasswordagain', + 'createacct-yourpasswordagain', + 'createacct-yourpasswordagain-ph', 'remembermypassword', - 'securelogin-stick-https', + 'userlogin-remembermypassword', + 'userlogin-signwithsecure', 'yourdomainname', 'password-change-forbidden', 'externaldberror', @@ -446,17 +474,49 @@ $wgMessageStructure = array( 'userlogout', 'userlogout-summary', 'notloggedin', + 'userlogin-noaccount', + 'userlogin-joinproject', 'nologin', 'nologinlink', 'createaccount', 'gotaccount', 'gotaccountlink', 'userlogin-resetlink', + 'userlogin-resetpassword-link', + 'helplogin-url', + 'userlogin-helplink', + 'userlogin-loggedin', + 'userlogin-createanother', + 'createacct-join', + 'createacct-another-join', + 'createacct-emailrequired', + 'createacct-emailoptional', + 'createacct-email-ph', + 'createacct-another-email-ph', 'createaccountmail', + 'createacct-realname', 'createaccountreason', + 'createacct-reason', + 'createacct-reason-ph', + 'createacct-captcha', + 'createacct-imgcaptcha-help', + 'createacct-imgcaptcha-ph', + 'createacct-submit', + 'createacct-another-submit', + 'createacct-benefit-heading', + 'createacct-benefit-icon1', + 'createacct-benefit-head1', + 'createacct-benefit-body1', + 'createacct-benefit-icon2', + 'createacct-benefit-head2', + 'createacct-benefit-body2', + 'createacct-benefit-icon3', + 'createacct-benefit-head3', + 'createacct-benefit-body3', 'badretype', 'userexists', 'loginerror', + 'createacct-error', 'createaccounterror', 'nocookiesnew', 'nocookieslogin', @@ -508,6 +568,7 @@ $wgMessageStructure = array( 'loginlanguagelabel', 'loginlanguagelinks', 'suspicious-userlogout', + 'createacct-another-realname-tip', ), 'mail' => array( 'pear-mail-error', @@ -525,7 +586,7 @@ $wgMessageStructure = array( 'newpassword', 'retypenew', 'resetpass_submit', - 'resetpass_success', + 'changepassword-success', 'resetpass_forbidden', 'resetpass-no-info', 'resetpass-submit-loggedin', @@ -536,10 +597,11 @@ $wgMessageStructure = array( ), 'passwordreset' => array( 'passwordreset', - 'passwordreset-text', + 'passwordreset-text-one', + 'passwordreset-text-many', 'passwordreset-legend', 'passwordreset-disabled', - 'passwordreset-pretext', + 'passwordreset-emaildisabled', 'passwordreset-username', 'passwordreset-domain', 'passwordreset-capture', @@ -566,6 +628,18 @@ $wgMessageStructure = array( 'changeemail-submit', 'changeemail-cancel', ), + 'resettokens' => array( + 'resettokens', + 'resettokens-summary', + 'resettokens-text', + 'resettokens-no-tokens', + 'resettokens-legend', + 'resettokens-tokens', + 'resettokens-token-label', + 'resettokens-watchlist-token', + 'resettokens-done', + 'resettokens-resetbutton', + ), 'toolbar' => array( 'bold_sample', 'bold_tip', @@ -689,6 +763,7 @@ $wgMessageStructure = array( 'edit-gone-missing', 'edit-conflict', 'edit-no-change', + 'postedit-confirmation', 'edit-already-exists', 'addsection-preload', 'addsection-editintro', @@ -696,6 +771,7 @@ $wgMessageStructure = array( 'content-failed-to-parse', 'invalid-content-data', 'content-not-allowed-here', + 'editwarning-warning', ), 'contentmodels' => array( 'content-model-wikitext', @@ -726,6 +802,7 @@ $wgMessageStructure = array( 'undo-failure', 'undo-norev', 'undo-summary', + 'undo-summary-username-hidden', ), 'cantcreateaccount' => array( 'cantcreateaccounttitle', @@ -874,6 +951,7 @@ $wgMessageStructure = array( 'compareselectedversions', 'showhideselectedversions', 'editundo', + 'diff-empty', 'diff-multi', 'diff-multi-manyusers', 'difference-missing-revision', @@ -900,9 +978,7 @@ $wgMessageStructure = array( 'searchmenu-exists', 'searchmenu-new', 'searchmenu-new-nocreate', - 'searchhelp-url', 'searchmenu-prefix', - 'searchmenu-help', 'searchprofile-articles', 'searchprofile-project', 'searchprofile-images', @@ -944,19 +1020,11 @@ $wgMessageStructure = array( 'search-external', 'searchdisabled', 'googlesearch', + 'search-error', ), 'opensearch' => array( 'opensearch-desc', ), - 'quickbar' => array( - 'qbsettings', - 'qbsettings-none', - 'qbsettings-fixedleft', - 'qbsettings-fixedright', - 'qbsettings-floatingleft', - 'qbsettings-floatingright', - 'qbsettings-directionality', - ), 'preferences' => array( 'preferences', 'preferences-summary', @@ -991,7 +1059,6 @@ $wgMessageStructure = array( 'resetprefs', 'restoreprefs', 'prefs-editing', - 'prefs-edit-boxsize', 'rows', 'columns', 'searchresultshead', @@ -1002,7 +1069,7 @@ $wgMessageStructure = array( 'recentchangesdays-max', 'recentchangescount', 'prefs-help-recentchangescount', - 'prefs-help-watchlist-token', + 'prefs-help-watchlist-token2', 'savedprefs', 'timezonelegend', 'localtime', @@ -1033,7 +1100,6 @@ $wgMessageStructure = array( 'prefs-common-css-js', 'prefs-reset-intro', 'prefs-emailconfirm-label', - 'prefs-textboxsize', 'youremail', 'username', 'uid', @@ -1068,6 +1134,8 @@ $wgMessageStructure = array( 'prefs-dateformat', 'prefs-timeoffset', 'prefs-advancedediting', + 'prefs-editor', + 'prefs-preview', 'prefs-advancedrc', 'prefs-advancedrendering', 'prefs-advancedsearchoptions', @@ -1075,7 +1143,9 @@ $wgMessageStructure = array( 'prefs-displayrc', 'prefs-displaysearchoptions', 'prefs-displaywatchlist', + 'prefs-tokenwatchlist', 'prefs-diffs', + 'prefs-help-prefershttps', ), 'preferences-email' => array( 'email-address-validity-valid', @@ -1102,6 +1172,8 @@ $wgMessageStructure = array( 'userrights-changeable-col', 'userrights-unchangeable-col', 'userrights-irreversible-marker', + 'userrights-conflict', + 'userrights-removed-self', ), 'group' => array( 'group', @@ -1170,10 +1242,18 @@ $wgMessageStructure = array( 'right-unblockself', 'right-protect', 'right-editprotected', + 'right-editsemiprotected', 'right-editinterface', 'right-editusercssjs', 'right-editusercss', 'right-edituserjs', + 'right-editmyusercss', + 'right-editmyuserjs', + 'right-viewmywatchlist', + 'right-editmywatchlist', + 'right-viewmyprivateinfo', + 'right-editmyprivateinfo', + 'right-editmyoptions', 'right-rollback', 'right-markbotedits', 'right-noratelimit', @@ -1235,14 +1315,21 @@ $wgMessageStructure = array( 'action-userrights-interwiki', 'action-siteadmin', 'action-sendemail', + 'action-editmywatchlist', + 'action-viewmywatchlist', + 'action-viewmyprivateinfo', + 'action-editmyprivateinfo', ), 'recentchanges' => array( 'nchanges', + 'enhancedrc-since-last-visit', + 'enhancedrc-history', 'recentchanges', 'recentchanges-url', 'recentchanges-legend', 'recentchanges-summary', 'recentchangestext', + 'recentchanges-noresult', 'recentchanges-feed-description', 'recentchanges-label-newpage', 'recentchanges-label-minor', @@ -1282,7 +1369,6 @@ $wgMessageStructure = array( 'recentchangeslinked-feed', 'recentchangeslinked-toolbox', 'recentchangeslinked-title', - 'recentchangeslinked-noresult', 'recentchangeslinked-summary', 'recentchangeslinked-page', 'recentchangeslinked-to', @@ -1304,6 +1390,7 @@ $wgMessageStructure = array( 'upload-preferred', 'upload-prohibited', 'uploadfooter', + 'upload-default-description', 'uploadlog', 'uploadlogpage', 'uploadlogpagetext', @@ -1481,7 +1568,6 @@ $wgMessageStructure = array( 'http-read-error', 'http-timed-out', 'http-curl-error', - 'http-host-unreachable', 'http-bad-status', ), @@ -1512,6 +1598,10 @@ $wgMessageStructure = array( 'listfiles_size', 'listfiles_description', 'listfiles_count', + 'listfiles-show-all', + 'listfiles-latestversion', + 'listfiles-latestversion-yes', + 'listfiles-latestversion-no', ), 'filedescription' => array( 'file-anchor-link', @@ -1605,6 +1695,13 @@ $wgMessageStructure = array( 'randompage-nopages', 'randompage-url', ), + 'randomincategory' => array( + 'randomincategory', + 'randomincategory-invalidcategory', + 'randomincategory-nopages', + 'randomincategory-selectcategory', + 'randomincategory-selectcategory-submit', + ), 'randomredirect' => array( 'randomredirect', 'randomredirect-nopages', @@ -1632,12 +1729,6 @@ $wgMessageStructure = array( 'statistics-mostpopular', 'statistics-footer', ), - 'disambiguations' => array( - 'disambiguations', - 'disambiguations-summary', - 'disambiguationspage', - 'disambiguations-text', - ), 'pageswithprop' => array( 'pageswithprop', 'pageswithprop-summary', @@ -1645,6 +1736,8 @@ $wgMessageStructure = array( 'pageswithprop-text', 'pageswithprop-prop', 'pageswithprop-submit', + 'pageswithprop-prophidden-long', + 'pageswithprop-prophidden-binary', ), 'doubleredirects' => array( 'doubleredirects', @@ -1728,6 +1821,7 @@ $wgMessageStructure = array( 'prefixindex', 'prefixindex-namespace', 'prefixindex-summary', + 'prefixindex-strip', 'shortpages', 'shortpages-summary', 'longpages', @@ -1749,6 +1843,7 @@ $wgMessageStructure = array( 'listusers-summary', 'listusers-editsonly', 'listusers-creationsort', + 'listusers-desc', 'usereditcount', 'usercreated', 'newpages', @@ -1934,7 +2029,6 @@ $wgMessageStructure = array( 'unwatchthispage', 'notanarticle', 'notvisiblerev', - 'watchnochange', 'watchlist-details', 'wlheader-enotif', 'wlheader-showupdated', @@ -2284,14 +2378,12 @@ $wgMessageStructure = array( 'ipb_blocked_as_range', 'ip_range_invalid', 'ip_range_toolarge', - 'blockme', 'proxyblocker', - 'proxyblocker-disabled', 'proxyblockreason', - 'proxyblocksuccess', 'sorbs', 'sorbsreason', 'sorbs_create_account_reason', + 'xffblockreason', 'cant-block-while-blocked', 'cant-see-hidden-user', 'ipbblocked', @@ -2355,6 +2447,7 @@ $wgMessageStructure = array( 'movesubpagetext', 'movenosubpage', 'movereason', + 'move-redirect-text', 'revertmove', 'delete_and_move', 'delete_and_move_text', @@ -2416,6 +2509,7 @@ $wgMessageStructure = array( 'thumbnail-more', 'filemissing', 'thumbnail_error', + 'thumbnail_error_remote', 'djvu_page_error', 'djvu_no_xml', 'thumbnail-temp-create', @@ -2488,7 +2582,7 @@ $wgMessageStructure = array( 'javascripttest-pagetext-noframework', 'javascripttest-pagetext-unknownframework', 'javascripttest-pagetext-frameworks', - 'javascripttest-pagetext-skins' , + 'javascripttest-pagetext-skins', 'javascripttest-qunit-name', 'javascripttest-qunit-intro', 'javascripttest-qunit-heading', @@ -2633,20 +2727,15 @@ $wgMessageStructure = array( 'tooltip-undo', 'tooltip-preferences-save', 'tooltip-summary', + 'interlanguage-link-title', ), 'stylesheets' => array( 'common.css', - 'standard.css', - 'nostalgia.css', 'cologneblue.css', 'monobook.css', - 'myskin.css', - 'chick.css', - 'simple.css', 'modern.css', 'vector.css', 'print.css', - 'handheld.css', 'noscript.css', 'group-autoconfirmed.css', 'group-bot.css', @@ -2655,13 +2744,8 @@ $wgMessageStructure = array( ), 'scripts' => array( 'common.js', - 'standard.js', - 'nostalgia.js', 'cologneblue.js', 'monobook.js', - 'myskin.js', - 'chick.js', - 'simple.js', 'modern.js', 'vector.js', 'group-autoconfirmed.js', @@ -2692,6 +2776,7 @@ $wgMessageStructure = array( 'spam_reverting', 'spam_blanking', 'spam_deleting', + 'simpleantispam-label', ), 'info' => array( 'pageinfo-header', @@ -2743,13 +2828,8 @@ $wgMessageStructure = array( 'pageinfo-category-files' ), 'skin' => array( - 'skinname-standard', - 'skinname-nostalgia', 'skinname-cologneblue', 'skinname-monobook', - 'skinname-myskin', - 'skinname-chick', - 'skinname-simple', 'skinname-modern', 'skinname-vector', ), @@ -2832,11 +2912,26 @@ $wgMessageStructure = array( 'minutes', 'hours', 'days', + 'weeks', 'months', 'years', 'ago', 'just-now', ), + 'human-timestamps' => array( + 'hours-ago', + 'minutes-ago', + 'seconds-ago', + 'monday-at', + 'tuesday-at', + 'wednesday-at', + 'thursday-at', + 'friday-at', + 'saturday-at', + 'sunday-at', + 'today-at', + 'yesterday-at', + ), 'badimagelist' => array( 'bad_image_list', ), @@ -3192,16 +3287,16 @@ $wgMessageStructure = array( 'exif-lightsource-255', ), 'exif-flash' => array( - 'exif-flash-fired-0' , - 'exif-flash-fired-1' , - 'exif-flash-return-0' , - 'exif-flash-return-2' , - 'exif-flash-return-3' , - 'exif-flash-mode-1' , - 'exif-flash-mode-2' , - 'exif-flash-mode-3' , - 'exif-flash-function-1' , - 'exif-flash-redeye-1' , + 'exif-flash-fired-0', + 'exif-flash-fired-1', + 'exif-flash-return-0', + 'exif-flash-return-2', + 'exif-flash-return-3', + 'exif-flash-mode-1', + 'exif-flash-mode-2', + 'exif-flash-mode-3', + 'exif-flash-function-1', + 'exif-flash-redeye-1', ), 'exif-focalplaneresolutionunit' => array( 'exif-focalplaneresolutionunit-2', @@ -3596,7 +3691,6 @@ $wgMessageStructure = array( 'version-other', 'version-mediahandlers', 'version-hooks', - 'version-extension-functions', 'version-parser-extensiontags', 'version-parser-function-hooks', 'version-hook-name', @@ -3606,6 +3700,7 @@ $wgMessageStructure = array( 'version-license', 'version-poweredby-credits', 'version-poweredby-others', + 'version-poweredby-translators', 'version-credits-summary', 'version-license-info', 'version-software', @@ -3620,11 +3715,18 @@ $wgMessageStructure = array( 'version-entrypoints-api-php', 'version-entrypoints-load-php', ), - 'filepath' => array( - 'filepath', - 'filepath-page', - 'filepath-submit', - 'filepath-summary', + 'redirect' => array( + 'redirect', + 'redirect-legend', + 'redirect-text', + 'redirect-summary', + 'redirect-submit', + 'redirect-lookup', + 'redirect-value', + 'redirect-user', + 'redirect-revision', + 'redirect-file', + 'redirect-not-exists', ), 'fileduplicatesearch' => array( 'fileduplicatesearch', @@ -3666,12 +3768,16 @@ $wgMessageStructure = array( 'tags-summary', 'tag-filter', 'tag-filter-submit', + 'tag-list-wrapper', 'tags-title', 'tags-intro', 'tags-tag', 'tags-display-header', 'tags-description-header', + 'tags-active-header', 'tags-hitcount-header', + 'tags-active-yes', + 'tags-active-no', 'tags-edit', 'tags-hitcount', ), @@ -3693,6 +3799,7 @@ $wgMessageStructure = array( 'dberr-problems', 'dberr-again', 'dberr-info', + 'dberr-info-hidden', 'dberr-usegoogle', 'dberr-outofdate', 'dberr-cachederror', @@ -3708,6 +3815,9 @@ $wgMessageStructure = array( 'htmlform-submit', 'htmlform-reset', 'htmlform-selectorother-other', + 'htmlform-no', + 'htmlform-yes', + 'htmlform-chosen-placeholder', ), 'sqlite' => array( 'sqlite-has-fts', @@ -3856,6 +3966,25 @@ $wgMessageStructure = array( 'rotation' => array( 'rotate-comment', ), + 'limitreport' => array( + 'limitreport-title', + 'limitreport-cputime', + 'limitreport-cputime-value', + 'limitreport-walltime', + 'limitreport-walltime-value', + 'limitreport-ppvisitednodes', + 'limitreport-ppvisitednodes-value', + 'limitreport-ppgeneratednodes', + 'limitreport-ppgeneratednodes-value', + 'limitreport-postexpandincludesize', + 'limitreport-postexpandincludesize-value', + 'limitreport-templateargumentsize', + 'limitreport-templateargumentsize-value', + 'limitreport-expansiondepth', + 'limitreport-expansiondepth-value', + 'limitreport-expensivefunctioncount', + 'limitreport-expensivefunctioncount-value', + ), ); /** Comments for each block */ @@ -3864,8 +3993,8 @@ $wgBlockComments = array( begin with * or ** are discarded, furthermore lines that do begin with ** and do not contain | are also discarded, but do not depend on this behavior for future releases. Also note that since each list value is wrapped in a unique -XHTML id it should only appear once and include characters that are legal -XHTML id names.", +(X)HTML id it should only appear once and include characters that are legal +(X)HTML id names.", 'toggles' => 'User preference toggles', 'underline' => '', 'editfont' => 'Font style option in Special:Preferences', @@ -3876,7 +4005,7 @@ XHTML id names.", 'cologneblue' => 'Cologne Blue skin', 'vector' => 'Vector skin', 'miscellaneous2' => '', - 'links' => 'All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).', + 'links' => 'All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).', 'badaccess' => '', 'versionrequired' => '', 'miscellaneous3' => '', @@ -3890,6 +4019,7 @@ XHTML id names.", 'resetpass' => 'Change password dialog', 'passwordreset' => 'Special:PasswordReset', 'changeemail' => 'Special:ChangeEmail', + 'resettokens' => 'Special:ResetTokens', 'toolbar' => 'Edit page toolbar', 'edit' => 'Edit pages', 'parserwarnings' => 'Parser/template warnings', @@ -3905,7 +4035,6 @@ XHTML id names.", 'diffs' => 'Diffs', 'search' => 'Search results', 'opensearch' => 'OpenSearch description', - 'quickbar' => 'Quickbar', 'preferences' => 'Preferences page', 'preferences-email' => 'User preference: email validation using jQuery', 'userrights' => 'User rights', @@ -3937,9 +4066,9 @@ XHTML id names.", 'listredirects' => 'List redirects', 'unusedtemplates' => 'Unused templates', 'randompage' => 'Random page', + 'randomincategory' => 'Random page in category', 'randomredirect' => 'Random redirect', 'statistics' => 'Statistics', - 'disambiguations' => '', 'pageswithprop' => '', 'doubleredirects' => '', 'brokenredirects' => '', @@ -3995,8 +4124,9 @@ XHTML id names.", 'patrol-log' => 'Patrol log', 'imagedeletion' => 'Image deletion', 'browsediffs' => 'Browsing diffs', - 'newfiles' => 'Special:NewFiles', + 'newfiles' => 'Special:NewFiles', 'video-info' => 'Video information, used by Language::formatTimePeriod() to format lengths in the above messages', + 'human-timestamps' => 'Human-readable timestamps', 'badimagelist' => 'Bad image list', 'variantname-zh' => "Short names for language variants used for language conversion links. Variants for Chinese language", @@ -4009,9 +4139,9 @@ Variants for Chinese language", 'variantname-shi' => 'Variants for Tachelhit language', 'media-info' => 'Media information', 'metadata' => 'Metadata', - 'exif' => 'EXIF tags', + 'exif' => 'Exif tags', 'exif-values' => 'Make & model, can be wikified in order to link to the camera and model name', - 'exif-compression' => 'EXIF attributes', + 'exif-compression' => 'Exif attributes', 'exif-copyrighted' => '', 'exif-unknowndate' => '', 'exif-photometricinterpretation' => '', @@ -4080,7 +4210,7 @@ Variants for Chinese language", 'signatures' => 'Signatures', 'CoreParserFunctions' => 'Core parser functions', 'version' => 'Special:Version', - 'filepath' => 'Special:FilePath', + 'redirect' => 'Special:Redirect', 'fileduplicatesearch' => 'Special:FileDuplicateSearch', 'special-specialpages' => 'Special:SpecialPages', 'special-blank' => 'Special:BlankPage', @@ -4098,4 +4228,5 @@ Variants for Chinese language", 'duration' => 'Durations', 'cachedspecial' => 'SpecialCachedPage', 'rotation' => 'Image rotation', + 'limitreport' => 'Limit report', ); diff --git a/maintenance/language/rebuildLanguage.php b/maintenance/language/rebuildLanguage.php index ad839054..66948aeb 100644 --- a/maintenance/language/rebuildLanguage.php +++ b/maintenance/language/rebuildLanguage.php @@ -22,9 +22,9 @@ * @defgroup MaintenanceLanguage MaintenanceLanguage */ -require_once( __DIR__ . '/../commandLine.inc' ); -require_once( 'languages.inc' ); -require_once( 'writeMessagesArray.inc' ); +require_once __DIR__ . '/../commandLine.inc'; +require_once 'languages.inc'; +require_once 'writeMessagesArray.inc'; /** * Rewrite a messages array. @@ -56,13 +56,13 @@ function rebuildLanguage( $languages, $code, $write, $listUnknown, $removeUnknow */ function removeDupes( $oldMsgArray, $dupeMsgSource ) { if ( file_exists( $dupeMsgSource ) ) { - include( $dupeMsgSource ); + include $dupeMsgSource; if ( !isset( $dupeMessages ) ) { - echo( "There are no duplicated messages in the source file provided." ); + echo "There are no duplicated messages in the source file provided."; exit( 1 ); } } else { - echo ( "The specified file $dupeMsgSource cannot be found." ); + echo "The specified file $dupeMsgSource cannot be found."; exit( 1 ); } $newMsgArray = $oldMsgArray; diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php index ba503224..61b84a07 100644 --- a/maintenance/language/transstat.php +++ b/maintenance/language/transstat.php @@ -28,9 +28,9 @@ */ $optionsWithArgs = array( 'output' ); -require_once( __DIR__ . '/../commandLine.inc' ); -require_once( 'languages.inc' ); -require_once( __DIR__ . '/StatOutputs.php' ); +require_once __DIR__ . '/../commandLine.inc'; +require_once 'languages.inc'; +require_once __DIR__ . '/StatOutputs.php'; if ( isset( $options['help'] ) ) { @@ -96,7 +96,7 @@ $wgRequiredMessagesNumber = count( $wgGeneralMessages['required'] ); foreach ( $wgLanguages->getLanguages() as $code ) { # Don't check English, RTL English or dummy language codes - if ( $code == 'en' || $code == 'enRTL' || (is_array( $wgDummyLanguageCodes ) && + if ( $code == 'en' || $code == 'enRTL' || ( is_array( $wgDummyLanguageCodes ) && isset( $wgDummyLanguageCodes[$code] ) ) ) { continue; } diff --git a/maintenance/language/validate.php b/maintenance/language/validate.php index 4f00496f..63d9b847 100644 --- a/maintenance/language/validate.php +++ b/maintenance/language/validate.php @@ -36,8 +36,8 @@ define( 'NOT_REALLY_MEDIAWIKI', 1 ); $IP = __DIR__ . '/../..'; -require_once( "$IP/includes/Defines.php" ); -require_once( "$IP/languages/Language.php" ); +require_once "$IP/includes/Defines.php"; +require_once "$IP/languages/Language.php"; $files = array(); foreach ( $argv as $arg ) { @@ -57,7 +57,7 @@ foreach ( $files as $filename ) { } function getVars( $filename ) { - require( $filename ); + require $filename; $vars = get_defined_vars(); unset( $vars['filename'] ); return $vars; diff --git a/maintenance/language/writeMessagesArray.inc b/maintenance/language/writeMessagesArray.inc index b2e04c7f..fc0da3f5 100644 --- a/maintenance/language/writeMessagesArray.inc +++ b/maintenance/language/writeMessagesArray.inc @@ -50,25 +50,27 @@ class MessageWriter { $sortedMessages = $messages[1]; # Write to the file - if ( $messagesFolder ) + if ( $messagesFolder ) { $filename = Language::getFileName( "$messagesFolder/Messages", $code ); - else + } else { $filename = Language::getMessagesFileName( $code ); + } - if ( file_exists( $filename ) ) + if ( file_exists( $filename ) ) { $contents = file_get_contents( $filename ); - else + } else { $contents = '<?php $messages = array( ); '; + } - if( strpos( $contents, '$messages' ) !== false ) { + if ( strpos( $contents, '$messages' ) !== false ) { $contents = explode( '$messages', $contents ); - if( $messagesText == '$messages' . $contents[1] ) { + if ( $messagesText == '$messages' . $contents[1] ) { echo "Generated messages for language $code. Same as the current file.\n"; } else { - if( $write ) { + if ( $write ) { $new = $contents[0]; $new .= $messagesText; file_put_contents( $filename, $new ); @@ -77,12 +79,13 @@ $messages = array( echo "Generated messages for language $code. Please run the script again (without the parameter \"dry-run\") to write the array to the file.\n"; } } - if( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) { - if ( $removeUnknown ) + if ( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) { + if ( $removeUnknown ) { echo "\nThe following " . count( $sortedMessages['unknown'] ) . " unknown messages have been removed:\n"; - else + } else { echo "\nThere are " . count( $sortedMessages['unknown'] ) . " unknown messages, please check them:\n"; - foreach( $sortedMessages['unknown'] as $key => $value ) { + } + foreach ( $sortedMessages['unknown'] as $key => $value ) { echo "* " . $key . "\n"; } } @@ -107,22 +110,22 @@ $messages = array( # Load messages $dir = $prefix ? $prefix : __DIR__; - require( $dir . '/messages.inc' ); + require $dir . '/messages.inc'; self::$messageStructure = $wgMessageStructure; self::$blockComments = $wgBlockComments; - require( $dir . '/messageTypes.inc' ); + require $dir . '/messageTypes.inc'; self::$ignoredMessages = $wgIgnoredMessages; self::$optionalMessages = $wgOptionalMessages; # Sort messages to blocks $sortedMessages['unknown'] = $messages; - foreach( self::$messageStructure as $blockName => $block ) { + foreach ( self::$messageStructure as $blockName => $block ) { /** * @var $block array */ - foreach( $block as $key ) { - if( array_key_exists( $key, $sortedMessages['unknown'] ) ) { + foreach ( $block as $key ) { + if ( array_key_exists( $key, $sortedMessages['unknown'] ) ) { $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key]; unset( $sortedMessages['unknown'][$key] ); } @@ -132,13 +135,13 @@ $messages = array( # Write all the messages $messagesText = "\$messages = array( "; - foreach( $sortedMessages as $block => $messages ) { + foreach ( $sortedMessages as $block => $messages ) { # Skip if it's the block of unknown messages - handle that in the end of file - if( $block == 'unknown' ) { + if ( $block == 'unknown' ) { continue; } - if( $ignoredComments ) { + if ( $ignoredComments ) { $ignored = self::$ignoredMessages; $optional = self::$optionalMessages; } else { @@ -175,10 +178,10 @@ $messages = array( $commentArray = array(); # List of keys only - foreach( $messages as $key ) { - if( in_array( $key, $ignored ) ) { + foreach ( $messages as $key ) { + if ( in_array( $key, $ignored ) ) { $commentArray[$key] = ' # ' . self::$ignoredComment; - } elseif( in_array( $key, $optional ) ) { + } elseif ( in_array( $key, $optional ) ) { $commentArray[$key] = ' # ' . self::$optionalComment; } } @@ -202,13 +205,13 @@ $messages = array( $blockText = ''; # Skip the block if it includes no messages - if( empty( $messages ) ) { + if ( empty( $messages ) ) { return ''; } # Format the block comment (if exists); check for multiple lines comments - if( !empty( $blockComment ) ) { - if( strpos( $blockComment, "\n" ) === false ) { + if ( !empty( $blockComment ) ) { + if ( strpos( $blockComment, "\n" ) === false ) { $blockText .= "$prefix# $blockComment "; } else { @@ -223,7 +226,7 @@ $blockComment $maxKeyLength = max( array_map( 'strlen', array_keys( $messages ) ) ); # Format the messages - foreach( $messages as $key => $value ) { + foreach ( $messages as $key => $value ) { # Add the key name $blockText .= "$prefix'$key'"; @@ -241,16 +244,16 @@ $blockComment $single = "'"; $double = '"'; - if( strpos( $value, $single ) === false ) { + if ( strpos( $value, $single ) === false ) { # Nothing ugly, just use ' - $blockText .= $single.$value.$single; - } elseif( strpos( $value, $double ) === false && !preg_match('/\$[a-zA-Z_\x7f-\xff]/', $value) ) { + $blockText .= $single . $value . $single; + } elseif ( strpos( $value, $double ) === false && !preg_match( '/\$[a-zA-Z_\x7f-\xff]/', $value ) ) { # No "-quotes, no variables that need quoting, use " - $blockText .= $double.$value.$double; + $blockText .= $double . $value . $double; } else { # Something needs quoting, pick the quote which causes less quoting $quote = substr_count( $value, $double ) + substr_count( $value, '$' ) >= substr_count( $value, $single ) ? $single : $double; - if( $quote === $double ) { + if ( $quote === $double ) { $extra = '$'; } else { $extra = ''; @@ -262,7 +265,7 @@ $blockComment $blockText .= ','; # Add comments, if there is any - if( array_key_exists( $key, $messageComments ) ) { + if ( array_key_exists( $key, $messageComments ) ) { $blockText .= $messageComments[$key]; } diff --git a/maintenance/mcc.php b/maintenance/mcc.php index 6ff8a176..7b7b7614 100644 --- a/maintenance/mcc.php +++ b/maintenance/mcc.php @@ -23,7 +23,7 @@ */ /** */ -require_once( __DIR__ . '/commandLine.inc' ); +require_once __DIR__ . '/commandLine.inc'; $options = getopt( '', array( 'debug', 'help', 'cache:' ) ); @@ -48,7 +48,7 @@ if ( $cache ) { $servers = $wgObjectCaches[$cache]['servers']; } elseif ( $wgMainCacheType === CACHE_MEMCACHED ) { $mcc->set_servers( $wgMemCachedServers ); -} elseif( isset( $wgObjectCaches[$wgMainCacheType]['servers'] ) ) { +} elseif ( isset( $wgObjectCaches[$wgMainCacheType]['servers'] ) ) { $mcc->set_servers( $wgObjectCaches[$wgMainCacheType]['servers'] ); } else { print "MediaWiki isn't configured for Memcached usage\n"; @@ -116,7 +116,9 @@ do { $quit = false; $line = Maintenance::readconsole(); - if ( $line === false ) exit; + if ( $line === false ) { + exit; + } $args = explode( ' ', $line ); $command = array_shift( $args ); diff --git a/maintenance/mctest.php b/maintenance/mctest.php index 469feca2..eda101e7 100644 --- a/maintenance/mctest.php +++ b/maintenance/mctest.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that makes several 'set', 'incr' and 'get' requests @@ -34,7 +34,7 @@ class mcTest extends Maintenance { public function __construct() { parent::__construct(); $this->mDescription = "Makes several 'set', 'incr' and 'get' requests on every" - . " memcached server and shows a report"; + . " memcached server and shows a report"; $this->addOption( 'i', 'Number of iterations', false, true ); $this->addOption( 'cache', 'Use servers from this $wgObjectCaches store', false, true ); $this->addArg( 'server[:port]', 'Memcached server to test, with optional port', false ); @@ -54,15 +54,22 @@ class mcTest extends Maintenance { $servers = array( $this->getArg() ); } elseif ( $wgMainCacheType === CACHE_MEMCACHED ) { global $wgMemCachedServers; - $servers = $wgMemCachedServers ; + $servers = $wgMemCachedServers; } elseif ( isset( $wgObjectCaches[$wgMainCacheType]['servers'] ) ) { $servers = $wgObjectCaches[$wgMainCacheType]['servers']; } else { $this->error( "MediaWiki isn't configured for Memcached usage", 1 ); } + # find out the longest server string to nicely align output later on + $maxSrvLen = $servers ? max( array_map( 'strlen', $servers ) ) : 0; + foreach ( $servers as $server ) { - $this->output( $server . " ", $server ); + $this->output( + str_pad( $server, $maxSrvLen ), + $server # output channel + ); + $mcc = new MemCachedClientforWiki( array( 'persistant' => true, 'timeout' => $wgMemCachedTimeout @@ -73,7 +80,7 @@ class mcTest extends Maintenance { $get = 0; $time_start = $this->microtime_float(); for ( $i = 1; $i <= $iterations; $i++ ) { - if ( !is_null( $mcc->set( "test$i", $i ) ) ) { + if ( $mcc->set( "test$i", $i ) ) { $set++; } } @@ -90,7 +97,7 @@ class mcTest extends Maintenance { } $exectime = $this->microtime_float() - $time_start; - $this->output( "set: $set incr: $incr get: $get time: $exectime", $server ); + $this->output( " set: $set incr: $incr get: $get time: $exectime", $server ); } } @@ -105,4 +112,4 @@ class mcTest extends Maintenance { } $maintClass = "mcTest"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/mergeMessageFileList.php b/maintenance/mergeMessageFileList.php index 62596b20..e9183377 100644 --- a/maintenance/mergeMessageFileList.php +++ b/maintenance/mergeMessageFileList.php @@ -25,7 +25,7 @@ # Start from scratch define( 'MW_NO_EXTENSION_MESSAGES', 1 ); -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; $maintClass = 'MergeMessageFileList'; $mmfl = false; @@ -36,10 +36,14 @@ $mmfl = false; * @ingroup Maintenance */ class MergeMessageFileList extends Maintenance { + /** + * @var bool + */ + protected $hasError; function __construct() { parent::__construct(); - $this->addOption( 'list-file', 'A file containing a list of extension setup files, one per line.', true, true ); + $this->addOption( 'list-file', 'A file containing a list of extension setup files, one per line.', false, true ); $this->addOption( 'extensions-dir', 'Path where extensions can be found.', false, true ); $this->addOption( 'output', 'Send output to this file (omit for stdout)', false, true ); $this->mDescription = 'Merge $wgExtensionMessagesFiles from various extensions to produce a ' . @@ -47,21 +51,29 @@ class MergeMessageFileList extends Maintenance { } public function execute() { - global $mmfl; + global $mmfl, $wgExtensionEntryPointListFiles; + + if ( !count( $wgExtensionEntryPointListFiles ) + && !$this->hasOption( 'list-file' ) + && !$this->hasOption( 'extensions-dir' ) + ) { + $this->error( "Either --list-file or --extensions-dir must be provided if " . + "\$wgExtensionEntryPointListFiles is not set", 1 ); + } + + $mmfl = array( 'setupFiles' => array() ); # Add setup files contained in file passed to --list-file - $lines = file( $this->getOption( 'list-file' ) ); - if ( $lines === false ) { - $this->error( 'Unable to open list file.' ); + if ( $this->hasOption( 'list-file' ) ) { + $extensionPaths = $this->readFile( $this->getOption( 'list-file' ) ); + $mmfl['setupFiles'] = array_merge( $mmfl['setupFiles'], $extensionPaths ); } - $mmfl = array( 'setupFiles' => array_map( 'trim', $lines ) ); # Now find out files in a directory - $hasError = false; if ( $this->hasOption( 'extensions-dir' ) ) { $extdir = $this->getOption( 'extensions-dir' ); $entries = scandir( $extdir ); - foreach( $entries as $extname ) { + foreach ( $entries as $extname ) { if ( $extname == '.' || $extname == '..' || !is_dir( "$extdir/$extname" ) ) { continue; } @@ -69,13 +81,19 @@ class MergeMessageFileList extends Maintenance { if ( file_exists( $extfile ) ) { $mmfl['setupFiles'][] = $extfile; } else { - $hasError = true; + $this->hasError = true; $this->error( "Extension {$extname} in {$extdir} lacks expected {$extname}.php" ); } } } - if ( $hasError ) { + # Add setup files defined via configuration + foreach ( $wgExtensionEntryPointListFiles as $points ) { + $extensionPaths = $this->readFile( $points ); + $mmfl['setupFiles'] = array_merge( $mmfl['setupFiles'], $extensionPaths ); + } + + if ( $this->hasError ) { $this->error( "Some files are missing (see above). Giving up.", 1 ); } @@ -86,19 +104,54 @@ class MergeMessageFileList extends Maintenance { $mmfl['quiet'] = true; } } + + /** + * @param string $fileName + * @return array List of absolute extension paths + */ + private function readFile( $fileName ) { + global $IP; + + $files = array(); + $fileLines = file( $fileName ); + if ( $fileLines === false ) { + $this->hasError = true; + $this->error( "Unable to open list file $fileName." ); + return $files; + } + # Strip comments, discard empty lines, and trim leading and trailing + # whitespace. Comments start with '#' and extend to the end of the line. + foreach ( $fileLines as $extension ) { + $extension = trim( preg_replace( '/#.*/', '', $extension ) ); + if ( $extension !== '' ) { + # Paths may use the string $IP to be substituted by the actual value + $extension = str_replace( '$IP', $IP, $extension ); + if ( file_exists( $extension ) ) { + $files[] = $extension; + } else { + $this->hasError = true; + $this->error( "Extension {$extension} doesn't exist" ); + } + } + } + return $files; + } } -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; foreach ( $mmfl['setupFiles'] as $fileName ) { if ( strval( $fileName ) === '' ) { continue; } - $fileName = str_replace( '$IP', $IP, $fileName ); if ( empty( $mmfl['quiet'] ) ) { fwrite( STDERR, "Loading data from $fileName\n" ); } - include_once( $fileName ); + // Include the extension to update $wgExtensionMessagesFiles + if ( !( include_once( $fileName ) ) ) { + fwrite( STDERR, "Unable to read $fileName\n" ); + exit( 1 ); + } } fwrite( STDERR, "\n" ); $s = @@ -114,10 +167,7 @@ $dirs = array( ); foreach ( $dirs as $dir ) { - $s = preg_replace( - "/'" . preg_quote( $dir, '/' ) . "([^']*)'/", - '"$IP\1"', - $s ); + $s = preg_replace( "/'" . preg_quote( $dir, '/' ) . "([^']*)'/", '"$IP\1"', $s ); } if ( isset( $mmfl['output'] ) ) { diff --git a/maintenance/migrateUserGroup.php b/maintenance/migrateUserGroup.php index f3e5957c..6903365b 100644 --- a/maintenance/migrateUserGroup.php +++ b/maintenance/migrateUserGroup.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that re-assigns users from an old group to a new one. @@ -106,4 +106,4 @@ class MigrateUserGroup extends Maintenance { } $maintClass = "MigrateUserGroup"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/minify.php b/maintenance/minify.php index 0846a64c..ec936c83 100644 --- a/maintenance/minify.php +++ b/maintenance/minify.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that minifies a file or set of files. @@ -144,4 +144,4 @@ class MinifyScript extends Maintenance { } $maintClass = 'MinifyScript'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/moveBatch.php b/maintenance/moveBatch.php index 7d15959c..34e64282 100644 --- a/maintenance/moveBatch.php +++ b/maintenance/moveBatch.php @@ -34,7 +34,7 @@ * e.g. immobile_namespace for namespaces which can't be moved */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to move a batch of pages. @@ -116,4 +116,4 @@ class MoveBatch extends Maintenance { } $maintClass = "MoveBatch"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/mssql/tables.sql b/maintenance/mssql/tables.sql index ad996175..7356c38f 100644 --- a/maintenance/mssql/tables.sql +++ b/maintenance/mssql/tables.sql @@ -159,6 +159,7 @@ CREATE TABLE /*$wgDBprefix*/text ( -- Cannot reasonably create views on this table, due to the presence of TEXT -- columns. CREATE TABLE /*$wgDBprefix*/archive ( + ar_id NOT NULL PRIMARY KEY clustered IDENTITY, ar_namespace SMALLINT NOT NULL DEFAULT 0, ar_title NVARCHAR(255) NOT NULL DEFAULT '', ar_text NVARCHAR(MAX) NOT NULL, @@ -298,6 +299,7 @@ CREATE INDEX /*$wgDBprefix*/lc_lang_key ON /*$wgDBprefix*/l10n_cache (lc_lang, l -- Track links to external URLs -- IE >= 4 supports no more than 2083 characters in a URL CREATE TABLE /*$wgDBprefix*/externallinks ( + el_id INT NOT NULL PRIMARY KEY clustered IDENTITY, el_from INT NOT NULL DEFAULT '0', el_to VARCHAR(2083) NOT NULL, el_index VARCHAR(896) NOT NULL, @@ -306,17 +308,6 @@ CREATE TABLE /*$wgDBprefix*/externallinks ( CREATE INDEX /*$wgDBprefix*/externallinks_index ON /*$wgDBprefix*/externallinks(el_index); -- --- Track external user accounts, if ExternalAuth is used --- -CREATE TABLE /*$wgDBprefix*/external_user ( - -- Foreign key to user_id - eu_local_id INT NOT NULL PRIMARY KEY, - -- opaque identifier provided by the external database - eu_external_id NVARCHAR(255) NOT NULL, -); -CREATE UNIQUE INDEX /*$wgDBprefix*/eu_external_idx ON /*$wgDBprefix*/external_user(eu_external_id); - --- -- Track INTerlanguage links -- CREATE TABLE /*$wgDBprefix*/langlinks ( @@ -516,8 +507,6 @@ CREATE TABLE /*$wgDBprefix*/recentchanges ( rc_this_oldid INT DEFAULT 0, rc_last_oldid INT DEFAULT 0, rc_type tinyint DEFAULT 0, - rc_moved_to_ns BIT DEFAULT 0, - rc_moved_to_title NVARCHAR(255) DEFAULT '', rc_patrolled BIT DEFAULT 0, rc_ip NCHAR(40) DEFAULT '', rc_old_len INT DEFAULT 0, diff --git a/maintenance/mwdoc-filter.php b/maintenance/mwdoc-filter.php index 6eeb48d3..c80981b5 100644 --- a/maintenance/mwdoc-filter.php +++ b/maintenance/mwdoc-filter.php @@ -18,6 +18,6 @@ if ( PHP_SAPI != 'cli' ) { $source = file_get_contents( $argv[1] ); $regexp = '#\@var\s+([^\s]+)([^/]+)/\s+(var|public|protected|private)\s+(\$[^\s;=]+)#'; $replac = '${2} */ ${3} ${1} ${4}'; -$source = preg_replace($regexp, $replac, $source); +$source = preg_replace( $regexp, $replac, $source ); echo $source; diff --git a/maintenance/mwdocgen.php b/maintenance/mwdocgen.php index 4fad7a7f..b22dd885 100644 --- a/maintenance/mwdocgen.php +++ b/maintenance/mwdocgen.php @@ -8,12 +8,6 @@ * Usage: * php mwdocgen.php * - * KNOWN BUGS: - * - * - pass_thru seems to always use buffering (even with ob_implicit_flush()), - * that make output slow when doxygen parses language files. - * - the menu doesnt work, got disabled at revision 13740. Need to code it. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -39,237 +33,135 @@ * @version first release */ -# -# Variables / Configuration -# - -if ( PHP_SAPI != 'cli' ) { - echo 'Run "' . __FILE__ . '" from the command line.'; - die( -1 ); -} - -/** Figure out the base directory for MediaWiki location */ -$mwPath = dirname( __DIR__ ) . DIRECTORY_SEPARATOR; - -/** doxygen binary script */ -$doxygenBin = 'doxygen'; - -/** doxygen configuration template for mediawiki */ -$doxygenTemplate = $mwPath . 'maintenance/Doxyfile'; - -/** doxygen input filter to tweak source file before they are parsed */ -$doxygenInputFilter = "php {$mwPath}maintenance/mwdoc-filter.php"; - -/** where Phpdoc should output documentation */ -$doxyOutput = $mwPath . 'docs' . DIRECTORY_SEPARATOR ; - -$doxyVersion = 'master'; - -/** MediaWiki subpaths */ -$mwPathI = $mwPath . 'includes/'; -$mwPathL = $mwPath . 'languages/'; -$mwPathM = $mwPath . 'maintenance/'; -$mwPathS = $mwPath . 'skins/'; - -/** Ignored paths relative to $mwPath */ -$mwExcludePaths = array( - 'images', - 'static', -); - -/** Variable to get user input */ -$input = ''; -$excludePatterns = ''; -/** Whether to generates man pages: */ -$doxyGenerateMan = false; - -# -# Functions -# - -define( 'MEDIAWIKI', true ); -require_once( "$mwPath/includes/GlobalFunctions.php" ); - -/** - * Read a line from the shell - * @param $prompt String - * @return string - */ -function readaline( $prompt = '' ) { - print $prompt; - $fp = fopen( "php://stdin", "r" ); - $resp = trim( fgets( $fp, 1024 ) ); - fclose( $fp ); - return $resp; -} +require_once __DIR__ . '/Maintenance.php'; /** - * Generate a configuration file given user parameters and return the temporary filename. - * @param $doxygenTemplate String: full path for the template. - * @param $outputDirectory String: directory where the stuff will be output. - * @param $stripFromPath String: path that should be stripped out (usually mediawiki base path). - * @param $currentVersion String: Version number of the software - * @param $input String: Path to analyze. - * @param $exclude String: Additionals path regex to exclude - * @param $excludePatterns String: Additionals path regex to exclude - * (LocalSettings.php, AdminSettings.php, .svn and .git directories are always excluded) - * @param $doxyGenerateMan Boolean - * @return string + * Maintenance script that builds doxygen documentation. + * @ingroup Maintenance */ -function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath, $currentVersion, $input, $exclude, $excludePatterns, $doxyGenerateMan, $doxygenInputFilter ) { - - $template = file_get_contents( $doxygenTemplate ); - // Replace template placeholders by correct values. - $replacements = array( - '{{OUTPUT_DIRECTORY}}' => $outputDirectory, - '{{STRIP_FROM_PATH}}' => $stripFromPath, - '{{CURRENT_VERSION}}' => $currentVersion, - '{{INPUT}}' => $input, - '{{EXCLUDE}}' => $exclude, - '{{EXCLUDE_PATTERNS}}' => $excludePatterns, - '{{HAVE_DOT}}' => `which dot` ? 'YES' : 'NO', - '{{GENERATE_MAN}}' => $doxyGenerateMan ? 'YES' : 'NO', - '{{INPUT_FILTER}}' => $doxygenInputFilter, - ); - $tmpCfg = str_replace( array_keys( $replacements ), array_values( $replacements ), $template ); - $tmpFileName = tempnam( wfTempDir(), 'mwdocgen-' ); - file_put_contents( $tmpFileName, $tmpCfg ) or die( "Could not write doxygen configuration to file $tmpFileName\n" ); +class MWDocGen extends Maintenance { + + /** + * Prepare Maintenance class + */ + public function __construct() { + parent::__construct(); + $this->mDescription = 'Build doxygen documentation'; + + $this->addOption( 'doxygen', + 'Path to doxygen', + false, true ); + $this->addOption( 'version', + 'Pass a MediaWiki version', + false, true ); + $this->addOption( 'generate-man', + 'Whether to generate man files' ); + $this->addOption( 'file', + "Only process given file or directory. Multiple values " . + "accepted with comma separation. Path relative to \$IP.", + false, true ); + $this->addOption( 'output', + 'Path to write doc to', + false, true ); + $this->addOption( 'no-extensions', + 'Ignore extensions' ); + } - return $tmpFileName; -} + public function getDbType() { + return Maintenance::DB_NONE; + } -# -# Main ! -# + protected function init() { + global $IP; -unset( $file ); + $this->doxygen = $this->getOption( 'doxygen', 'doxygen' ); + $this->mwVersion = $this->getOption( 'version', 'master' ); -if ( is_array( $argv ) ) { - for ($i = 0; $i < count($argv); $i++ ) { - switch( $argv[$i] ) { - case '--all': $input = 0; break; - case '--includes': $input = 1; break; - case '--languages': $input = 2; break; - case '--maintenance': $input = 3; break; - case '--skins': $input = 4; break; - case '--file': - $input = 5; - $i++; - if ( isset( $argv[$i] ) ) { - $file = $argv[$i]; - } - break; - case '--no-extensions': $input = 6; break; - case '--output': - $i++; - if ( isset( $argv[$i] ) ) { - $doxyOutput = realpath( $argv[$i] ); - } - break; - case '--version': - $i++; - if ( isset( $argv[$i] ) ) { - $doxyVersion = $argv[$i]; - } - break; - case '--generate-man': - $doxyGenerateMan = true; - break; - case '--help': - print <<<END -Usage: php mwdocgen.php [<command>] [<options>] + $this->input = ''; + $inputs = explode( ',', $this->getOption( 'file', '' ) ); + foreach ( $inputs as $input ) { + # Doxygen inputs are space separted and double quoted + $this->input .= " \"$IP/$input\""; + } -Commands: - --all Process entire codebase - --includes Process only files in includes/ dir - --languages Process only files in languages/ dir - --maintenance Process only files in maintenance/ dir - --skins Process only files in skins/ dir - --file <file> Process only the given file - --no-extensions Process everything but extensions directorys + $this->output = $this->getOption( 'output', "$IP/docs" ); + + $this->inputFilter = wfShellWikiCmd( + $IP . '/maintenance/mwdoc-filter.php' ); + $this->template = $IP . '/maintenance/Doxyfile'; + $this->excludes = array( + 'vendor', + 'images', + 'static', + ); + $this->excludePatterns = array(); + if ( $this->hasOption( 'no-extensions' ) ) { + $this->excludePatterns[] = 'extensions'; + } -If no command is given, you will be prompted. + $this->doDot = `which dot`; + $this->doMan = $this->hasOption( 'generate-man' ); + } -Other options: - --output <dir> Set output directory (default: $doxyOutput) - --generate-man Generates man page documentation - --version Project version to display in the outut (default: $doxyVersion) - --help Show this help and exit. + public function execute() { + global $IP; + $this->init(); -END; - exit(0); - break; + # Build out directories we want to exclude + $exclude = ''; + foreach ( $this->excludes as $item ) { + $exclude .= " $IP/$item"; } - } -} -// TODO : generate a list of paths )) - -if ( $input === '' ) { - echo <<<OPTIONS -Several documentation possibilities: - 0 : whole documentation (1 + 2 + 3 + 4) - 1 : only includes - 2 : only languages - 3 : only maintenance - 4 : only skins - 5 : only a given file - 6 : all but the extensions directory -OPTIONS; - while ( !is_numeric( $input ) ) - { - $input = readaline( "\nEnter your choice [0]:" ); - if ( $input == '' ) { - $input = 0; + $excludePatterns = implode( ' ', $this->excludePatterns ); + + $conf = strtr( file_get_contents( $this->template ), + array( + '{{OUTPUT_DIRECTORY}}' => $this->output, + '{{STRIP_FROM_PATH}}' => $IP, + '{{CURRENT_VERSION}}' => $this->mwVersion, + '{{INPUT}}' => $this->input, + '{{EXCLUDE}}' => $exclude, + '{{EXCLUDE_PATTERNS}}' => $excludePatterns, + '{{HAVE_DOT}}' => $this->doDot ? 'YES' : 'NO', + '{{GENERATE_MAN}}' => $this->doMan ? 'YES' : 'NO', + '{{INPUT_FILTER}}' => $this->inputFilter, + ) + ); + + $tmpFile = tempnam( wfTempDir(), 'MWDocGen-' ); + if ( file_put_contents( $tmpFile, $conf ) === false ) { + $this->error( "Could not write doxygen configuration to file $tmpFile\n", + /** exit code: */ 1 ); } - } -} - -switch ( $input ) { -case 0: $input = $mwPath; break; -case 1: $input = $mwPathI; break; -case 2: $input = $mwPathL; break; -case 3: $input = $mwPathM; break; -case 4: $input = $mwPathS; break; -case 5: - if ( !isset( $file ) ) { - $file = readaline( "Enter file name $mwPath" ); - } - $input = $mwPath . $file; - break; -case 6: - $input = $mwPath; - $excludePatterns = 'extensions'; -} -// Generate path exclusions -$excludedPaths = $mwPath . join( " $mwPath", $mwExcludePaths ); -print "EXCLUDE: $excludedPaths\n\n"; + $command = $this->doxygen . ' ' . $tmpFile; + $this->output( "Executing command:\n$command\n" ); -$generatedConf = generateConfigFile( $doxygenTemplate, $doxyOutput, $mwPath, $doxyVersion, $input, $excludedPaths, $excludePatterns, $doxyGenerateMan, $doxygenInputFilter ); -$command = $doxygenBin . ' ' . $generatedConf; + $exitcode = 1; + system( $command, $exitcode ); -echo <<<TEXT + $this->output( <<<TEXT --------------------------------------------------- -Launching the command: - -$command +Doxygen execution finished. +Check above for possible errors. +You might want to delete the temporary file: + $tmpFile --------------------------------------------------- -TEXT; - -$exitcode = 1; -passthru( $command, $exitcode ); +TEXT + ); -echo <<<TEXT ---------------------------------------------------- -Doxygen execution finished. -Check above for possible errors. + if ( $exitcode !== 0 ) { + $this->error( "Something went wrong (exit: $exitcode)\n", + $exitcode ); + } -You might want to delete the temporary file $generatedConf + } -TEXT; +} -exit( $exitcode ); +$maintClass = 'MWDocGen'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/mwjsduck-gen b/maintenance/mwjsduck-gen index fbd428f1..bc10bc2c 100644 --- a/maintenance/mwjsduck-gen +++ b/maintenance/mwjsduck-gen @@ -1,2 +1,21 @@ -#!/usr/bin/env sh -jsduck --config=$(cd $(dirname $0)/..; pwd)/maintenance/jsduck/config.json && echo 'JSDuck execution finished.' +#!/usr/bin/env bash + +JSDUCK_MWVERSION=master +if [[ "$1" == "--version" && "$2" != "" ]] +then + JSDUCK_MWVERSION="$2" +elif [[ "$*" != "" ]] +then + echo "Usage $0: [--version <mediawiki version>]" + echo + exit 1 +fi + +MWCORE_DIR=$(cd $(dirname $0)/..; pwd) + +jsduck \ +--config=$MWCORE_DIR/maintenance/jsduck/config.json \ +--footer="Documentation for MediaWiki core ($JSDUCK_MWVERSION). Generated on {DATE} by {JSDUCK} {VERSION}." \ +&& echo 'JSDuck execution finished.' + +ln -s ../../resources $MWCORE_DIR/docs/js/modules diff --git a/maintenance/namespaceDupes.php b/maintenance/namespaceDupes.php index 6067a826..ff024682 100644 --- a/maintenance/namespaceDupes.php +++ b/maintenance/namespaceDupes.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that checks for articles to fix after @@ -185,7 +185,7 @@ class NamespaceConflictChecker extends Maintenance { } /** - * @todo: do this for reals + * @todo Do this for real * @param $key * @param $prefix * @param $fix @@ -207,10 +207,10 @@ class NamespaceConflictChecker extends Maintenance { * @return array */ private function getConflicts( $ns, $name ) { - $page = 'page'; + $page = 'page'; $table = $this->db->tableName( $page ); - $prefix = $this->db->strencode( $name ); + $prefix = $this->db->strencode( $name ); $encNamespace = $this->db->addQuotes( $ns ); $titleSql = "TRIM(LEADING '$prefix:' FROM {$page}_title)"; @@ -318,12 +318,12 @@ class NamespaceConflictChecker extends Maintenance { $this->db->update( $table, array( "{$prefix}_namespace" => $newTitle->getNamespace(), - "{$prefix}_title" => $newTitle->getDBkey(), + "{$prefix}_title" => $newTitle->getDBkey(), ), array( // "{$prefix}_namespace" => 0, - // "{$prefix}_title" => $row->oldtitle, - "{$prefix}_id" => $row->id, + // "{$prefix}_title" => $row->oldtitle, + "{$prefix}_id" => $row->id, ), __METHOD__ ); $this->output( "ok.\n" ); @@ -332,4 +332,4 @@ class NamespaceConflictChecker extends Maintenance { } $maintClass = "NamespaceConflictChecker"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/nextJobDB.php b/maintenance/nextJobDB.php index 1be5146e..219b5d8e 100644 --- a/maintenance/nextJobDB.php +++ b/maintenance/nextJobDB.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that picks a database that has pending jobs. @@ -116,4 +116,4 @@ class nextJobDB extends Maintenance { } $maintClass = "nextJobDb"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/nukeNS.php b/maintenance/nukeNS.php index c471a441..479dcf76 100644 --- a/maintenance/nukeNS.php +++ b/maintenance/nukeNS.php @@ -33,7 +33,7 @@ * based on nukePage by Rob Church */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that removes pages with only one revision from the @@ -66,7 +66,7 @@ class NukeNS extends Maintenance { foreach ( $res as $row ) { // echo "$ns_name:".$row->page_title, "\n"; $title = Title::makeTitle( $ns, $row->page_title ); - $id = $title->getArticleID(); + $id = $title->getArticleID(); // Get corresponding revisions $res2 = $dbw->query( "SELECT rev_id FROM $tbl_rev WHERE rev_page = $id" ); @@ -94,7 +94,7 @@ class NukeNS extends Maintenance { $n_deleted ++; } } else { - $this->output( "skip: " . $title->getPrefixedText() . "\n" ); + $this->output( "skip: " . $title->getPrefixedText() . "\n" ); } } $dbw->commit( __METHOD__ ); @@ -119,4 +119,4 @@ class NukeNS extends Maintenance { } $maintClass = "NukeNS"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/nukePage.php b/maintenance/nukePage.php index 89dffe0c..1870273e 100644 --- a/maintenance/nukePage.php +++ b/maintenance/nukePage.php @@ -23,7 +23,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that erases a page record from the database. @@ -54,7 +54,7 @@ class NukePage extends Maintenance { $this->output( "Searching for \"$name\"..." ); $title = Title::newFromText( $name ); if ( $title ) { - $id = $title->getArticleID(); + $id = $title->getArticleID(); $real = $title->getPrefixedText(); $isGoodArticle = $title->isContentPage(); $this->output( "found \"$real\" with ID $id.\n" ); @@ -117,4 +117,4 @@ class NukePage extends Maintenance { } $maintClass = "NukePage"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/oracle/alterSharedConstraints.php b/maintenance/oracle/alterSharedConstraints.php index a46c5e1f..435625d5 100644 --- a/maintenance/oracle/alterSharedConstraints.php +++ b/maintenance/oracle/alterSharedConstraints.php @@ -27,7 +27,7 @@ * i.e.: GRANT REFERENCES (user_id) ON mwuser TO hubclient; */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; class AlterSharedConstraints extends Maintenance { public function __construct() { @@ -49,11 +49,11 @@ class AlterSharedConstraints extends Maintenance { $dbw = wfGetDB( DB_MASTER ); foreach ( $wgSharedTables as $table ) { - $stable = $dbw->tableNameInternal($table); + $stable = $dbw->tableNameInternal( $table ); if ( $wgSharedPrefix != null ) { $ltable = preg_replace( "/^$wgSharedPrefix(.*)/i", "$wgDBprefix\\1", $stable ); } else { - $ltable = "{$wgDBprefix}{$stable}" ; + $ltable = "{$wgDBprefix}{$stable}"; } $result = $dbw->query( "SELECT uc.constraint_name, uc.table_name, ucc.column_name, uccpk.table_name pk_table_name, uccpk.column_name pk_column_name, uc.delete_rule, uc.deferrable, uc.deferred @@ -62,14 +62,14 @@ class AlterSharedConstraints extends Maintenance { AND ucc.constraint_name = uc.constraint_name AND uccpk.constraint_name = uc.r_constraint_name AND uccpk.table_name = '$ltable'" ); - while (($row = $result->fetchRow()) !== false) { + while ( ( $row = $result->fetchRow() ) !== false ) { - $this->output( "Altering {$row['constraint_name']} ..."); + $this->output( "Altering {$row['constraint_name']} ..." ); try { $dbw->query( "ALTER TABLE {$row['table_name']} DROP CONSTRAINT {$wgDBprefix}{$row['constraint_name']}" ); - } catch (DBQueryError $exdb) { - if ($exdb->errno != 2443) { + } catch ( DBQueryError $exdb ) { + if ( $exdb->errno != 2443 ) { throw $exdb; } } @@ -88,4 +88,4 @@ class AlterSharedConstraints extends Maintenance { } $maintClass = "AlterSharedConstraints"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/oracle/archives/patch-archive-ar_id.sql b/maintenance/oracle/archives/patch-archive-ar_id.sql new file mode 100644 index 00000000..a43f7602 --- /dev/null +++ b/maintenance/oracle/archives/patch-archive-ar_id.sql @@ -0,0 +1,6 @@ +define mw_prefix='{$wgDBprefix}'; + +ALTER TABLE &mw_prefix.archive ADD ( +ar_id NUMBER NOT NULL, +); +ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id); diff --git a/maintenance/oracle/archives/patch-externallinks-el_id.sql b/maintenance/oracle/archives/patch-externallinks-el_id.sql new file mode 100644 index 00000000..a8c443f4 --- /dev/null +++ b/maintenance/oracle/archives/patch-externallinks-el_id.sql @@ -0,0 +1,4 @@ +define mw_prefix='{$wgDBprefix}'; + +ALTER TABLE &mw_prefix.externallinks ADD el_id NUMBER NOT NULL; +ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_pk PRIMARY KEY (el_id);
\ No newline at end of file diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql index ba69da1b..acfabc33 100644 --- a/maintenance/oracle/tables.sql +++ b/maintenance/oracle/tables.sql @@ -129,7 +129,9 @@ CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text' ); ALTER TABLE &mw_prefix.pagecontent ADD CONSTRAINT &mw_prefix.pagecontent_pk PRIMARY KEY (old_id); +CREATE SEQUENCE archive_ar_id_seq; CREATE TABLE &mw_prefix.archive ( + ar_id NUMBER NOT NULL, ar_namespace NUMBER DEFAULT 0 NOT NULL, ar_title VARCHAR2(255) NOT NULL, ar_text CLOB, @@ -149,6 +151,7 @@ CREATE TABLE &mw_prefix.archive ( ar_content_model VARCHAR2(32), ar_content_format VARCHAR2(64) ); +ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id); ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY (ar_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp); CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp); @@ -208,23 +211,19 @@ ALTER TABLE &mw_prefix.category ADD CONSTRAINT &mw_prefix.category_pk PRIMARY KE CREATE UNIQUE INDEX &mw_prefix.category_u01 ON &mw_prefix.category (cat_title); CREATE INDEX &mw_prefix.category_i01 ON &mw_prefix.category (cat_pages); +CREATE SEQUENCE externallinks_el_id_seq; CREATE TABLE &mw_prefix.externallinks ( + el_id NUMBER NOT NULL, el_from NUMBER NOT NULL, el_to VARCHAR2(2048) NOT NULL, el_index VARCHAR2(2048) NOT NULL ); +ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_pk PRIMARY KEY (el_id); ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_fk1 FOREIGN KEY (el_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; CREATE INDEX &mw_prefix.externallinks_i01 ON &mw_prefix.externallinks (el_from, el_to); CREATE INDEX &mw_prefix.externallinks_i02 ON &mw_prefix.externallinks (el_to, el_from); CREATE INDEX &mw_prefix.externallinks_i03 ON &mw_prefix.externallinks (el_index); -CREATE TABLE &mw_prefix.external_user ( - eu_local_id NUMBER NOT NULL, - eu_external_id varchar2(255) NOT NULL -); -ALTER TABLE &mw_prefix.external_user ADD CONSTRAINT &mw_prefix.external_user_pk PRIMARY KEY (eu_local_id); -CREATE UNIQUE INDEX &mw_prefix.external_user_u01 ON &mw_prefix.external_user (eu_external_id); - CREATE TABLE &mw_prefix.langlinks ( ll_from NUMBER NOT NULL, ll_lang VARCHAR2(20), @@ -416,8 +415,6 @@ CREATE TABLE &mw_prefix.recentchanges ( rc_this_oldid NUMBER DEFAULT 0 NOT NULL, rc_last_oldid NUMBER DEFAULT 0 NOT NULL, rc_type CHAR(1) DEFAULT '0' NOT NULL, - rc_moved_to_ns NUMBER DEFAULT 0 NOT NULL, - rc_moved_to_title VARCHAR2(255), rc_patrolled CHAR(1) DEFAULT '0' NOT NULL, rc_ip VARCHAR2(15), rc_old_len NUMBER, @@ -643,10 +640,11 @@ ALTER TABLE &mw_prefix.valid_tag ADD CONSTRAINT &mw_prefix.valid_tag_pk PRIMARY -- This table is not used unless profiling is turned on --CREATE TABLE &mw_prefix.profiling ( --- pf_count NUMBER DEFAULT 0 NOT NULL, --- pf_time NUMERIC(18,10) DEFAULT 0 NOT NULL, --- pf_name CLOB NOT NULL, --- pf_server CLOB NULL +-- pf_count NUMBER DEFAULT 0 NOT NULL, +-- pf_time NUMBER(18,10) DEFAULT 0 NOT NULL, +-- pf_memory NUMBER(18,10) DEFAULT 0 NOT NULL, +-- pf_name VARCHAR2(255), +-- pf_server VARCHAR2(30) --); --CREATE UNIQUE INDEX &mw_prefix.profiling_u01 ON &mw_prefix.profiling (pf_name, pf_server); diff --git a/maintenance/orphans.php b/maintenance/orphans.php index 3b1a9b0e..b4d255ab 100644 --- a/maintenance/orphans.php +++ b/maintenance/orphans.php @@ -28,7 +28,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that looks for 'orphan' revisions hooked to pages which @@ -171,7 +171,7 @@ class Orphans extends Maintenance { */ private function checkSeparation( $fix ) { $dbw = wfGetDB( DB_MASTER ); - $page = $dbw->tableName( 'page' ); + $page = $dbw->tableName( 'page' ); $revision = $dbw->tableName( 'revision' ); if ( $fix ) { @@ -209,7 +209,7 @@ class Orphans extends Maintenance { 'revision', 'rev_id', array( - 'rev_page' => $row->page_id, + 'rev_page' => $row->page_id, 'rev_timestamp' => $row2->max_timestamp ) ); $this->output( "... updating to revision $maxId\n" ); $maxRev = Revision::newFromId( $maxId ); @@ -239,4 +239,4 @@ class Orphans extends Maintenance { } $maintClass = "Orphans"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/parse.php b/maintenance/parse.php index 58e76b0a..3ac7a281 100644 --- a/maintenance/parse.php +++ b/maintenance/parse.php @@ -49,7 +49,7 @@ * @license GNU General Public License 2.0 or later */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to parse some wikitext. @@ -85,12 +85,12 @@ class CLIParser extends Maintenance { */ protected function Wikitext() { - $php_stdin = 'php://stdin'; + $php_stdin = 'php://stdin'; $input_file = $this->getArg( 0, $php_stdin ); - if( $input_file === $php_stdin ) { + if ( $input_file === $php_stdin ) { $ctrl = wfIsWindows() ? 'CTRL+Z' : 'CTRL+D'; - $this->error( basename(__FILE__) .": warning: reading wikitext from STDIN. Press $ctrl to parse.\n" ); + $this->error( basename( __FILE__ ) . ": warning: reading wikitext from STDIN. Press $ctrl to parse.\n" ); } return file_get_contents( $input_file ); @@ -113,7 +113,7 @@ class CLIParser extends Maintenance { $title = $this->getOption( 'title' ) ? $this->getOption( 'title' ) - : 'CLIParser' ; + : 'CLIParser'; return Title::newFromText( $title ); } @@ -131,4 +131,4 @@ class CLIParser extends Maintenance { } $maintClass = "CLIParser"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/patchSql.php b/maintenance/patchSql.php index 1f393556..31ce1566 100644 --- a/maintenance/patchSql.php +++ b/maintenance/patchSql.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that manually runs an SQL patch outside of the general updaters. @@ -62,4 +62,4 @@ class PatchSql extends Maintenance { } $maintClass = "PatchSql"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateCategory.php b/maintenance/populateCategory.php index ae54d698..4c8cdaa1 100644 --- a/maintenance/populateCategory.php +++ b/maintenance/populateCategory.php @@ -22,7 +22,7 @@ * @author Simetrical */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Mainteance script to populate the category table. @@ -142,4 +142,4 @@ TEXT; } $maintClass = "PopulateCategory"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateFilearchiveSha1.php b/maintenance/populateFilearchiveSha1.php index 27e692d1..c579d4fc 100644 --- a/maintenance/populateFilearchiveSha1.php +++ b/maintenance/populateFilearchiveSha1.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( dirname( __FILE__ ) . '/Maintenance.php' ); +require_once dirname( __FILE__ ) . '/Maintenance.php'; /** * Maintenance script to populate the fa_sha1 field. @@ -86,7 +86,7 @@ class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance { } $done += $i; - if( $i !== $batchSize ) { + if ( $i !== $batchSize ) { break; } @@ -94,7 +94,7 @@ class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance { $this->output( sprintf( "id %d done (up to %d), %5.3f%% \r", $lastId, $endId, $lastId / $endId * 100 ) ); wfWaitForSlaves(); - } while( true ); + } while ( true ); $processingTime = microtime( true ) - $startTime; $this->output( sprintf( "\nDone %d files in %.1f seconds\n", $done, $processingTime ) ); @@ -104,4 +104,4 @@ class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance { } $maintClass = "PopulateFilearchiveSha1"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateImageSha1.php b/maintenance/populateImageSha1.php index 37429a34..126d22d9 100644 --- a/maintenance/populateImageSha1.php +++ b/maintenance/populateImageSha1.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to populate the img_sha1 field. @@ -164,4 +164,4 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance { } $maintClass = "PopulateImageSha1"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateLogSearch.php b/maintenance/populateLogSearch.php index 99d81557..d65635e5 100644 --- a/maintenance/populateLogSearch.php +++ b/maintenance/populateLogSearch.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that makes the required database updates for populating the @@ -75,7 +75,9 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { if ( LogEventsList::typeAction( $row, $delTypes, 'revision' ) ) { $params = LogPage::extractParams( $row->log_params ); // Param format: <urlparam> <item CSV> [<ofield> <nfield>] - if ( count( $params ) < 2 ) continue; // bad row? + if ( count( $params ) < 2 ) { + continue; // bad row? + } $field = RevisionDeleter::getRelationType( $params[0] ); // B/C, the params may start with a title key (<title> <urlparam> <CSV>) if ( $field == null ) { @@ -97,8 +99,9 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { $log->addRelations( $field, $items, $row->log_id ); // Determine what table to query... $prefix = substr( $field, 0, strpos( $field, '_' ) ); // db prefix - if ( !isset( self::$tableMap[$prefix] ) ) + if ( !isset( self::$tableMap[$prefix] ) ) { continue; // bad row? + } $table = self::$tableMap[$prefix]; $userField = $prefix . '_user'; $userTextField = $prefix . '_user_text'; @@ -109,10 +112,11 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { array( $field => $items ) ); foreach ( $sres as $srow ) { - if ( $srow->$userField > 0 ) + if ( $srow->$userField > 0 ) { $userIds[] = intval( $srow->$userField ); - elseif ( $srow->$userTextField != '' ) + } elseif ( $srow->$userTextField != '' ) { $userIPs[] = $srow->$userTextField; + } } // Add item author relations... $log->addRelations( 'target_author_id', $userIds, $row->log_id ); @@ -121,7 +125,9 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { } elseif ( LogEventsList::typeAction( $row, $delTypes, 'event' ) ) { $params = LogPage::extractParams( $row->log_params ); // Param format: <item CSV> [<ofield> <nfield>] - if ( count( $params ) < 1 ) continue; // bad row + if ( count( $params ) < 1 ) { + continue; // bad row + } $items = explode( ',', $params[0] ); $log = new LogPage( $row->log_type ); // Add item relations... @@ -133,10 +139,11 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { array( 'log_id' => $items ) ); foreach ( $sres as $srow ) { - if ( $srow->log_user > 0 ) + if ( $srow->log_user > 0 ) { $userIds[] = intval( $srow->log_user ); - elseif ( IP::isIPAddress( $srow->log_user_text ) ) + } elseif ( IP::isIPAddress( $srow->log_user_text ) ) { $userIPs[] = $srow->log_user_text; + } } $log->addRelations( 'target_author_id', $userIds, $row->log_id ); $log->addRelations( 'target_author_ip', $userIPs, $row->log_id ); @@ -152,4 +159,4 @@ class PopulateLogSearch extends LoggedUpdateMaintenance { } $maintClass = "PopulateLogSearch"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateLogUsertext.php b/maintenance/populateLogUsertext.php index fa9d512f..e579e522 100644 --- a/maintenance/populateLogUsertext.php +++ b/maintenance/populateLogUsertext.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that makes the required database updates for @@ -82,4 +82,4 @@ class PopulateLogUsertext extends LoggedUpdateMaintenance { } $maintClass = "PopulateLogUsertext"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateParentId.php b/maintenance/populateParentId.php index e81d4ffb..e29fa5f1 100644 --- a/maintenance/populateParentId.php +++ b/maintenance/populateParentId.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that makes the required database updates for rev_parent_id @@ -98,8 +98,9 @@ class PopulateParentId extends LoggedUpdateMaintenance { } } $previousID = intval( $previousID ); - if ( $previousID != $row->rev_parent_id ) + if ( $previousID != $row->rev_parent_id ) { $changed++; + } # Update the row... $db->update( 'revision', array( 'rev_parent_id' => $previousID ), @@ -117,4 +118,4 @@ class PopulateParentId extends LoggedUpdateMaintenance { } $maintClass = "PopulateParentId"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateRevisionLength.php b/maintenance/populateRevisionLength.php index 7c529d53..3c69125a 100644 --- a/maintenance/populateRevisionLength.php +++ b/maintenance/populateRevisionLength.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that populates the rev_len field for old revisions @@ -48,8 +48,8 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance { $db = $this->getDB( DB_MASTER ); if ( !$db->tableExists( 'revision' ) ) { $this->error( "revision table does not exist", true ); - } else if ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) { - $this->output( "rev_sha1 column does not exist\n\n", true ); + } elseif ( !$db->fieldExists( 'revision', 'rev_len', __METHOD__ ) ) { + $this->output( "rev_len column does not exist\n\n", true ); return false; } @@ -70,12 +70,16 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance { $fields = Revision::selectFields(); while ( $blockStart <= $end ) { $this->output( "...doing rev_id from $blockStart to $blockEnd\n" ); - $res = $db->select( 'revision', - $fields, - array( "rev_id >= $blockStart", - "rev_id <= $blockEnd", - "rev_len IS NULL" ), - __METHOD__ ); + $res = $db->select( + 'revision', + $fields, + array( + "rev_id >= $blockStart", + "rev_id <= $blockEnd", + "rev_len IS NULL" + ), + __METHOD__ + ); # Go through and update rev_len from these rows. foreach ( $res as $row ) { $rev = new Revision( $row ); @@ -105,4 +109,4 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance { } $maintClass = "PopulateRevisionLength"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/populateRevisionSha1.php b/maintenance/populateRevisionSha1.php index 113eef49..89bfb85b 100644 --- a/maintenance/populateRevisionSha1.php +++ b/maintenance/populateRevisionSha1.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that fills the rev_sha1 and ar_sha1 columns of revision @@ -48,7 +48,7 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance { $this->error( "revision table does not exist", true ); } elseif ( !$db->tableExists( 'archive' ) ) { $this->error( "archive table does not exist", true ); - } else if ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) { + } elseif ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) { $this->output( "rev_sha1 column does not exist\n\n", true ); return false; } @@ -189,9 +189,9 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance { array( 'ar_sha1' => Revision::base36Sha1( $text ) ), array( 'ar_namespace' => $row->ar_namespace, - 'ar_title' => $row->ar_title, + 'ar_title' => $row->ar_title, 'ar_timestamp' => $row->ar_timestamp, - 'ar_len' => $row->ar_len // extra sanity + 'ar_len' => $row->ar_len // extra sanity ), __METHOD__ ); @@ -201,4 +201,4 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance { } $maintClass = "PopulateRevisionSha1"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/postgres/archives/patch-external_user.sql b/maintenance/postgres/archives/patch-external_user.sql deleted file mode 100644 index 6058a706..00000000 --- a/maintenance/postgres/archives/patch-external_user.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE external_user ( - eu_local_id INTEGER NOT NULL PRIMARY KEY, - eu_external_id TEXT -); - -CREATE UNIQUE INDEX eu_external_id ON external_user (eu_external_id); diff --git a/maintenance/postgres/archives/patch-kill-iwl_pft.sql b/maintenance/postgres/archives/patch-kill-iwl_pft.sql deleted file mode 100644 index 4419d9e9..00000000 --- a/maintenance/postgres/archives/patch-kill-iwl_pft.sql +++ /dev/null @@ -1,7 +0,0 @@ --- --- Kill the old iwl_prefix_from_title index, which may be present on some --- installs if they ran update.php between it being added and being renamed --- - -DROP INDEX iwl_prefix_from_title; - diff --git a/maintenance/postgres/archives/patch-profiling.sql b/maintenance/postgres/archives/patch-profiling.sql index 1c4dce4e..5a2710a8 100644 --- a/maintenance/postgres/archives/patch-profiling.sql +++ b/maintenance/postgres/archives/patch-profiling.sql @@ -1,6 +1,7 @@ CREATE TABLE profiling ( pf_count INTEGER NOT NULL DEFAULT 0, - pf_time NUMERIC(18,10) NOT NULL DEFAULT 0, + pf_time FLOAT NOT NULL DEFAULT 0, + pf_memory FLOAT NOT NULL DEFAULT 0, pf_name TEXT NOT NULL, pf_server TEXT NULL ); diff --git a/maintenance/postgres/archives/patch-rename-iwl_prefix.sql b/maintenance/postgres/archives/patch-rename-iwl_prefix.sql index a4bdb6a9..0eb792ea 100644 --- a/maintenance/postgres/archives/patch-rename-iwl_prefix.sql +++ b/maintenance/postgres/archives/patch-rename-iwl_prefix.sql @@ -1,2 +1,2 @@ DROP INDEX iwl_prefix; -CREATE UNIQUE INDEX iwl_prefix_title_from ON iwlinks (iwl_prefix, iwl_from, iwl_title); +CREATE UNIQUE INDEX iwl_prefix_title_from ON iwlinks (iwl_prefix, iwl_title, iwl_from); diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql index 9cbabfdf..bc2428e4 100644 --- a/maintenance/postgres/tables.sql +++ b/maintenance/postgres/tables.sql @@ -18,6 +18,8 @@ DROP SEQUENCE IF EXISTS recentchanges_rc_id_seq CASCADE; DROP SEQUENCE IF EXISTS logging_log_id_seq CASCADE; DROP SEQUENCE IF EXISTS job_job_id_seq CASCADE; DROP SEQUENCE IF EXISTS category_cat_id_seq CASCADE; +DROP SEQUENCE IF EXISTS archive_ar_id_seq CASCADE; +DROP SEQUENCE IF EXISTS externallinks_el_id_seq CASCADE; DROP FUNCTION IF EXISTS page_deleted() CASCADE; DROP FUNCTION IF EXISTS ts2_page_title() CASCADE; DROP FUNCTION IF EXISTS ts2_page_text() CASCADE; @@ -156,7 +158,9 @@ ALTER TABLE page_props ADD CONSTRAINT page_props_pk PRIMARY KEY (pp_page,pp_prop CREATE INDEX page_props_propname ON page_props (pp_propname); CREATE UNIQUE INDEX pp_propname_page ON page_props (pp_propname,pp_page); +CREATE SEQUENCE archive_ar_id_seq; CREATE TABLE archive ( + ar_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('archive_ar_id_seq'), ar_namespace SMALLINT NOT NULL, ar_title TEXT NOT NULL, ar_text TEXT, -- technically should be bytea, but not used anymore @@ -224,7 +228,9 @@ CREATE TABLE categorylinks ( CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to); CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey, cl_from); +CREATE SEQUENCE externallinks_id_seq; CREATE TABLE externallinks ( + el_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('externallinks_id_seq'), el_from INTEGER NOT NULL REFERENCES page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, el_to TEXT NOT NULL, el_index TEXT NOT NULL @@ -232,13 +238,6 @@ CREATE TABLE externallinks ( CREATE INDEX externallinks_from_to ON externallinks (el_from,el_to); CREATE INDEX externallinks_index ON externallinks (el_index); -CREATE TABLE external_user ( - eu_local_id INTEGER NOT NULL PRIMARY KEY, - eu_external_id TEXT -); - -CREATE UNIQUE INDEX eu_external_id ON external_user (eu_external_id); - CREATE TABLE langlinks ( ll_from INTEGER NOT NULL REFERENCES page (page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, ll_lang TEXT, @@ -412,8 +411,6 @@ CREATE TABLE recentchanges ( rc_this_oldid INTEGER NOT NULL, rc_last_oldid INTEGER NOT NULL, rc_type SMALLINT NOT NULL DEFAULT 0, - rc_moved_to_ns SMALLINT, - rc_moved_to_title TEXT, rc_patrolled SMALLINT NOT NULL DEFAULT 0, rc_ip CIDR, rc_old_len INTEGER, @@ -594,8 +591,8 @@ $mw$; -- This table is not used unless profiling is turned on CREATE TABLE profiling ( pf_count INTEGER NOT NULL DEFAULT 0, - pf_time NUMERIC(18,10) NOT NULL DEFAULT 0, - pf_memory NUMERIC(18,10) NOT NULL DEFAULT 0, + pf_time FLOAT NOT NULL DEFAULT 0, + pf_memory FLOAT NOT NULL DEFAULT 0, pf_name TEXT NOT NULL, pf_server TEXT NULL ); @@ -679,6 +676,7 @@ CREATE TABLE iwlinks ( ); CREATE UNIQUE INDEX iwl_from ON iwlinks (iwl_from, iwl_prefix, iwl_title); CREATE UNIQUE INDEX iwl_prefix_title_from ON iwlinks (iwl_prefix, iwl_title, iwl_from); +CREATE UNIQUE INDEX iwl_prefix_from_title ON iwlinks (iwl_prefix, iwl_from, iwl_title); CREATE TABLE msg_resource ( mr_resource TEXT NOT NULL, diff --git a/maintenance/preprocessDump.php b/maintenance/preprocessDump.php index bb3d68b0..0dc19e28 100644 --- a/maintenance/preprocessDump.php +++ b/maintenance/preprocessDump.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/dumpIterator.php' ); +require_once __DIR__ . '/dumpIterator.php'; /** * Maintenance script that takes page text out of an XML dump file and @@ -86,12 +86,11 @@ class PreprocessDump extends DumpIterator { try { $this->mPreprocessor->preprocessToObj( strval( $content->getNativeData() ), 0 ); - } - catch(Exception $e) { - $this->error("Caught exception " . $e->getMessage() . " in " . $rev->getTitle()->getPrefixedText() ); + } catch ( Exception $e ) { + $this->error( "Caught exception " . $e->getMessage() . " in " . $rev->getTitle()->getPrefixedText() ); } } } $maintClass = "PreprocessDump"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/preprocessorFuzzTest.php b/maintenance/preprocessorFuzzTest.php index 49c7aee3..563ea459 100644 --- a/maintenance/preprocessorFuzzTest.php +++ b/maintenance/preprocessorFuzzTest.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/commandLine.inc' ); +require_once __DIR__ . '/commandLine.inc'; $wgHooks['BeforeParserFetchTemplateAndtitle'][] = 'PPFuzzTester::templateHook'; @@ -29,7 +29,7 @@ class PPFuzzTester { public $hairs = array( '[[', ']]', '{{', '{{', '}}', '}}', '{{{', '}}}', '<', '>', '<nowiki', '<gallery', '</nowiki>', '</gallery>', '<nOwIkI>', '</NoWiKi>', - '<!--' , '-->', + '<!--', '-->', "\n==", "==\n", '|', '=', "\n", ' ', "\t", "\x7f", '~~', '~~~', '~~~~', 'subst:', diff --git a/maintenance/protect.php b/maintenance/protect.php index ff13bd6e..ec03f934 100644 --- a/maintenance/protect.php +++ b/maintenance/protect.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that protects or unprotects a page. @@ -67,7 +67,7 @@ class Protect extends Maintenance { } $restrictions = array(); - foreach( $t->getRestrictionTypes() as $type ) { + foreach ( $t->getRestrictionTypes() as $type ) { $restrictions[$type] = $protection; } @@ -86,4 +86,4 @@ class Protect extends Maintenance { } $maintClass = "Protect"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/proxyCheck.php b/maintenance/proxyCheck.php deleted file mode 100644 index 2ccf703e..00000000 --- a/maintenance/proxyCheck.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** - * Command line script to check for an open proxy at a specified location. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @ingroup Maintenance - */ - -if( PHP_SAPI != 'cli' ) { - die( 1 ); -} - -/** - * - */ -$output = ''; - -/** - * Exit if there are not enough parameters, or if it's not command line mode - */ -if ( ( isset( $_REQUEST ) && array_key_exists( 'argv', $_REQUEST ) ) || count( $argv ) < 4 ) { - $output .= "Incorrect parameters\n"; -} else { - /** - * Get parameters - */ - $ip = $argv[1]; - $port = $argv[2]; - $url = $argv[3]; - $host = trim(`hostname`); - $output = "Connecting to $ip:$port, target $url, this hostname $host\n"; - - # Open socket - $sock = @fsockopen($ip, $port, $errno, $errstr, 5); - if ($errno == 0 ) { - $output .= "Connected\n"; - # Send payload - $request = "GET $url HTTP/1.0\r\n"; -# $request .= "Proxy-Connection: Keep-Alive\r\n"; -# $request .= "Pragma: no-cache\r\n"; -# $request .= "Host: ".$url."\r\n"; -# $request .= "User-Agent: MediaWiki open proxy check\r\n"; - $request .= "\r\n"; - @fputs($sock, $request); - $response = fgets($sock, 65536); - $output .= $response; - @fclose($sock); - } else { - $output .= "No connection\n"; - } -} - -$output = escapeshellarg( $output ); - -#`echo $output >> /home/tstarling/open/proxy.log`; diff --git a/maintenance/pruneFileCache.php b/maintenance/pruneFileCache.php index e058e3ec..48d38977 100644 --- a/maintenance/pruneFileCache.php +++ b/maintenance/pruneFileCache.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that prunes file cache for pages, objects, resources, etc. @@ -108,4 +108,4 @@ class PruneFileCache extends Maintenance { } $maintClass = "PruneFileCache"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeChangedFiles.php b/maintenance/purgeChangedFiles.php new file mode 100644 index 00000000..9f83ee7f --- /dev/null +++ b/maintenance/purgeChangedFiles.php @@ -0,0 +1,255 @@ +<?php +/** + * Scan the logging table and purge affected files within a timeframe. + * + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Maintenance + */ + +require_once __DIR__ . '/Maintenance.php'; + +/** + * Maintenance script that scans the deletion log and purges affected files + * within a timeframe. + * + * @ingroup Maintenance + */ +class PurgeChangedFiles extends Maintenance { + /** + * Mapping from type option to log type and actions. + * @var array + */ + private static $typeMappings = array( + 'created' => array( + 'upload' => array( 'upload' ), + 'import' => array( 'upload', 'interwiki' ), + ), + 'deleted' => array( + 'delete' => array( 'delete', 'revision' ), + 'suppress' => array( 'delete', 'revision' ), + ), + 'modified' => array( + 'upload' => array( 'overwrite', 'revert' ), + 'move' => array( 'move', 'move_redir' ), + ), + ); + + /** + * @var string + */ + private $startTimestamp; + + /** + * @var string + */ + private $endTimestamp; + + public function __construct() { + parent::__construct(); + $this->mDescription = "Scan the logging table and purge files and thumbnails."; + $this->addOption( 'starttime', 'Starting timestamp', true, true ); + $this->addOption( 'endtime', 'Ending timestamp', true, true ); + $this->addOption( 'type', 'Comma-separated list of types of changes to send purges for (' . + implode( ',', array_keys( self::$typeMappings ) ) . ',all)', false, true ); + $this->addOption( 'htcp-dest', 'HTCP announcement destination (IP:port)', false, true ); + $this->addOption( 'dry-run', 'Do not send purge requests' ); + $this->addOption( 'verbose', 'Show more output', false, false, 'v' ); + } + + public function execute() { + global $wgHTCPRouting; + + if ( $this->hasOption( 'htcp-dest' ) ) { + $parts = explode( ':', $this->getOption( 'htcp-dest' ) ); + if ( count( $parts ) < 2 ) { + // Add default htcp port + $parts[] = '4827'; + } + + // Route all HTCP messages to provided host:port + $wgHTCPRouting = array( + '' => array( 'host' => $parts[0], 'port' => $parts[1] ), + ); + $this->verbose( "HTCP broadcasts to {$parts[0]}:{$parts[1]}\n" ); + } + + // Find out which actions we should be concerned with + $typeOpt = $this->getOption( 'type', 'all' ); + $validTypes = array_keys( self::$typeMappings ); + if ( $typeOpt === 'all' ) { + // Convert 'all' to all registered types + $typeOpt = implode( ',', $validTypes ); + } + $typeList = explode( ',', $typeOpt ); + foreach ( $typeList as $type ) { + if ( !in_array( $type, $validTypes ) ) { + $this->error( "\nERROR: Unknown type: {$type}\n" ); + $this->maybeHelp( true ); + } + } + + // Validate the timestamps + $dbr = $this->getDB( DB_SLAVE ); + $this->startTimestamp = $dbr->timestamp( $this->getOption( 'starttime' ) ); + $this->endTimestamp = $dbr->timestamp( $this->getOption( 'endtime' ) ); + + if ( $this->startTimestamp > $this->endTimestamp ) { + $this->error( "\nERROR: starttime after endtime\n" ); + $this->maybeHelp( true ); + } + + // Turn on verbose when dry-run is enabled + if ( $this->hasOption( 'dry-run' ) ) { + $this->mOptions['verbose'] = 1; + } + + $this->verbose( 'Purging files that were: ' . implode( ', ', $typeList ) . "\n"); + foreach ( $typeList as $type ) { + $this->verbose( "Checking for {$type} files...\n" ); + $this->purgeFromLogType( $type ); + if ( !$this->hasOption( 'dry-run' ) ) { + $this->verbose( "...{$type} files purged.\n\n" ); + } + } + } + + /** + * Purge cache and thumbnails for changes of the given type. + * + * @param string $type Type of change to find + */ + protected function purgeFromLogType( $type ) { + $repo = RepoGroup::singleton()->getLocalRepo(); + $dbr = $this->getDB( DB_SLAVE ); + + foreach ( self::$typeMappings[$type] as $logType => $logActions ) { + $this->verbose( "Scanning for {$logType}/" . implode( ',', $logActions ) . "\n" ); + + $res = $dbr->select( + 'logging', + array( 'log_title', 'log_timestamp', 'log_params' ), + array( + 'log_namespace' => NS_FILE, + 'log_type' => $logType, + 'log_action' => $logActions, + 'log_timestamp >= ' . $dbr->addQuotes( $this->startTimestamp ), + 'log_timestamp <= ' . $dbr->addQuotes( $this->endTimestamp ), + ), + __METHOD__ + ); + + foreach ( $res as $row ) { + $file = $repo->newFile( Title::makeTitle( NS_FILE, $row->log_title ) ); + + if ( $this->hasOption( 'dry-run' ) ) { + $this->verbose( "{$type}[{$row->log_timestamp}]: {$row->log_title}\n" ); + continue; + } + + // Purge current version and any versions in oldimage table + $file->purgeCache(); + $file->purgeHistory(); + + if ( $logType === 'delete' ) { + // If there is an orphaned storage file... delete it + if ( !$file->exists() && $repo->fileExists( $file->getPath() ) ) { + $dpath = $this->getDeletedPath( $repo, $file ); + if ( $repo->fileExists( $dpath ) ) { + // Sanity check to avoid data loss + $repo->getBackend()->delete( array( 'src' => $file->getPath() ) ); + $this->verbose( "Deleted orphan file: {$file->getPath()}.\n" ); + + } else { + $this->error( "File was not deleted: {$file->getPath()}.\n" ); + } + } + + // Purge items from fileachive table (rows are likely here) + $this->purgeFromArchiveTable( $repo, $file ); + + } else if ( $logType === 'move' ) { + // Purge the target file as well + + $params = unserialize( $row->log_params ); + if ( isset( $params['4::target'] ) ) { + $target = $params['4::target']; + $targetFile = $repo->newFile( Title::makeTitle( NS_FILE, $target ) ); + $targetFile->purgeCache(); + $targetFile->purgeHistory(); + $this->verbose( "Purged file {$target}; move target @{$row->log_timestamp}.\n" ); + } + } + + $this->verbose( "Purged file {$row->log_title}; {$type} @{$row->log_timestamp}.\n" ); + } + } + } + + protected function purgeFromArchiveTable( LocalRepo $repo, LocalFile $file ) { + $dbr = $repo->getSlaveDB(); + $res = $dbr->select( + 'filearchive', + array( 'fa_archive_name' ), + array( 'fa_name' => $file->getName() ), + __METHOD__ + ); + + foreach ( $res as $row ) { + if ( $row->fa_archive_name === null ) { + // Was not an old version (current version names checked already) + continue; + } + $ofile = $repo->newFromArchiveName( $file->getTitle(), $row->fa_archive_name ); + // If there is an orphaned storage file still there...delete it + if ( !$file->exists() && $repo->fileExists( $ofile->getPath() ) ) { + $dpath = $this->getDeletedPath( $repo, $ofile ); + if ( $repo->fileExists( $dpath ) ) { + // Sanity check to avoid data loss + $repo->getBackend()->delete( array( 'src' => $ofile->getPath() ) ); + $this->output( "Deleted orphan file: {$ofile->getPath()}.\n" ); + + } else { + $this->error( "File was not deleted: {$ofile->getPath()}.\n" ); + } + } + $file->purgeOldThumbnails( $row->fa_archive_name ); + } + } + + protected function getDeletedPath( LocalRepo $repo, LocalFile $file ) { + $hash = $repo->getFileSha1( $file->getPath() ); + $key = "{$hash}.{$file->getExtension()}"; + return $repo->getDeletedHashPath( $key ) . $key; + } + + /** + * Send an output message iff the 'verbose' option has been provided. + * + * @param string $msg Message to output + */ + protected function verbose( $msg ) { + if ( $this->hasOption( 'verbose' ) ) { + $this->output( $msg ); + } + } + +} + +$maintClass = "PurgeChangedFiles"; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeChangedPages.php b/maintenance/purgeChangedPages.php new file mode 100644 index 00000000..071ac09c --- /dev/null +++ b/maintenance/purgeChangedPages.php @@ -0,0 +1,191 @@ +<?php +/** + * Send purge requests for pages edited in date range to squid/varnish. + * + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Maintenance + */ + +require_once __DIR__ . '/Maintenance.php'; + +/** + * Maintenance script that sends purge requests for pages edited in a date + * range to squid/varnish. + * + * Can be used to recover from an HTCP message partition or other major cache + * layer interruption. + * + * @ingroup Maintenance + */ +class PurgeChangedPages extends Maintenance { + + public function __construct() { + parent::__construct(); + $this->mDescription = 'Send purge requests for edits in date range to squid/varnish'; + $this->addOption( 'starttime', 'Starting timestamp', true, true ); + $this->addOption( 'endtime', 'Ending timestamp', true, true ); + $this->addOption( 'htcp-dest', 'HTCP announcement destination (IP:port)', false, true ); + $this->addOption( 'sleep-per-batch', 'Milliseconds to sleep between batches', false, true ); + $this->addOption( 'dry-run', 'Do not send purge requests' ); + $this->addOption( 'verbose', 'Show more output', false, false, 'v' ); + $this->setBatchSize( 100 ); + } + + public function execute() { + global $wgHTCPRouting; + + if ( $this->hasOption( 'htcp-dest' ) ) { + $parts = explode( ':', $this->getOption( 'htcp-dest' ) ); + if ( count( $parts ) < 2 ) { + // Add default htcp port + $parts[] = '4827'; + } + + // Route all HTCP messages to provided host:port + $wgHTCPRouting = array( + '' => array( 'host' => $parts[0], 'port' => $parts[1] ), + ); + if ( $this->hasOption( 'verbose' ) ) { + $this->output( "HTCP broadcasts to {$parts[0]}:{$parts[1]}\n" ); + } + } + + $dbr = $this->getDB( DB_SLAVE ); + $minTime = $dbr->timestamp( $this->getOption( 'starttime' ) ); + $maxTime = $dbr->timestamp( $this->getOption( 'endtime' ) ); + + if ( $maxTime < $minTime ) { + $this->error( "\nERROR: starttime after endtime\n" ); + $this->maybeHelp( true ); + } + + $stuckCount = 0; // loop breaker + while ( true ) { + // Adjust bach size if we are stuck in a second that had many changes + $bSize = $this->mBatchSize + ( $stuckCount * $this->mBatchSize ); + + $res = $dbr->select( + array( 'page', 'revision' ), + array( + 'rev_timestamp', + 'page_namespace', + 'page_title', + ), + array( + "rev_timestamp > " . $dbr->addQuotes( $minTime ), + "rev_timestamp <= " . $dbr->addQuotes( $maxTime ), + // Only get rows where the revision is the latest for the page. + // Other revisions would be duplicate and we don't need to purge if + // there has been an edit after the interesting time window. + "page_latest = rev_id", + ), + __METHOD__, + array( 'ORDER BY' => 'rev_timestamp', 'LIMIT' => $bSize ), + array( + 'page' => array( 'INNER JOIN', 'rev_page=page_id' ), + ) + ); + + if ( !$res->numRows() ) { + // nothing more found so we are done + break; + } + + // Kludge to not get stuck in loops for batches with the same timestamp + list( $rows, $lastTime ) = $this->pageableSortedRows( $res, 'rev_timestamp', $bSize ); + if ( !count( $rows ) ) { + ++$stuckCount; + continue; + } + // Reset suck counter + $stuckCount = 0; + + $this->output( "Processing changes from {$minTime} to {$lastTime}.\n" ); + + // Advance past the last row next time + $minTime = $lastTime; + + // Create list of URLs from page_namespace + page_title + $urls = array(); + foreach ( $rows as $row ) { + $title = Title::makeTitle( $row->page_namespace, $row->page_title ); + $urls[] = $title->getInternalURL(); + } + + if ( $this->hasOption( 'dry-run' ) || $this->hasOption( 'verbose' ) ) { + $this->output( implode( "\n", $urls ) . "\n" ); + if ( $this->hasOption( 'dry-run' ) ) { + continue; + } + } + + // Send batch of purge requests out to squids + $squid = new SquidUpdate( $urls, count( $urls ) ); + $squid->doUpdate(); + + if ( $this->hasOption( 'sleep-per-batch' ) ) { + // sleep-per-batch is milliseconds, usleep wants micro seconds. + usleep( 1000 * (int)$this->getOption( 'sleep-per-batch' ) ); + } + } + + $this->output( "Done!\n" ); + } + + /** + * Remove all the rows in a result set with the highest value for column + * $column unless the number of rows is less $limit. This returns the new + * array of rows and the highest value of column $column for the rows left. + * The ordering of rows is maintained. + * + * This is useful for paging on mostly-unique values that may sometimes + * have large clumps of identical values. It should be safe to do the next + * query on items with a value higher than the highest of the rows returned here. + * If this returns an empty array for a non-empty query result, then all the rows + * had the same column value and the query should be repeated with a higher LIMIT. + * + * @TODO: move this elsewhere + * + * @param ResultWrapper $res Query result sorted by $column (ascending) + * @param string $column + * @return array (array of rows, string column value) + */ + protected function pageableSortedRows( ResultWrapper $res, $column, $limit ) { + $rows = iterator_to_array( $res, false ); + $count = count( $rows ); + if ( !$count ) { + return array( array(), null ); // nothing to do + } elseif ( $count < $limit ) { + return array( $rows, $rows[$count - 1]->$column ); // no more rows left + } + $lastValue = $rows[$count - 1]->$column; // should be the highest + for ( $i = $count - 1; $i >= 0; --$i ) { + if ( $rows[$i]->$column === $lastValue ) { + unset( $rows[$i] ); + } else { + break; + } + } + $lastValueLeft = count( $rows ) ? $rows[count( $rows ) - 1]->$column : null; + return array( $rows, $lastValueLeft ); + } +} + +$maintClass = "PurgeChangedPages"; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeDeletedFiles.php b/maintenance/purgeDeletedFiles.php deleted file mode 100644 index cd62716b..00000000 --- a/maintenance/purgeDeletedFiles.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php -/** - * Scan the deletion log and purges affected files within a timeframe. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @ingroup Maintenance - */ - -require_once( __DIR__ . '/Maintenance.php' ); - -/** - * Maintenance script that scans the deletion log and purges affected files - * within a timeframe. - * - * @ingroup Maintenance - */ -class PurgeDeletedFiles extends Maintenance { - public function __construct() { - parent::__construct(); - $this->mDescription = "Scan the logging table and purge files that where deleted."; - $this->addOption( 'starttime', 'Starting timestamp', false, true ); - $this->addOption( 'endtime', 'Ending timestamp', false, true ); - } - - public function execute() { - $this->output( "Purging cache and thumbnails for deleted files...\n" ); - $this->purgeFromLogType( 'delete' ); - $this->output( "...deleted files purged.\n\n" ); - - $this->output( "Purging cache and thumbnails for suppressed files...\n" ); - $this->purgeFromLogType( 'suppress' ); - $this->output( "...suppressed files purged.\n" ); - } - - protected function purgeFromLogType( $logType ) { - $repo = RepoGroup::singleton()->getLocalRepo(); - $db = $repo->getSlaveDB(); - - $conds = array( - 'log_namespace' => NS_FILE, - 'log_type' => $logType, - 'log_action' => array( 'delete', 'revision' ) - ); - $start = $this->getOption( 'starttime' ); - if ( $start ) { - $conds[] = 'log_timestamp >= ' . $db->addQuotes( $db->timestamp( $start ) ); - } - $end = $this->getOption( 'endtime' ); - if ( $end ) { - $conds[] = 'log_timestamp <= ' . $db->addQuotes( $db->timestamp( $end ) ); - } - - $res = $db->select( 'logging', array( 'log_title', 'log_timestamp' ), $conds, __METHOD__ ); - foreach ( $res as $row ) { - $file = $repo->newFile( Title::makeTitle( NS_FILE, $row->log_title ) ); - - // Purge current version and any versions in oldimage table - $file->purgeCache(); - $file->purgeHistory(); - // Purge items from fileachive table (rows are likely here) - $this->purgeFromArchiveTable( $file ); - - $this->output( "Purged file {$row->log_title}; deleted on {$row->log_timestamp}.\n" ); - } - } - - protected function purgeFromArchiveTable( LocalFile $file ) { - $db = $file->getRepo()->getSlaveDB(); - $res = $db->select( 'filearchive', - array( 'fa_archive_name' ), - array( 'fa_name' => $file->getName() ), - __METHOD__ - ); - foreach ( $res as $row ) { - $file->purgeOldThumbnails( $row->fa_archive_name ); - } - } -} - -$maintClass = "PurgeDeletedFiles"; -require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/maintenance/purgeList.php b/maintenance/purgeList.php index b72c417e..2f895201 100644 --- a/maintenance/purgeList.php +++ b/maintenance/purgeList.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that sends purge requests for listed pages to squid. @@ -44,7 +44,7 @@ class PurgeList extends Maintenance { if ( $this->hasOption( 'all' ) ) { $this->purgeNamespace( false ); } elseif ( $this->hasOption( 'namespace' ) ) { - $this->purgeNamespace( intval( $this->getOption( 'namespace') ) ); + $this->purgeNamespace( intval( $this->getOption( 'namespace' ) ) ); } else { $this->doPurge(); } @@ -63,7 +63,7 @@ class PurgeList extends Maintenance { } elseif ( $page !== '' ) { $title = Title::newFromText( $page ); if ( $title ) { - $url = $title->getInternalUrl(); + $url = $title->getInternalURL(); $this->output( "$url\n" ); $urls[] = $url; if ( $this->getOption( 'purge' ) ) { @@ -74,7 +74,7 @@ class PurgeList extends Maintenance { } } } - $this->output( "Purging " . count( $urls ). " urls\n" ); + $this->output( "Purging " . count( $urls ) . " urls\n" ); $this->sendPurgeRequest( $urls ); } @@ -88,7 +88,7 @@ class PurgeList extends Maintenance { $conds = array( 'page_namespace' => $namespace ); } while ( true ) { - $res = $dbr->select( 'page', + $res = $dbr->select( 'page', array( 'page_id', 'page_namespace', 'page_title' ), $conds + array( 'page_id > ' . $dbr->addQuotes( $startId ) ), __METHOD__, @@ -104,7 +104,7 @@ class PurgeList extends Maintenance { $urls = array(); foreach ( $res as $row ) { $title = Title::makeTitle( $row->page_namespace, $row->page_title ); - $url = $title->getInternalUrl(); + $url = $title->getInternalURL(); $urls[] = $url; $startId = $row->page_id; } @@ -129,7 +129,7 @@ class PurgeList extends Maintenance { } } else { if ( $this->hasOption( 'verbose' ) ) { - $this->output( implode( "\n", $urls ) . "\n" ); + $this->output( implode( "\n", $urls ) . "\n" ); } $u = new SquidUpdate( $urls ); $u->doUpdate(); @@ -139,4 +139,4 @@ class PurgeList extends Maintenance { } $maintClass = "PurgeList"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeOldText.inc b/maintenance/purgeOldText.inc index 111c786a..db961d81 100644 --- a/maintenance/purgeOldText.inc +++ b/maintenance/purgeOldText.inc @@ -34,42 +34,42 @@ function PurgeRedundantText( $delete = false ) { $tbl_txt = $dbw->tableName( 'text' ); # Get "active" text records from the revisions table - echo( "Searching for active text records in revisions table..." ); + echo "Searching for active text records in revisions table..."; $res = $dbw->query( "SELECT DISTINCT rev_text_id FROM $tbl_rev" ); foreach ( $res as $row ) { $cur[] = $row->rev_text_id; } - echo( "done.\n" ); + echo "done.\n"; # Get "active" text records from the archive table - echo( "Searching for active text records in archive table..." ); + echo "Searching for active text records in archive table..."; $res = $dbw->query( "SELECT DISTINCT ar_text_id FROM $tbl_arc" ); $cur = array(); foreach ( $res as $row ) { $cur[] = $row->ar_text_id; } - echo( "done.\n" ); + echo "done.\n"; # Get the IDs of all text records not in these sets - echo( "Searching for inactive text records..." ); + echo "Searching for inactive text records..."; $set = implode( ', ', $cur ); $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" ); $old = array(); foreach ( $res as $row ) { $old[] = $row->old_id; } - echo( "done.\n" ); + echo "done.\n"; # Inform the user of what we're going to do $count = count( $old ); - echo( "$count inactive items found.\n" ); + echo "$count inactive items found.\n"; # Delete as appropriate if ( $delete && $count ) { - echo( "Deleting..." ); + echo "Deleting..."; $set = implode( ', ', $old ); $dbw->query( "DELETE FROM $tbl_txt WHERE old_id IN ( $set )" ); - echo( "done.\n" ); + echo "done.\n"; } # Done diff --git a/maintenance/purgeOldText.php b/maintenance/purgeOldText.php index 1f0b063b..3d81e2df 100644 --- a/maintenance/purgeOldText.php +++ b/maintenance/purgeOldText.php @@ -22,7 +22,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that purges old text records from the database. @@ -42,4 +42,4 @@ class PurgeOldText extends Maintenance { } $maintClass = "PurgeOldText"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeParserCache.php b/maintenance/purgeParserCache.php index e21dd176..ca2a0414 100644 --- a/maintenance/purgeParserCache.php +++ b/maintenance/purgeParserCache.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require( __DIR__ . '/Maintenance.php' ); +require __DIR__ . '/Maintenance.php'; /** * Maintenance script to remove old objects from the parser cache. @@ -81,4 +81,4 @@ class PurgeParserCache extends Maintenance { } } $maintClass = 'PurgeParserCache'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/reassignEdits.php b/maintenance/reassignEdits.php index 2d79f363..7e15c09e 100644 --- a/maintenance/reassignEdits.php +++ b/maintenance/reassignEdits.php @@ -23,7 +23,7 @@ * @licence GNU General Public Licence 2.0 or later */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that reassigns edits from a user or IP address @@ -46,7 +46,7 @@ class ReassignEdits extends Maintenance { if ( $this->hasArg( 0 ) && $this->hasArg( 1 ) ) { # Set up the users involved $from = $this->initialiseUser( $this->getArg( 0 ) ); - $to = $this->initialiseUser( $this->getArg( 1 ) ); + $to = $this->initialiseUser( $this->getArg( 1 ) ); # If the target doesn't exist, and --force is not set, stop here if ( $to->getId() || $this->hasOption( 'force' ) ) { @@ -179,4 +179,4 @@ class ReassignEdits extends Maintenance { } $maintClass = "ReassignEdits"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildFileCache.php b/maintenance/rebuildFileCache.php index 3165b97f..12ed9fac 100644 --- a/maintenance/rebuildFileCache.php +++ b/maintenance/rebuildFileCache.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that builds file cache for content pages. @@ -153,10 +153,11 @@ class RebuildFileCache extends Maintenance { $this->output( "Done!\n" ); // Remove these to be safe - if ( isset( $wgTitle ) ) + if ( isset( $wgTitle ) ) { unset( $wgTitle ); + } } } $maintClass = "RebuildFileCache"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildImages.php b/maintenance/rebuildImages.php index 2842b402..53bf823f 100644 --- a/maintenance/rebuildImages.php +++ b/maintenance/rebuildImages.php @@ -30,7 +30,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to update image metadata records. @@ -217,4 +217,4 @@ class ImageBuilder extends Maintenance { } $maintClass = 'ImageBuilder'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildLocalisationCache.php b/maintenance/rebuildLocalisationCache.php index db77564b..b7f306b1 100644 --- a/maintenance/rebuildLocalisationCache.php +++ b/maintenance/rebuildLocalisationCache.php @@ -29,7 +29,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to rebuild the localisation cache. @@ -44,6 +44,8 @@ class RebuildLocalisationCache extends Maintenance { $this->addOption( 'threads', 'Fork more than one thread', false, true ); $this->addOption( 'outdir', 'Override the output directory (normally $wgCacheDirectory)', false, true ); + $this->addOption( 'lang', 'Only rebuild these languages, comma separated.', + false, true ); } public function memoryLimit() { @@ -59,7 +61,7 @@ class RebuildLocalisationCache extends Maintenance { # no l10n cache. Break the cycle by forcing $wgLanguageCode = 'en'. global $wgLanguageCode; $wgLanguageCode = 'en'; - return parent::finalSetup(); + parent::finalSetup(); } public function execute() { @@ -90,7 +92,19 @@ class RebuildLocalisationCache extends Maintenance { } $lc = new LocalisationCache_BulkLoad( $conf ); - $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ); + $allCodes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ); + if ( $this->hasOption( 'lang' ) ) { + # Validate requested languages + $codes = array_intersect( $allCodes, + explode( ',', $this->getOption( 'lang' ) ) ); + # Bailed out if nothing is left + if ( count( $codes ) == 0 ) { + $this->error( 'None of the languages specified exists.', 1 ); + } + } else { + # By default get all languages + $codes = $allCodes; + } sort( $codes ); // Initialise and split into chunks @@ -162,4 +176,4 @@ class RebuildLocalisationCache extends Maintenance { } $maintClass = "RebuildLocalisationCache"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildall.php b/maintenance/rebuildall.php index 882ae1b3..1268d209 100644 --- a/maintenance/rebuildall.php +++ b/maintenance/rebuildall.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that rebuilds link tracking tables from scratch. @@ -35,6 +35,10 @@ class RebuildAll extends Maintenance { $this->mDescription = "Rebuild links, text index and recent changes"; } + public function getDbType() { + return Maintenance::DB_ADMIN; + } + public function execute() { // Rebuild the text index if ( wfGetDB( DB_SLAVE )->getType() != 'postgres' ) { @@ -58,4 +62,4 @@ class RebuildAll extends Maintenance { } $maintClass = "RebuildAll"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildmessages.php b/maintenance/rebuildmessages.php index a70e591f..f223f1ab 100644 --- a/maintenance/rebuildmessages.php +++ b/maintenance/rebuildmessages.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that purges all languages from the message cache. @@ -45,12 +45,13 @@ class RebuildMessages extends Maintenance { foreach ( $databases as $db ) { $this->output( "Deleting message cache for {$db}... " ); $messageMemc->delete( "{$db}:messages" ); - if ( $wgEnableSidebarCache ) + if ( $wgEnableSidebarCache ) { $messageMemc->delete( "{$db}:sidebar" ); + } $this->output( "Deleted\n" ); } } } $maintClass = "RebuildMessages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildrecentchanges.php b/maintenance/rebuildrecentchanges.php index bfaaab54..18348258 100644 --- a/maintenance/rebuildrecentchanges.php +++ b/maintenance/rebuildrecentchanges.php @@ -23,7 +23,7 @@ * @todo Document */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that rebuilds recent changes from scratch. @@ -61,9 +61,9 @@ class RebuildRecentchanges extends Maintenance { $this->output( '$wgRCMaxAge=' . $wgRCMaxAge ); $days = $wgRCMaxAge / 24 / 3600; if ( intval( $days ) == $days ) { - $this->output( " (" . $days . " days)\n" ); + $this->output( " (" . $days . " days)\n" ); } else { - $this->output( " (approx. " . intval( $days ) . " days)\n" ); + $this->output( " (approx. " . intval( $days ) . " days)\n" ); } $cutoff = time() - $wgRCMaxAge; @@ -99,13 +99,13 @@ class RebuildRecentchanges extends Maintenance { */ private function rebuildRecentChangesTablePass2() { $dbw = wfGetDB( DB_MASTER ); - list ( $recentchanges, $revision ) = $dbw->tableNamesN( 'recentchanges', 'revision' ); + list( $recentchanges, $revision ) = $dbw->tableNamesN( 'recentchanges', 'revision' ); $this->output( "Updating links and size differences...\n" ); # Fill in the rc_last_oldid field, which points to the previous edit $sql = "SELECT rc_cur_id,rc_this_oldid,rc_timestamp FROM $recentchanges " . - "ORDER BY rc_cur_id,rc_timestamp"; + "ORDER BY rc_cur_id,rc_timestamp"; $res = $dbw->query( $sql, DB_MASTER ); $lastCurId = 0; @@ -142,12 +142,12 @@ class RebuildRecentchanges extends Maintenance { $dbw->update( 'recentchanges', array( 'rc_last_oldid' => $lastOldId, - 'rc_new' => $new, - 'rc_type' => $new, - 'rc_old_len' => $lastSize, - 'rc_new_len' => $size, + 'rc_new' => $new, + 'rc_type' => $new, + 'rc_old_len' => $lastSize, + 'rc_new_len' => $size, ), array( - 'rc_cur_id' => $lastCurId, + 'rc_cur_id' => $lastCurId, 'rc_this_oldid' => $obj->rc_this_oldid, ), __METHOD__ @@ -292,4 +292,4 @@ class RebuildRecentchanges extends Maintenance { } $maintClass = "RebuildRecentchanges"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rebuildtextindex.php b/maintenance/rebuildtextindex.php index 534b7ca1..c651f720 100644 --- a/maintenance/rebuildtextindex.php +++ b/maintenance/rebuildtextindex.php @@ -25,7 +25,7 @@ * @todo document */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that rebuilds search index table from scratch. @@ -115,9 +115,8 @@ class RebuildTextIndex extends Maintenance { $rev = new Revision( $s ); $content = $rev->getContent(); - $text = $content->getTextForSearchIndex(); - $u = new SearchUpdate( $s->page_id, $title, $text ); + $u = new SearchUpdate( $s->page_id, $title, $content ); $u->doUpdate(); } catch ( MWContentSerializationException $ex ) { $this->output( "Failed to deserialize content of revision {$s->rev_id} of page " @@ -147,7 +146,7 @@ class RebuildTextIndex extends Maintenance { $searchindex = $this->db->tableName( 'searchindex' ); $this->output( "\nRebuild the index...\n" ); $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " . - "ADD FULLTEXT si_text (si_text)"; + "ADD FULLTEXT si_text (si_text)"; $this->db->query( $sql, __METHOD__ ); } @@ -162,4 +161,4 @@ class RebuildTextIndex extends Maintenance { } $maintClass = "RebuildTextIndex"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/refreshFileHeaders.php b/maintenance/refreshFileHeaders.php index 74f0f35d..8b852e39 100644 --- a/maintenance/refreshFileHeaders.php +++ b/maintenance/refreshFileHeaders.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to refresh file headers from metadata @@ -90,4 +90,4 @@ class RefreshFileHeaders extends Maintenance { } $maintClass = 'RefreshFileHeaders'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/refreshImageMetadata.php b/maintenance/refreshImageMetadata.php index 55f5b4aa..7fe5c4c1 100644 --- a/maintenance/refreshImageMetadata.php +++ b/maintenance/refreshImageMetadata.php @@ -27,7 +27,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to refresh image metadata fields. @@ -99,7 +99,7 @@ class RefreshImageMetadata extends Maintenance { if ( $res->numRows() > 0 ) { $row1 = $res->current(); - $this->output( "Processing next {$this->mBatchSize} rows starting with {$row1->img_name}.\n"); + $this->output( "Processing next {$this->mBatchSize} rows starting with {$row1->img_name}.\n" ); $res->rewind(); } else { $this->error( "No images to process.", 4 ); @@ -123,7 +123,7 @@ class RefreshImageMetadata extends Maintenance { $this->output( "Warning: File:{$row->img_name} used to have " . "$oldLength bytes of metadata but now has $newLength bytes.\n" ); } elseif ( $verbose ) { - $this->output("Refreshed File:{$row->img_name}.\n" ); + $this->output( "Refreshed File:{$row->img_name}.\n" ); } } else { $leftAlone++; @@ -138,7 +138,7 @@ class RefreshImageMetadata extends Maintenance { } if ( $verbose ) { - $this->output("Forcibly refreshed File:{$row->img_name}.\n" ); + $this->output( "Forcibly refreshed File:{$row->img_name}.\n" ); } } else { @@ -151,7 +151,7 @@ class RefreshImageMetadata extends Maintenance { } $conds2 = array( 'img_name > ' . $dbw->addQuotes( $row->img_name ) ); wfWaitForSlaves(); - } while( $res->numRows() === $this->mBatchSize ); + } while ( $res->numRows() === $this->mBatchSize ); $total = $upgraded + $leftAlone; if ( $force ) { @@ -173,7 +173,7 @@ class RefreshImageMetadata extends Maintenance { $like = $this->getOption( 'metadata-contains', false ); if ( $end !== false ) { - $conds[] = 'img_name <= ' . $dbw->addQuotes( $end ) ; + $conds[] = 'img_name <= ' . $dbw->addQuotes( $end ); } if ( $mime !== false ) { list( $major, $minor ) = File::splitMime( $mime ); @@ -209,4 +209,4 @@ class RefreshImageMetadata extends Maintenance { $maintClass = 'RefreshImageMetadata'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/refreshLinks.php b/maintenance/refreshLinks.php index 7b255664..98ea9301 100644 --- a/maintenance/refreshLinks.php +++ b/maintenance/refreshLinks.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to refresh link tables. @@ -160,7 +160,7 @@ class RefreshLinks extends Maintenance { } if ( !$redirectsOnly ) { - $this->output( "Refreshing links table.\n" ); + $this->output( "Refreshing links tables.\n" ); $this->output( "Starting from page_id $start of $end.\n" ); for ( $id = $start; $id <= $end; $id++ ) { @@ -281,12 +281,13 @@ class RefreshLinks extends Maintenance { $this->output( "Retrieving illegal entries from $table... " ); // SELECT DISTINCT( $field ) FROM $table LEFT JOIN page ON $field=page_id WHERE page_id IS NULL; - $results = $dbr->select( array( $table, 'page' ), - $field, - array( 'page_id' => null ), - __METHOD__, - 'DISTINCT', - array( 'page' => array( 'LEFT JOIN', "$field=page_id" ) ) + $results = $dbr->select( + array( $table, 'page' ), + $field, + array( 'page_id' => null ), + __METHOD__, + 'DISTINCT', + array( 'page' => array( 'LEFT JOIN', "$field=page_id" ) ) ); $counter = 0; @@ -315,4 +316,4 @@ class RefreshLinks extends Maintenance { } $maintClass = 'RefreshLinks'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/removeUnusedAccounts.php b/maintenance/removeUnusedAccounts.php index b4528ca0..16cb17ab 100644 --- a/maintenance/removeUnusedAccounts.php +++ b/maintenance/removeUnusedAccounts.php @@ -23,7 +23,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that removes unused user accounts from the database. @@ -74,9 +74,12 @@ class RemoveUnusedAccounts extends Maintenance { # If required, go back and delete each marked account if ( $count > 0 && $this->hasOption( 'delete' ) ) { - $this->output( "\nDeleting inactive accounts..." ); + $this->output( "\nDeleting unused accounts..." ); $dbw = wfGetDB( DB_MASTER ); $dbw->delete( 'user', array( 'user_id' => $del ), __METHOD__ ); + $dbw->delete( 'user_groups', array( 'ug_user' => $del ), __METHOD__ ); + $dbw->delete( 'user_former_groups', array( 'ufg_user' => $del ), __METHOD__ ); + $dbw->delete( 'user_properties', array( 'up_user' => $del ), __METHOD__ ); $dbw->delete( 'logging', array( 'log_user' => $del ), __METHOD__ ); $dbw->delete( 'recentchanges', array( 'rc_user' => $del ), __METHOD__ ); $this->output( "done.\n" ); @@ -124,4 +127,4 @@ class RemoveUnusedAccounts extends Maintenance { } $maintClass = "RemoveUnusedAccounts"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/renameDbPrefix.php b/maintenance/renameDbPrefix.php index 6f244791..ed9d1f5d 100644 --- a/maintenance/renameDbPrefix.php +++ b/maintenance/renameDbPrefix.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that changes the prefix of database tables. @@ -91,4 +91,4 @@ class RenameDbPrefix extends Maintenance { } $maintClass = "RenameDbPrefix"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/renderDump.php b/maintenance/renderDump.php index 2ba2b3dc..0cde28c5 100644 --- a/maintenance/renderDump.php +++ b/maintenance/renderDump.php @@ -28,7 +28,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that takes page text out of an XML dump file @@ -69,9 +69,10 @@ class DumpRenderer extends Maintenance { $importer->doImport(); $delta = microtime( true ) - $this->startTime; - $this->error( "Rendered {$this->count} pages in " . round($delta, 2) . " seconds " ); - if ($delta > 0) - $this->error( round($this->count / $delta, 2) . " pages/sec" ); + $this->error( "Rendered {$this->count} pages in " . round( $delta, 2 ) . " seconds " ); + if ( $delta > 0 ) { + $this->error( round( $this->count / $delta, 2 ) . " pages/sec" ); + } $this->error( "\n" ); } @@ -104,11 +105,10 @@ class DumpRenderer extends Maintenance { $output = $content->getParserOutput( $title, null, $options ); file_put_contents( $filename, - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " . - "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" . - "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" . + "<!DOCTYPE html>\n" . + "<html lang=\"en\" dir=\"ltr\">\n" . "<head>\n" . - "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n" . + "<meta charset=\"UTF-8\" />\n" . "<title>" . htmlspecialchars( $display ) . "</title>\n" . "</head>\n" . "<body>\n" . @@ -119,4 +119,4 @@ class DumpRenderer extends Maintenance { } $maintClass = "DumpRenderer"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/resetUserTokens.php b/maintenance/resetUserTokens.php index d7f8c6d0..bfe04d79 100644 --- a/maintenance/resetUserTokens.php +++ b/maintenance/resetUserTokens.php @@ -21,9 +21,10 @@ * @file * @ingroup Maintenance * @author Daniel Friesen <mediawiki@danielfriesen.name> + * @author Chris Steipp <csteipp@wikimedia.org> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to reset the user_token for all users on the wiki. @@ -35,14 +36,21 @@ class ResetUserTokens extends Maintenance { parent::__construct(); $this->mDescription = "Reset the user_token of all users on the wiki. Note that this may log some of them out."; $this->addOption( 'nowarn', "Hides the 5 seconds warning", false, false ); + $this->addOption( 'nulls', 'Only reset tokens that are currently null (string of \x00\'s)', false, false ); + $this->setBatchSize( 1000 ); } public function execute() { + $this->nullsOnly = $this->getOption( 'nulls' ); if ( !$this->getOption( 'nowarn' ) ) { - $this->output( "The script is about to reset the user_token for ALL USERS in the database.\n" ); - $this->output( "This may log some of them out and is not necessary unless you believe your\n" ); - $this->output( "user table has been compromised.\n" ); + if ( $this->nullsOnly ) { + $this->output( "The script is about to reset the user_token for USERS WITH NULL TOKENS in the database.\n" ); + } else { + $this->output( "The script is about to reset the user_token for ALL USERS in the database.\n" ); + $this->output( "This may log some of them out and is not necessary unless you believe your\n" ); + $this->output( "user table has been compromised.\n" ); + } $this->output( "\n" ); $this->output( "Abort with control-c in the next five seconds (skip this countdown with --nowarn) ... " ); wfCountDown( 5 ); @@ -50,29 +58,53 @@ class ResetUserTokens extends Maintenance { // We list user by user_id from one of the slave database $dbr = wfGetDB( DB_SLAVE ); - $result = $dbr->select( 'user', - array( 'user_id' ), - array(), - __METHOD__ - ); - foreach ( $result as $id ) { - $user = User::newFromId( $id->user_id ); + $where = array(); + if ( $this->nullsOnly ) { + // Have to build this by hand, because \ is escaped in helper functions + $where = array( 'user_token = \'' . str_repeat( '\0', 32) . '\'' ); + } - $username = $user->getName(); + $maxid = $dbr->selectField( 'user', 'MAX(user_id)', array(), __METHOD__ ); - $this->output( "Resetting user_token for $username: " ); + $min = 0; + $max = $this->mBatchSize; - // Change value - $user->setToken(); - $user->saveSettings(); + do { + $result = $dbr->select( 'user', + array( 'user_id' ), + array_merge( + $where, + array( 'user_id > ' . $dbr->addQuotes( $min ), + 'user_id <= ' . $dbr->addQuotes( $max ) + ) + ), + __METHOD__ + ); - $this->output( " OK\n" ); + foreach ( $result as $user ) { + $this->updateUser( $user->user_id ); + } - } + $min = $max; + $max = $min + $this->mBatchSize; + + wfWaitForSlaves(); + + } while ( $max <= $maxid ); + + } + private function updateUser( $userid ) { + $user = User::newFromId( $userid ); + $username = $user->getName(); + $this->output( 'Resetting user_token for "' . $username . '": ' ); + // Change value + $user->setToken(); + $user->saveSettings(); + $this->output( " OK\n" ); } } $maintClass = "ResetUserTokens"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/rollbackEdits.php b/maintenance/rollbackEdits.php index 4660bcef..e5e33c02 100644 --- a/maintenance/rollbackEdits.php +++ b/maintenance/rollbackEdits.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to rollback all edits by a given user or IP provided @@ -104,4 +104,4 @@ class RollbackEdits extends Maintenance { } $maintClass = 'RollbackEdits'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/runBatchedQuery.php b/maintenance/runBatchedQuery.php index e1139164..93ba24a9 100644 --- a/maintenance/runBatchedQuery.php +++ b/maintenance/runBatchedQuery.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to run a database query in batches and wait for slaves. @@ -38,8 +38,9 @@ class BatchedQueryRunner extends Maintenance { } public function execute() { - if ( !$this->hasArg() ) + if ( !$this->hasArg() ) { $this->error( "No query specified. Specify the query as a command line parameter.", true ); + } $query = $this->getArg(); $n = 1; @@ -61,4 +62,4 @@ class BatchedQueryRunner extends Maintenance { $maintClass = "BatchedQueryRunner"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/runJobs.php b/maintenance/runJobs.php index b1be714c..429edf42 100644 --- a/maintenance/runJobs.php +++ b/maintenance/runJobs.php @@ -25,7 +25,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that runs pending jobs. @@ -61,10 +61,11 @@ class RunJobs extends Maintenance { $procs = intval( $this->getOption( 'procs' ) ); if ( $procs < 1 || $procs > 1000 ) { $this->error( "Invalid argument to --procs", true ); - } - $fc = new ForkController( $procs ); - if ( $fc->start() != 'child' ) { - exit( 0 ); + } elseif ( $procs != 1 ) { + $fc = new ForkController( $procs ); + if ( $fc->start() != 'child' ) { + exit( 0 ); + } } } $maxJobs = $this->getOption( 'maxjobs', false ); @@ -72,7 +73,6 @@ class RunJobs extends Maintenance { $startTime = time(); $type = $this->getOption( 'type', false ); $wgTitle = Title::newFromText( 'RunJobs.php' ); - $dbw = wfGetDB( DB_MASTER ); $jobsRun = 0; // counter $group = JobQueueGroup::singleton(); @@ -82,16 +82,20 @@ class RunJobs extends Maintenance { $this->runJobsLog( "Executed $count periodic queue task(s)." ); } - $lastTime = time(); + $flags = JobQueueGroup::USE_CACHE | JobQueueGroup::USE_PRIORITY; + $lastTime = time(); // time since last slave check do { $job = ( $type === false ) - ? $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE ) + ? $group->pop( JobQueueGroup::TYPE_DEFAULT, $flags ) : $group->pop( $type ); // job from a single queue if ( $job ) { // found a job ++$jobsRun; $this->runJobsLog( $job->toString() . " STARTING" ); + // Set timer to stop the job if too much CPU time is used + set_time_limit( $maxTime ?: 0 ); // Run the job... + wfProfileIn( __METHOD__ . '-' . get_class( $job ) ); $t = microtime( true ); try { $status = $job->run(); @@ -99,15 +103,19 @@ class RunJobs extends Maintenance { } catch ( MWException $e ) { $status = false; $error = get_class( $e ) . ': ' . $e->getMessage(); + $e->report(); // write error to STDERR and the log } $timeMs = intval( ( microtime( true ) - $t ) * 1000 ); + wfProfileOut( __METHOD__ . '-' . get_class( $job ) ); + // Disable the timer + set_time_limit( 0 ); // Mark the job as done on success or when the job cannot be retried if ( $status !== false || !$job->allowRetries() ) { $group->ack( $job ); // done } - if ( !$status ) { + if ( $status === false ) { $this->runJobsLog( $job->toString() . " t=$timeMs error={$error}" ); } else { $this->runJobsLog( $job->toString() . " t=$timeMs good" ); @@ -124,16 +132,42 @@ class RunJobs extends Maintenance { $timePassed = time() - $lastTime; if ( $timePassed >= 5 || $timePassed < 0 ) { wfWaitForSlaves(); + $lastTime = time(); } // Don't let any queue slaves/backups fall behind if ( $jobsRun > 0 && ( $jobsRun % 100 ) == 0 ) { $group->waitForBackups(); } + + // Bail if near-OOM instead of in a job + $this->assertMemoryOK(); } } while ( $job ); // stop when there are no jobs } /** + * Make sure that this script is not too close to the memory usage limit + * @throws MWException + */ + private function assertMemoryOK() { + static $maxBytes = null; + if ( $maxBytes === null ) { + $m = array(); + if ( preg_match( '!^(\d+)(k|m|g|)$!i', ini_get( 'memory_limit' ), $m ) ) { + list( , $num, $unit ) = $m; + $conv = array( 'g' => 1024 * 1024 * 1024, 'm' => 1024 * 1024, 'k' => 1024, '' => 1 ); + $maxBytes = $num * $conv[strtolower( $unit )]; + } else { + $maxBytes = 0; + } + } + $usedBytes = memory_get_usage(); + if ( $maxBytes && $usedBytes >= 0.95 * $maxBytes ) { + throw new MWException( "Detected excessive memory usage ($usedBytes/$maxBytes)." ); + } + } + + /** * Log the job message * @param $msg String The message to log */ @@ -144,4 +178,4 @@ class RunJobs extends Maintenance { } $maintClass = "RunJobs"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/showCacheStats.php b/maintenance/showCacheStats.php index 8f238680..cd9768d4 100644 --- a/maintenance/showCacheStats.php +++ b/maintenance/showCacheStats.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that shows statistics from the cache. @@ -103,4 +103,4 @@ class ShowCacheStats extends Maintenance { } $maintClass = "ShowCacheStats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/showJobs.php b/maintenance/showJobs.php index 8b49517f..afd7c745 100644 --- a/maintenance/showJobs.php +++ b/maintenance/showJobs.php @@ -25,7 +25,7 @@ * @author Antoine Musso */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that reports the number of jobs currently waiting @@ -38,17 +38,33 @@ class ShowJobs extends Maintenance { parent::__construct(); $this->mDescription = "Show number of jobs waiting in master database"; $this->addOption( 'group', 'Show number of jobs per job type' ); + $this->addOption( 'list', 'Show a complete list of all jobs in a machine-readable format, instead of statistics' ); } public function execute() { $group = JobQueueGroup::singleton(); - if ( $this->hasOption( 'group' ) ) { + if ( $this->hasOption( 'list' ) ) { foreach ( $group->getQueueTypes() as $type ) { - $queue = $group->get( $type ); + $queue = $group->get( $type ); + foreach ( $queue->getAllQueuedJobs() as $job ) { + $this->output( $job->toString() . " status=unclaimed\n" ); + } + foreach ( $queue->getAllDelayedJobs() as $job ) { + $this->output( $job->toString() . " status=delayed\n" ); + } + } + } elseif ( $this->hasOption( 'group' ) ) { + foreach ( $group->getQueueTypes() as $type ) { + $queue = $group->get( $type ); $pending = $queue->getSize(); $claimed = $queue->getAcquiredCount(); + $abandoned = $queue->getAbandonedCount(); + $active = max( 0, $claimed - $abandoned ); if ( ( $pending + $claimed ) > 0 ) { - $this->output( "{$type}: $pending queued; $claimed acquired\n" ); + $this->output( + "{$type}: $pending queued; " . + "$claimed claimed ($active active, $abandoned abandoned)\n" + ); } } } else { @@ -62,4 +78,4 @@ class ShowJobs extends Maintenance { } $maintClass = "ShowJobs"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/showSiteStats.php b/maintenance/showSiteStats.php index e7359b2f..49148b33 100644 --- a/maintenance/showSiteStats.php +++ b/maintenance/showSiteStats.php @@ -29,7 +29,7 @@ * @license GNU General Public License 2.0 or later */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to show the cached statistics. @@ -48,6 +48,7 @@ class ShowSiteStats extends Maintenance { 'ss_good_articles' => 'Number of articles', 'ss_total_pages' => 'Total pages', 'ss_users' => 'Number of users', + 'ss_active_users' => 'Active users', 'ss_images' => 'Number of images', ); @@ -59,7 +60,7 @@ class ShowSiteStats extends Maintenance { $max_length_value = $max_length_desc = 0; foreach ( $fields as $field => $desc ) { $max_length_value = max( $max_length_value, strlen( $stats->$field ) ); - $max_length_desc = max( $max_length_desc, strlen( $desc ) ) ; + $max_length_desc = max( $max_length_desc, strlen( $desc ) ); } // Show them @@ -70,4 +71,4 @@ class ShowSiteStats extends Maintenance { } $maintClass = "ShowSiteStats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/sql.php b/maintenance/sql.php index 11699909..a628b0bc 100644 --- a/maintenance/sql.php +++ b/maintenance/sql.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that sends SQL queries from the specified file to the database. @@ -34,16 +34,42 @@ class MwSql extends Maintenance { parent::__construct(); $this->mDescription = "Send SQL queries to a MediaWiki database"; $this->addOption( 'cluster', 'Use an external cluster by name', false, true ); + $this->addOption( 'slave', 'Use a slave server (either "any" or by name)', false, true ); } public function execute() { - // Get a DB handle (with this wiki's DB select) from the appropriate load balancer + // Get the appropriate load balancer (for this wiki) if ( $this->hasOption( 'cluster' ) ) { $lb = wfGetLBFactory()->getExternalLB( $this->getOption( 'cluster' ) ); - $dbw = $lb->getConnection( DB_MASTER ); // master for external LB } else { - $dbw = wfGetDB( DB_MASTER ); // master for primary LB for this wiki + $lb = wfGetLB(); } + // Figure out which server to use + if ( $this->hasOption( 'slave' ) ) { + $server = $this->getOption( 'slave' ); + if ( $server === 'any' ) { + $index = DB_SLAVE; + } else { + $index = null; + for ( $i = 0; $i < $lb->getServerCount(); ++$i ) { + if ( $lb->getServerName( $i ) === $server ) { + $index = $i; + break; + } + } + if ( $index === null ) { + $this->error( "No slave server configured with the name '$server'.", 1 ); + } + } + } else { + $index = DB_MASTER; + } + // Get a DB handle (with this wiki's DB selected) from the appropriate load balancer + $dbw = $lb->getConnection( $index ); + if ( $this->hasOption( 'slave' ) && $dbw->getLBInfo( 'master' ) !== null ) { + $this->error( "The server selected ({$dbw->getServer()}) is not a slave.", 1 ); + } + if ( $this->hasArg( 0 ) ) { $file = fopen( $this->getArg( 0 ), 'r' ); if ( !$file ) { @@ -70,9 +96,9 @@ class MwSql extends Maintenance { $wholeLine = ''; $newPrompt = '> '; - $prompt = $newPrompt; + $prompt = $newPrompt; while ( ( $line = Maintenance::readconsole( $prompt ) ) !== false ) { - if( !$line ) { + if ( !$line ) { # User simply pressed return key continue; } @@ -91,12 +117,12 @@ class MwSql extends Maintenance { readline_add_history( $wholeLine . $dbw->getDelimiter() ); readline_write_history( $historyFile ); } - try{ + try { $res = $dbw->query( $wholeLine ); $this->sqlPrintResult( $res, $dbw ); - $prompt = $newPrompt; + $prompt = $newPrompt; $wholeLine = ''; - } catch (DBQueryError $e) { + } catch ( DBQueryError $e ) { $doDie = ! Maintenance::posix_isatty( 0 ); $this->error( $e, $doDie ); } @@ -132,4 +158,4 @@ class MwSql extends Maintenance { } $maintClass = "MwSql"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/sqlite.inc b/maintenance/sqlite.inc index 16568ac7..08188cad 100644 --- a/maintenance/sqlite.inc +++ b/maintenance/sqlite.inc @@ -33,10 +33,7 @@ class Sqlite { * @return bool */ public static function isPresent() { - wfSuppressWarnings(); - $compiled = wfDl( 'pdo_sqlite' ); - wfRestoreWarnings(); - return $compiled; + return extension_loaded( 'pdo_sqlite' ); } /** @@ -73,7 +70,9 @@ class Sqlite { $tables = $db->query( "SELECT name FROM sqlite_master WHERE type='table'", __METHOD__ ); foreach ( $tables as $table ) { - if ( strpos( $table->name, 'sqlite_' ) === 0 ) continue; + if ( strpos( $table->name, 'sqlite_' ) === 0 ) { + continue; + } $columns = $db->query( "PRAGMA table_info({$table->name})", __METHOD__ ); foreach ( $columns as $col ) { @@ -89,4 +88,4 @@ class Sqlite { $db->close(); return true; } - }; +}; diff --git a/maintenance/sqlite.php b/maintenance/sqlite.php index 4085c59b..8a785245 100644 --- a/maintenance/sqlite.php +++ b/maintenance/sqlite.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that performs some operations specific to SQLite database backend. @@ -137,4 +137,4 @@ class SqliteMaintenance extends Maintenance { } $maintClass = "SqliteMaintenance"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/sqlite/archives/initial-indexes.sql b/maintenance/sqlite/archives/initial-indexes.sql index 73b008cc..1a59be5a 100644 --- a/maintenance/sqlite/archives/initial-indexes.sql +++ b/maintenance/sqlite/archives/initial-indexes.sql @@ -28,6 +28,8 @@ DROP TABLE IF EXISTS /*_*/interwiki_tmp; DROP TABLE IF EXISTS /*_*/page_restrictions_tmp; DROP TABLE IF EXISTS /*_*/protected_titles_tmp; DROP TABLE IF EXISTS /*_*/page_props_tmp; +DROP TABLE IF EXISTS /*_*/archive_tmp; +DROP TABLE IF EXISTS /*_*/externallinks_tmp; -------------------------------------------------------------------------------- -- Create new tables @@ -268,6 +270,47 @@ CREATE TABLE /*_*/page_props_tmp ( ); CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props_tmp (pp_page,pp_propname); +-- +-- Holding area for deleted articles, which may be viewed +-- or restored by admins through the Special:Undelete interface. +-- The fields generally correspond to the page, revision, and text +-- fields, with several caveats. +-- Cannot reasonably create views on this table, due to the presence of TEXT +-- columns. +CREATE TABLE /*$wgDBprefix*/archive_tmp ( + ar_id NOT NULL PRIMARY KEY clustered IDENTITY, + ar_namespace SMALLINT NOT NULL DEFAULT 0, + ar_title NVARCHAR(255) NOT NULL DEFAULT '', + ar_text NVARCHAR(MAX) NOT NULL, + ar_comment NVARCHAR(255) NOT NULL, + ar_user INT NULL REFERENCES /*$wgDBprefix*/[user](user_id) ON DELETE SET NULL, + ar_user_text NVARCHAR(255) NOT NULL, + ar_timestamp DATETIME NOT NULL DEFAULT GETDATE(), + ar_minor_edit BIT NOT NULL DEFAULT 0, + ar_flags NVARCHAR(255) NOT NULL, + ar_rev_id INT, + ar_text_id INT, + ar_deleted BIT NOT NULL DEFAULT 0, + ar_len INT DEFAULT NULL, + ar_page_id INT NULL, + ar_parent_id INT NULL +); +CREATE INDEX /*$wgDBprefix*/ar_name_title_timestamp ON /*$wgDBprefix*/archive_tmp(ar_namespace,ar_title,ar_timestamp); +CREATE INDEX /*$wgDBprefix*/ar_usertext_timestamp ON /*$wgDBprefix*/archive_tmp(ar_user_text,ar_timestamp); +CREATE INDEX /*$wgDBprefix*/ar_user_text ON /*$wgDBprefix*/archive_tmp(ar_user_text); + +-- +-- Track links to external URLs +-- IE >= 4 supports no more than 2083 characters in a URL +CREATE TABLE /*$wgDBprefix*/externallinks_tmp ( + el_id INT NOT NULL PRIMARY KEY clustered IDENTITY, + el_from INT NOT NULL DEFAULT '0', + el_to VARCHAR(2083) NOT NULL, + el_index VARCHAR(896) NOT NULL, +); +-- Maximum key length ON SQL Server is 900 bytes +CREATE INDEX /*$wgDBprefix*/externallinks_index ON /*$wgDBprefix*/externallinks_tmp(el_index); + -------------------------------------------------------------------------------- -- Populate the new tables using INSERT SELECT -------------------------------------------------------------------------------- @@ -290,6 +333,8 @@ INSERT OR IGNORE INTO /*_*/interwiki_tmp SELECT * FROM /*_*/interwiki; INSERT OR IGNORE INTO /*_*/page_restrictions_tmp SELECT * FROM /*_*/page_restrictions; INSERT OR IGNORE INTO /*_*/protected_titles_tmp SELECT * FROM /*_*/protected_titles; INSERT OR IGNORE INTO /*_*/page_props_tmp SELECT * FROM /*_*/page_props; +INSERT OR IGNORE INTO /*_*/archive_tmp SELECT * FROM /*_*/archive; +INSERT OR IGNORE INTO /*_*/externallinks_tmp SELECT * FROM /*_*/externallinks; -------------------------------------------------------------------------------- -- Do the table renames @@ -331,6 +376,10 @@ DROP TABLE /*_*/protected_titles; ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles; DROP TABLE /*_*/page_props; ALTER TABLE /*_*/page_props_tmp RENAME TO /*_*/page_props; +DROP TABLE /*_*/archive; +ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive; +DROP TABLE /*_*/externalllinks; +ALTER TABLE /*_*/externallinks_tmp RENAME TO /*_*/externallinks; -------------------------------------------------------------------------------- -- Drop and create tables with unique indexes but no valuable data diff --git a/maintenance/sqlite/archives/patch-archive-ar_id.sql b/maintenance/sqlite/archives/patch-archive-ar_id.sql new file mode 100644 index 00000000..00a9b071 --- /dev/null +++ b/maintenance/sqlite/archives/patch-archive-ar_id.sql @@ -0,0 +1,39 @@ +DROP TABLE IF EXISTS /*_*/archive_tmp; + +CREATE TABLE /*$wgDBprefix*/archive_tmp ( + ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, + ar_namespace int NOT NULL default 0, + ar_title varchar(255) binary NOT NULL default '', + ar_text mediumblob NOT NULL, + ar_comment tinyblob NOT NULL, + ar_user int unsigned NOT NULL default 0, + ar_user_text varchar(255) binary NOT NULL, + ar_timestamp binary(14) NOT NULL default '', + ar_minor_edit tinyint NOT NULL default 0, + ar_flags tinyblob NOT NULL, + ar_rev_id int unsigned, + ar_text_id int unsigned, + ar_deleted tinyint unsigned NOT NULL default 0, + ar_len int unsigned, + ar_page_id int unsigned, + ar_parent_id int unsigned default NULL, + ar_sha1 varbinary(32) NOT NULL default '', + ar_content_model varbinary(32) DEFAULT NULL, + ar_content_format varbinary(64) DEFAULT NULL +); + +INSERT OR IGNORE INTO /*_*/archive_tmp ( + ar_namespace, ar_title, ar_title, ar_text, ar_comment, ar_user, ar_user_text, ar_timestamp, + ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted, ar_len, ar_page_id, ar_parent_id ) + SELECT + ar_namespace, ar_title, ar_title, ar_text, ar_comment, ar_user, ar_user_text, ar_timestamp, + ar_minor_edit, ar_flags, ar_rev_id, ar_text_id, ar_deleted, ar_len, ar_page_id, ar_parent_id + FROM /*_*/archive; + +DROP TABLE /*_*/archive; + +ALTER TABLE /*_*/archive_tmp RENAME TO /*_*/archive; + +CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); +CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); +CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id); diff --git a/maintenance/sqlite/archives/patch-externallinks-el_id.sql b/maintenance/sqlite/archives/patch-externallinks-el_id.sql new file mode 100644 index 00000000..0aad4071 --- /dev/null +++ b/maintenance/sqlite/archives/patch-externallinks-el_id.sql @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS /*_*/externallinks_tmp; + +CREATE TABLE /*$wgDBprefix*/externallinks_tmp ( + el_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, + el_from int unsigned NOT NULL default 0, + el_to blob NOT NULL, + el_index blob NOT NULL +); + +INSERT OR IGNORE INTO /*_*/externallinks_tmp (el_from, el_to, el_index) SELECT + el_from, el_to, el_index FROM /*_*/externallinks; + +DROP TABLE /*_*/externallinks; + +ALTER TABLE /*_*/externallinks_tmp RENAME TO /*_*/externallinks; + +CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); +CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); +CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60));
\ No newline at end of file diff --git a/maintenance/sqlite/archives/patch-kill-iwl_pft.sql b/maintenance/sqlite/archives/patch-kill-iwl_pft.sql deleted file mode 100644 index 8fc4b5cd..00000000 --- a/maintenance/sqlite/archives/patch-kill-iwl_pft.sql +++ /dev/null @@ -1,7 +0,0 @@ --- --- Kill the old iwl_prefix_from_title index, which may be present on some --- installs if they ran update.php between it being added and being renamed --- - -DROP INDEX IF EXISTS /*i*/iwl_prefix; - diff --git a/maintenance/sqlite/archives/patch-rename-iwl_prefix.sql b/maintenance/sqlite/archives/patch-rename-iwl_prefix.sql index fd4c9ec7..6d5b1bfa 100644 --- a/maintenance/sqlite/archives/patch-rename-iwl_prefix.sql +++ b/maintenance/sqlite/archives/patch-rename-iwl_prefix.sql @@ -2,4 +2,4 @@ -- Recreates the iwl_prefix for the iwlinks table -- DROP INDEX IF EXISTS /*i*/iwl_prefix; -CREATE INDEX IF NOT EXISTS /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title); +CREATE INDEX IF NOT EXISTS /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); diff --git a/maintenance/storage/checkStorage.php b/maintenance/storage/checkStorage.php index fd9393f2..03dc113a 100644 --- a/maintenance/storage/checkStorage.php +++ b/maintenance/storage/checkStorage.php @@ -22,7 +22,7 @@ */ if ( !defined( 'MEDIAWIKI' ) ) { - require_once( __DIR__ . '/../commandLine.inc' ); + require_once __DIR__ . '/../commandLine.inc'; $cs = new CheckStorage; $fix = isset( $options['fix'] ); @@ -75,7 +75,7 @@ class CheckStorage { 'fixable' => array(), ); - for ( $chunkStart = 1 ; $chunkStart < $maxRevId; $chunkStart += $chunkSize ) { + for ( $chunkStart = 1; $chunkStart < $maxRevId; $chunkStart += $chunkSize ) { $chunkEnd = $chunkStart + $chunkSize - 1; // print "$chunkStart of $maxRevId\n"; @@ -443,18 +443,26 @@ class CheckStorage { function importRevision( &$revision, &$importer ) { $id = $revision->getID(); - $text = $revision->getText(); + $content = $revision->getContent( Revision::RAW ); + $id = $id ? $id : ''; + + if ( $content === null ) { + echo "Revision $id is broken, we have no content available\n"; + return; + } + + $text = $content->serialize(); if ( $text === '' ) { // This is what happens if the revision was broken at the time the // dump was made. Unfortunately, it also happens if the revision was // legitimately blank, so there's no way to tell the difference. To // be safe, we'll skip it and leave it broken - $id = $id ? $id : ''; + echo "Revision $id is blank in the dump, may have been broken before export\n"; return; } - if ( !$id ) { + if ( !$id ) { // No ID, can't import echo "No id tag in revision, can't import\n"; return; diff --git a/maintenance/storage/compressOld.php b/maintenance/storage/compressOld.php index d6362834..8cb55487 100644 --- a/maintenance/storage/compressOld.php +++ b/maintenance/storage/compressOld.php @@ -41,7 +41,7 @@ * @ingroup Maintenance ExternalStorage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that compress the text of a wiki. @@ -53,7 +53,7 @@ class CompressOld extends Maintenance { * @todo document */ const LS_INDIVIDUAL = 0; - const LS_CHUNKED = 1; + const LS_CHUNKED = 1; public function __construct() { parent::__construct(); @@ -113,9 +113,9 @@ class CompressOld extends Maintenance { $this->output( "Starting from old_id $start...\n" ); $dbw = wfGetDB( DB_MASTER ); do { - $res = $dbw->select( 'text', array( 'old_id','old_flags','old_text' ), + $res = $dbw->select( 'text', array( 'old_id', 'old_flags', 'old_text' ), "old_id>=$start", __METHOD__, array( 'ORDER BY' => 'old_id', 'LIMIT' => $chunksize, 'FOR UPDATE' ) ); - if( $res->numRows() == 0 ) { + if ( $res->numRows() == 0 ) { break; } $last = $start; @@ -126,7 +126,7 @@ class CompressOld extends Maintenance { } $start = $last + 1; # Deletion may leave long empty stretches $this->output( "$start...\n" ); - } while( true ); + } while ( true ); } /** @@ -223,7 +223,7 @@ class CompressOld extends Maintenance { } $conds[] = "rev_timestamp>'" . $beginDate . "'"; } - if ( $endDate ) { + if ( $endDate ) { if ( !preg_match( '/^\d{14}$/', $endDate ) ) { $this->error( "Invalid end date \"$endDate\"\n" ); return false; @@ -254,8 +254,8 @@ class CompressOld extends Maintenance { # Get the page row $pageRes = $dbr->select( 'page', - array('page_id', 'page_namespace', 'page_title','page_latest'), - $pageConds + array('page_id' => $pageId), __METHOD__ ); + array( 'page_id', 'page_namespace', 'page_title', 'page_latest' ), + $pageConds + array( 'page_id' => $pageId ), __METHOD__ ); if ( $pageRes->numRows() == 0 ) { continue; } @@ -282,7 +282,7 @@ class CompressOld extends Maintenance { $revs[] = $revRow; } - if ( count( $revs ) < 2) { + if ( count( $revs ) < 2 ) { # No revisions matching, no further processing $this->output( "\n" ); continue; @@ -351,21 +351,22 @@ class CompressOld extends Maintenance { if ( $extdb != "" ) { # Move blob objects to External Storage $stored = $storeObj->store( $extdb, serialize( $chunk )); - if ($stored === false) { - $this->error( "Unable to store object" ); + if ( $stored === false ) { + $this->error( "Unable to store object" ); return false; } # Store External Storage URLs instead of Stub placeholders - foreach ($stubs as $stub) { - if ($stub===false) + foreach ( $stubs as $stub ) { + if ( $stub === false ) { continue; + } # $stored should provide base path to a BLOB - $url = $stored."/".$stub->getHash(); + $url = $stored . "/" . $stub->getHash(); $dbw->update( 'text', array( /* SET */ 'old_text' => $url, 'old_flags' => 'external,utf-8', - ), array ( /* WHERE */ + ), array( /* WHERE */ 'old_id' => $stub->getReferrer(), ) ); @@ -387,7 +388,7 @@ class CompressOld extends Maintenance { if ( $stubs[$j] !== false && $revs[$i + $j]->rev_text_id != $primaryOldid ) { $dbw->update( 'text', array( /* SET */ - 'old_text' => serialize($stubs[$j]), + 'old_text' => serialize( $stubs[$j] ), 'old_flags' => 'object,utf-8', ), array( /* WHERE */ 'old_id' => $revs[$i + $j]->rev_text_id @@ -411,4 +412,4 @@ class CompressOld extends Maintenance { } $maintClass = 'CompressOld'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/storage/dumpRev.php b/maintenance/storage/dumpRev.php index 39f08f9d..f12bbd1b 100644 --- a/maintenance/storage/dumpRev.php +++ b/maintenance/storage/dumpRev.php @@ -21,7 +21,7 @@ * @ingroup Maintenance ExternalStorage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that gets the text of a revision, @@ -46,7 +46,7 @@ class DumpRev extends Maintenance { $this->error( "Row not found", true ); } - $flags = explode( ',', $row->old_flags ); + $flags = explode( ',', $row->old_flags ); $text = $row->old_text; if ( in_array( 'external', $flags ) ) { $this->output( "External $text\n" ); @@ -85,4 +85,4 @@ class DumpRev extends Maintenance { } $maintClass = "DumpRev"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/storage/fixBug20757.php b/maintenance/storage/fixBug20757.php index 30cbcf1a..101aa068 100644 --- a/maintenance/storage/fixBug20757.php +++ b/maintenance/storage/fixBug20757.php @@ -21,7 +21,7 @@ * @ingroup Maintenance ExternalStorage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script to fix bug 20757. @@ -348,4 +348,4 @@ class FixBug20757 extends Maintenance { } $maintClass = 'FixBug20757'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/storage/moveToExternal.php b/maintenance/storage/moveToExternal.php index 1049e0cc..348fb773 100644 --- a/maintenance/storage/moveToExternal.php +++ b/maintenance/storage/moveToExternal.php @@ -24,9 +24,9 @@ define( 'REPORTING_INTERVAL', 1 ); if ( !defined( 'MEDIAWIKI' ) ) { - require_once( __DIR__ . '/../commandLine.inc' ); - require_once( __DIR__ . '/../../includes/externalstore/ExternalStoreDB.php' ); - require_once( 'resolveStubs.php' ); + require_once __DIR__ . '/../commandLine.inc'; + require_once __DIR__ . '/../../includes/externalstore/ExternalStoreDB.php'; + require_once 'resolveStubs.php'; $fname = 'moveToExternal'; diff --git a/maintenance/storage/orphanStats.php b/maintenance/storage/orphanStats.php index 4e246287..1df1501e 100644 --- a/maintenance/storage/orphanStats.php +++ b/maintenance/storage/orphanStats.php @@ -21,7 +21,7 @@ * @ingroup Maintenance ExternalStorage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; /** * Maintenance script that shows some statistics on the blob_orphans table, @@ -74,4 +74,4 @@ class OrphanStats extends Maintenance { } $maintClass = "OrphanStats"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/storage/recompressTracked.php b/maintenance/storage/recompressTracked.php index 030a147e..b2663165 100644 --- a/maintenance/storage/recompressTracked.php +++ b/maintenance/storage/recompressTracked.php @@ -23,7 +23,7 @@ */ $optionsWithArgs = RecompressTracked::getOptionsWithArgs(); -require( __DIR__ . '/../commandLine.inc' ); +require __DIR__ . '/../commandLine.inc'; if ( count( $args ) < 1 ) { echo "Usage: php recompressTracked.php [options] <cluster> [... <cluster>...] @@ -279,7 +279,7 @@ class RecompressTracked { */ function dispatchToSlave( $slaveId, $args ) { $args = (array)$args; - $cmd = implode( ' ', $args ); + $cmd = implode( ' ', $args ); fwrite( $this->slavePipes[$slaveId], "$cmd\n" ); } diff --git a/maintenance/storage/resolveStubs.php b/maintenance/storage/resolveStubs.php index 414eab81..e47d6407 100644 --- a/maintenance/storage/resolveStubs.php +++ b/maintenance/storage/resolveStubs.php @@ -27,7 +27,7 @@ define( 'REPORTING_INTERVAL', 100 ); if ( !defined( 'MEDIAWIKI' ) ) { $optionsWithArgs = array( 'm' ); - require_once( __DIR__ . '/../commandLine.inc' ); + require_once __DIR__ . '/../commandLine.inc'; resolveStubs(); } diff --git a/maintenance/storage/storageTypeStats.php b/maintenance/storage/storageTypeStats.php index 3187c318..e33057f6 100644 --- a/maintenance/storage/storageTypeStats.php +++ b/maintenance/storage/storageTypeStats.php @@ -19,7 +19,7 @@ * @ingroup Maintenance ExternalStorage */ -require_once( __DIR__ . '/../Maintenance.php' ); +require_once __DIR__ . '/../Maintenance.php'; class StorageTypeStats extends Maintenance { function execute() { @@ -112,4 +112,4 @@ SQL; } $maintClass = 'StorageTypeStats'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/storage/testCompression.php b/maintenance/storage/testCompression.php index e13e1b10..fdc28d9b 100644 --- a/maintenance/storage/testCompression.php +++ b/maintenance/storage/testCompression.php @@ -22,7 +22,7 @@ */ $optionsWithArgs = array( 'start', 'limit', 'type' ); -require( __DIR__ . '/../commandLine.inc' ); +require __DIR__ . '/../commandLine.inc'; if ( !isset( $args[0] ) ) { echo "Usage: php testCompression.php [--type=<type>] [--start=<start-date>] [--limit=<num-revs>] <page-title>\n"; diff --git a/maintenance/storage/trackBlobs.php b/maintenance/storage/trackBlobs.php index 2f3c8c6a..7857dd95 100644 --- a/maintenance/storage/trackBlobs.php +++ b/maintenance/storage/trackBlobs.php @@ -22,7 +22,7 @@ * @see wfWaitForSlaves() */ -require( __DIR__ . '/../commandLine.inc' ); +require __DIR__ . '/../commandLine.inc'; if ( count( $args ) < 1 ) { diff --git a/maintenance/syncFileBackend.php b/maintenance/syncFileBackend.php index 158019b7..f0be709f 100644 --- a/maintenance/syncFileBackend.php +++ b/maintenance/syncFileBackend.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that syncs one file backend to another based on @@ -40,6 +40,7 @@ class SyncFileBackend extends Maintenance { $this->addOption( 'posdir', 'Directory to read/record journal positions', false, true ); $this->addOption( 'posdump', 'Just dump current journal position into the position dir.' ); $this->addOption( 'postime', 'For position dumps, get the ID at this time', false, true ); + $this->addOption( 'backoff', 'Stop at entries younger than this age (sec).', false, true ); $this->addOption( 'verbose', 'Verbose mode', false, false, 'v' ); $this->setBatchSize( 50 ); } @@ -88,7 +89,13 @@ class SyncFileBackend extends Maintenance { } else { $startFromPosFile = false; } - $end = $this->getOption( 'end', INF ); + + if ( $this->hasOption( 'backoff' ) ) { + $time = time() - $this->getOption( 'backoff', 0 ); + $end = (int)$src->getJournal()->getPositionAtTime( $time ); + } else { + $end = $this->getOption( 'end', INF ); + } $this->output( "Synchronizing backend '{$dst->getName()}' to '{$src->getName()}'...\n" ); $this->output( "Starting journal position is $start.\n" ); @@ -289,4 +296,4 @@ class SyncFileBackend extends Maintenance { } $maintClass = "SyncFileBackend"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 72b4eb6c..de92ef53 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -380,6 +380,8 @@ CREATE TABLE /*_*/text ( -- fields, with several caveats. -- CREATE TABLE /*_*/archive ( + -- Primary key + ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, ar_namespace int NOT NULL default 0, ar_title varchar(255) binary NOT NULL default '', @@ -445,7 +447,6 @@ CREATE TABLE /*_*/archive ( -- content format, see CONTENT_FORMAT_XXX constants ar_content_format varbinary(64) DEFAULT NULL - ) /*$wgDBTableOptions*/; CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); @@ -602,6 +603,9 @@ CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); -- Track links to external URLs -- CREATE TABLE /*_*/externallinks ( + -- Primary key + el_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, + -- page_id of the referring page el_from int unsigned NOT NULL default 0, @@ -626,21 +630,6 @@ CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); - --- --- Track external user accounts, if ExternalAuth is used --- -CREATE TABLE /*_*/external_user ( - -- Foreign key to user_id - eu_local_id int unsigned NOT NULL PRIMARY KEY, - - -- Some opaque identifier provided by the external database - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; - -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); - - -- -- Track interlanguage links -- @@ -674,7 +663,8 @@ CREATE TABLE /*_*/iwlinks ( ) /*$wgDBTableOptions*/; CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE UNIQUE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); +CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); +CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title); -- @@ -774,6 +764,9 @@ CREATE TABLE /*_*/ipblocks ( -- Start and end of an address range, in hexadecimal -- Size chosen to allow IPv6 + -- FIXME: these fields were originally blank for single-IP blocks, + -- but now they are populated. No migration was ever done. They + -- should be fixed to be blank again for such blocks (bug 49504). ipb_range_start tinyblob NOT NULL, ipb_range_end tinyblob NOT NULL, @@ -821,7 +814,7 @@ CREATE TABLE /*_*/image ( img_width int NOT NULL default 0, img_height int NOT NULL default 0, - -- Extracted EXIF metadata stored as a serialized PHP array. + -- Extracted Exif metadata stored as a serialized PHP array. img_metadata mediumblob NOT NULL, -- For images, bits per pixel if known. @@ -1066,7 +1059,7 @@ CREATE TABLE /*_*/recentchanges ( -- rev_id of the prior revision, for generating diff links. rc_last_oldid int unsigned NOT NULL default 0, - -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG) + -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG,RC_EXTERNAL) rc_type tinyint unsigned NOT NULL default 0, -- If the Recent Changes Patrol option is enabled, @@ -1087,7 +1080,7 @@ CREATE TABLE /*_*/recentchanges ( -- Visibility of recent changes items, bitfield rc_deleted tinyint unsigned NOT NULL default 0, - -- Value corresonding to log_id, specific log entries + -- Value corresponding to log_id, specific log entries rc_logid int unsigned NOT NULL default 0, -- Store log type info here, or null rc_log_type varbinary(255) NULL default NULL, @@ -1143,7 +1136,7 @@ CREATE TABLE /*_*/searchindex ( -- Munged version of body text si_text mediumtext NOT NULL -) ENGINE=MyISAM; +) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); CREATE FULLTEXT INDEX /*i*/si_title ON /*_*/searchindex (si_title); diff --git a/maintenance/tidyUpBug37714.php b/maintenance/tidyUpBug37714.php new file mode 100644 index 00000000..1ad9c7ee --- /dev/null +++ b/maintenance/tidyUpBug37714.php @@ -0,0 +1,49 @@ +<?php +require_once __DIR__ . '/Maintenance.php'; + +/** + * Fixes all rows affected by https://bugzilla.wikimedia.org/show_bug.cgi?id=37714 + */ +class TidyUpBug37714 extends Maintenance { + public function execute() { + // Search for all log entries which are about changing the visability of other log entries. + $result = wfGetDB( DB_SLAVE )->select( + 'logging', + array( 'log_id', 'log_params' ), + array( + 'log_type' => array( 'suppress', 'delete' ), + 'log_action' => 'event', + 'log_namespace' => NS_SPECIAL, + 'log_title' => SpecialPage::getTitleFor( 'Log' )->getText() + ), + __METHOD__ + ); + + foreach ( $result as $row ) { + $paramLines = explode( "\n", $row->log_params ); + $ids = explode( ',', $paramLines[0] ); // Array dereferencing is PHP >= 5.4 :( + $result = wfGetDB( DB_SLAVE )->select( // Work out what log entries were changed here. + 'logging', + 'log_type', + array( 'log_id' => $ids ), + __METHOD__, + 'DISTINCT' + ); + if ( $result->numRows() === 1 ) { + // If there's only one type, the target title can be set to include it. + $logTitle = SpecialPage::getTitleFor( 'Log', $result->current()->log_type )->getText(); + $this->output( 'Set log_title to "' . $logTitle . '" for log entry ' . $row->log_id . ".\n" ); + wfGetDB( DB_MASTER )->update( + 'logging', + array( 'log_title' => $logTitle ), + array( 'log_id' => $row->log_id ), + __METHOD__ + ); + wfWaitForSlaves(); + } + } + } +} + +$maintClass = 'TidyUpBug37714'; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/undelete.php b/maintenance/undelete.php index ea8b0c4b..c890c69b 100644 --- a/maintenance/undelete.php +++ b/maintenance/undelete.php @@ -21,7 +21,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; class Undelete extends Maintenance { public function __construct() { @@ -55,4 +55,4 @@ class Undelete extends Maintenance { } $maintClass = "Undelete"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/update.php b/maintenance/update.php index f69a9b0d..378217fd 100644 --- a/maintenance/update.php +++ b/maintenance/update.php @@ -26,12 +26,12 @@ */ if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.3.2' ) < 0 ) ) { - require( dirname( __FILE__ ) . '/../includes/PHPVersionError.php' ); + require dirname( __FILE__ ) . '/../includes/PHPVersionError.php'; wfPHPVersionError( 'cli' ); } $wgUseMasterForMaintenance = true; -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to run database schema updates. @@ -83,7 +83,7 @@ class UpdateMediaWiki extends Maintenance { function execute() { global $wgVersion, $wgTitle, $wgLang, $wgAllowSchemaUpdates; - if( !$wgAllowSchemaUpdates && !( $this->hasOption( 'force' ) || $this->hasOption( 'schema' ) || $this->hasOption( 'noschema' ) ) ) { + if ( !$wgAllowSchemaUpdates && !( $this->hasOption( 'force' ) || $this->hasOption( 'schema' ) || $this->hasOption( 'noschema' ) ) ) { $this->error( "Do not run update.php on this wiki. If you're seeing this you should\n" . "probably ask for some help in performing your schema updates or use\n" . "the --noschema and --schema options to get an SQL file for someone\n" @@ -92,12 +92,12 @@ class UpdateMediaWiki extends Maintenance { } $this->fileHandle = null; - if( substr( $this->getOption( 'schema' ), 0, 2 ) === "--" ) { + if ( substr( $this->getOption( 'schema' ), 0, 2 ) === "--" ) { $this->error( "The --schema option requires a file as an argument.\n", true ); - } else if( $this->hasOption( 'schema' ) ) { + } elseif ( $this->hasOption( 'schema' ) ) { $file = $this->getOption( 'schema' ); $this->fileHandle = fopen( $file, "w" ); - if( $this->fileHandle === false ) { + if ( $this->fileHandle === false ) { $err = error_get_last(); $this->error( "Problem opening the schema file for writing: $file\n\t{$err['message']}", true ); } @@ -122,7 +122,7 @@ class UpdateMediaWiki extends Maintenance { $db = wfGetDB( DB_MASTER ); $this->output( "Going to run database updates for " . wfWikiID() . "\n" ); - if( $db->getType() === 'sqlite' ) { + if ( $db->getType() === 'sqlite' ) { $this->output( "Using SQLite file: '{$db->mDatabaseFile}'\n" ); } $this->output( "Depending on the size of your database this may take a while!\n" ); @@ -135,21 +135,17 @@ class UpdateMediaWiki extends Maintenance { $shared = $this->hasOption( 'doshared' ); $updates = array( 'core', 'extensions' ); - if( !$this->hasOption('schema') ) { - if( $this->hasOption('noschema') ) { + if ( !$this->hasOption( 'schema' ) ) { + if ( $this->hasOption( 'noschema' ) ) { $updates[] = 'noschema'; } $updates[] = 'stats'; - - if( !$this->hasOption('nopurge') ) { - $updates[] = 'purge'; - } } $updater = DatabaseUpdater::newForDb( $db, $shared, $this ); $updater->doUpdates( $updates ); - foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { + foreach ( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { $child = $this->runChild( $maint ); // LoggedUpdateMaintenance is checking the updatelog itself @@ -159,14 +155,13 @@ class UpdateMediaWiki extends Maintenance { continue; } - $child = $this->runChild( $maint ); $child->execute(); if ( !$isLoggedUpdate ) { $updater->insertUpdateRow( $maint ); } } - if( !$this->hasOption('nopurge') ) { + if ( !$this->hasOption( 'nopurge' ) ) { $updater->purgeCache(); } @@ -189,4 +184,4 @@ class UpdateMediaWiki extends Maintenance { } $maintClass = 'UpdateMediaWiki'; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateArticleCount.php b/maintenance/updateArticleCount.php index 4d49dd2d..7964a21f 100644 --- a/maintenance/updateArticleCount.php +++ b/maintenance/updateArticleCount.php @@ -23,7 +23,7 @@ * @author Rob Church <robchur@gmail.com> */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to provide a better count of the number of articles @@ -58,4 +58,4 @@ class UpdateArticleCount extends Maintenance { } $maintClass = "UpdateArticleCount"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateCollation.php b/maintenance/updateCollation.php index a76a1ee6..964b3138 100644 --- a/maintenance/updateCollation.php +++ b/maintenance/updateCollation.php @@ -26,7 +26,7 @@ #$optionsWithArgs = array( 'begin', 'max-slave-lag' ); -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that will find all rows in the categorylinks table @@ -82,6 +82,10 @@ TEXT; $collation = Collation::singleton(); } + // Collation sanity check: in some cases the constructor will work, + // but this will raise an exception, breaking all category pages + $collation->getFirstLetter( 'MediaWiki' ); + $options = array( 'LIMIT' => self::BATCH_SIZE, 'ORDER BY' => 'cl_to, cl_type, cl_from', @@ -303,4 +307,4 @@ TEXT; } $maintClass = "UpdateCollation"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateDoubleWidthSearch.php b/maintenance/updateDoubleWidthSearch.php index dc7398ad..41988d1b 100644 --- a/maintenance/updateDoubleWidthSearch.php +++ b/maintenance/updateDoubleWidthSearch.php @@ -23,7 +23,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to normalize double-byte latin UTF-8 characters. @@ -72,4 +72,4 @@ class UpdateDoubleWidthSearch extends Maintenance { } $maintClass = "UpdateDoubleWidthSearch"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateRestrictions.php b/maintenance/updateRestrictions.php index 8699dc26..175447e7 100644 --- a/maintenance/updateRestrictions.php +++ b/maintenance/updateRestrictions.php @@ -24,7 +24,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script that updates page_restrictions table from @@ -114,4 +114,4 @@ class UpdateRestrictions extends Maintenance { } $maintClass = "UpdateRestrictions"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateSearchIndex.php b/maintenance/updateSearchIndex.php index ac784847..0691bee8 100644 --- a/maintenance/updateSearchIndex.php +++ b/maintenance/updateSearchIndex.php @@ -28,7 +28,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script for periodic off-peak updating of the search index. @@ -60,7 +60,7 @@ class UpdateSearchIndex extends Maintenance { # We can safely delete the file when we're done though. $start = file_get_contents( 'searchUpdate.pos' ); unlink( 'searchUpdate.pos' ); - } elseif( is_readable( $posFile ) ) { + } elseif ( is_readable( $posFile ) ) { $start = file_get_contents( $posFile ); } else { $start = wfTimestamp( TS_MW, time() - 86400 ); @@ -97,9 +97,8 @@ class UpdateSearchIndex extends Maintenance { $page = $dbw->tableName( 'page' ); $sql = "SELECT rc_cur_id FROM $recentchanges - JOIN $page ON rc_cur_id=page_id AND rc_this_oldid=page_latest - WHERE rc_type != " . RC_LOG . " AND rc_timestamp BETWEEN '$start' AND '$end' - "; + JOIN $page ON rc_cur_id=page_id AND rc_this_oldid=page_latest + WHERE rc_type != " . RC_LOG . " AND rc_timestamp BETWEEN '$start' AND '$end'"; $res = $dbw->query( $sql, __METHOD__ ); $this->updateSearchIndex( $maxLockTime, array( $this, 'searchIndexUpdateCallback' ), $dbw, $res ); @@ -113,4 +112,4 @@ class UpdateSearchIndex extends Maintenance { } $maintClass = "UpdateSearchIndex"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/updateSpecialPages.php b/maintenance/updateSpecialPages.php index f92f67aa..3432cb20 100644 --- a/maintenance/updateSpecialPages.php +++ b/maintenance/updateSpecialPages.php @@ -22,7 +22,7 @@ * @ingroup Maintenance */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to update cached special pages. @@ -33,41 +33,22 @@ class UpdateSpecialPages extends Maintenance { public function __construct() { parent::__construct(); $this->addOption( 'list', 'List special page names' ); - $this->addOption( 'only', 'Only update "page". Ex: --only=BrokenRedirects', false, true ); + $this->addOption( 'only', 'Only update "page"; case sensitive, ' . + 'check correct case by calling this script with --list or on ' . + 'includes/QueryPage.php. Ex: --only=BrokenRedirects', false, true ); $this->addOption( 'override', 'Also update pages that have updates disabled' ); } public function execute() { - global $IP, $wgSpecialPageCacheUpdates, $wgQueryPages, $wgQueryCacheLimit, $wgDisableQueryPageUpdate; + global $IP, $wgQueryPages, $wgQueryCacheLimit, $wgDisableQueryPageUpdate; - $dbw = wfGetDB( DB_MASTER ); - - foreach ( $wgSpecialPageCacheUpdates as $special => $call ) { - if ( !is_callable( $call ) ) { - $this->error( "Uncallable function $call!" ); - continue; - } - $this->output( sprintf( '%-30s ', $special ) ); - $t1 = explode( ' ', microtime() ); - call_user_func( $call, $dbw ); - $t2 = explode( ' ', microtime() ); - $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] ); - $hours = intval( $elapsed / 3600 ); - $minutes = intval( $elapsed % 3600 / 60 ); - $seconds = $elapsed - $hours * 3600 - $minutes * 60; - if ( $hours ) { - $this->output( $hours . 'h ' ); - } - if ( $minutes ) { - $this->output( $minutes . 'm ' ); - } - $this->output( sprintf( "completed in %.2fs\n", $seconds ) ); - # Wait for the slave to catch up - wfWaitForSlaves(); + if ( !$this->hasOption( 'list' ) && !$this->hasOption( 'only' ) ) { + $this->doSpecialPageCacheUpdates(); } + $dbw = wfGetDB( DB_MASTER ); // This is needed to initialise $wgQueryPages - require_once( "$IP/includes/QueryPage.php" ); + require_once "$IP/includes/QueryPage.php"; foreach ( $wgQueryPages as $page ) { list( $class, $special ) = $page; @@ -94,13 +75,13 @@ class UpdateSpecialPages extends Maintenance { } else { if ( !class_exists( $class ) ) { $file = $specialObj->getFile(); - require_once( $file ); + require_once $file; } $queryPage = new $class; } if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $queryPage->getName() ) { - $this->output( sprintf( '%-30s ', $special ) ); + $this->output( sprintf( '%-30s ', $special ) ); if ( $queryPage->isExpensive() ) { $t1 = explode( ' ', microtime() ); # Do the query @@ -124,7 +105,7 @@ class UpdateSpecialPages extends Maintenance { $this->output( sprintf( "%.2fs\n", $seconds ) ); } # Reopen any connections that have closed - if ( !wfGetLB()->pingAll() ) { + if ( !wfGetLB()->pingAll() ) { $this->output( "\n" ); do { $this->error( "Connection failed, reconnecting in 10 seconds..." ); @@ -140,10 +121,42 @@ class UpdateSpecialPages extends Maintenance { } else { $this->output( "cheap, skipped\n" ); } + if ( $this->hasOption( 'only' ) ) { + break; + } } } } + + public function doSpecialPageCacheUpdates() { + global $wgSpecialPageCacheUpdates; + $dbw = wfGetDB( DB_MASTER ); + + foreach ( $wgSpecialPageCacheUpdates as $special => $call ) { + if ( !is_callable( $call ) ) { + $this->error( "Uncallable function $call!" ); + continue; + } + $this->output( sprintf( '%-30s ', $special ) ); + $t1 = explode( ' ', microtime() ); + call_user_func( $call, $dbw ); + $t2 = explode( ' ', microtime() ); + $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] ); + $hours = intval( $elapsed / 3600 ); + $minutes = intval( $elapsed % 3600 / 60 ); + $seconds = $elapsed - $hours * 3600 - $minutes * 60; + if ( $hours ) { + $this->output( $hours . 'h ' ); + } + if ( $minutes ) { + $this->output( $minutes . 'm ' ); + } + $this->output( sprintf( "completed in %.2fs\n", $seconds ) ); + # Wait for the slave to catch up + wfWaitForSlaves(); + } + } } $maintClass = "UpdateSpecialPages"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/userDupes.inc b/maintenance/userDupes.inc index be45a111..8bd80c97 100644 --- a/maintenance/userDupes.inc +++ b/maintenance/userDupes.inc @@ -1,6 +1,6 @@ <?php /** - * Helper class for update.php and upgrade1_5.php. + * Helper class for update.php. * * Copyright © 2005 Brion Vibber <brion@pobox.com> * http://www.mediawiki.org/ @@ -112,9 +112,9 @@ class UserDupes { $count = count( $dupes ); $this->out( "Found $count accounts with duplicate records on " . wfWikiID() . ".\n" ); - $this->trimmed = 0; + $this->trimmed = 0; $this->reassigned = 0; - $this->failed = 0; + $this->failed = 0; foreach ( $dupes as $name ) { $this->examine( $name, $doDelete ); } @@ -158,11 +158,7 @@ class UserDupes { * @access private */ function lock() { - if ( $this->newSchema() ) { - $set = array( 'user', 'revision' ); - } else { - $set = array( 'user', 'cur', 'old' ); - } + $set = array( 'user', 'revision' ); $names = array_map( array( $this, 'lockTable' ), $set ); $tables = implode( ',', $names ); @@ -174,14 +170,6 @@ class UserDupes { } /** - * @return bool - * @access private - */ - function newSchema() { - return MWInit::classExists( 'Revision' ); - } - - /** * @access private */ function unlock() { @@ -223,7 +211,7 @@ class UserDupes { __METHOD__ ); $firstRow = $this->db->fetchObject( $result ); - $firstId = $firstRow->user_id; + $firstId = $firstRow->user_id; $this->out( "Record that will be used for '$name' is user_id=$firstId\n" ); foreach ( $result as $row ) { @@ -266,27 +254,10 @@ class UserDupes { * @access private */ function editCount( $userid ) { - if ( $this->newSchema() ) { - return $this->editCountOn( 'revision', 'rev_user', $userid ); - } else { - return $this->editCountOn( 'cur', 'cur_user', $userid ) + - $this->editCountOn( 'old', 'old_user', $userid ); - } - } - - /** - * Count the number of hits on a given table for this account. - * @param $table string - * @param $field string - * @param $userid int - * @return int - * @access private - */ - function editCountOn( $table, $field, $userid ) { return intval( $this->db->selectField( - $table, + 'revision', 'COUNT(*)', - array( $field => $userid ), + array( 'rev_user' => $userid ), __METHOD__ ) ); } @@ -296,26 +267,10 @@ class UserDupes { * @access private */ function reassignEdits( $from, $to ) { - $set = $this->newSchema() - ? array( 'revision' => 'rev_user' ) - : array( 'cur' => 'cur_user', 'old' => 'old_user' ); - foreach ( $set as $table => $field ) { - $this->reassignEditsOn( $table, $field, $from, $to ); - } - } - - /** - * @param $table string - * @param $field string - * @param $from int - * @param $to int - * @access private - */ - function reassignEditsOn( $table, $field, $from, $to ) { - $this->out( "reassigning on $table... " ); - $this->db->update( $table, - array( $field => $to ), - array( $field => $from ), + $this->out( 'reassigning... ' ); + $this->db->update( 'revision', + array( 'rev_user' => $to ), + array( 'rev_user' => $from ), __METHOD__ ); $this->out( "ok. " ); } diff --git a/maintenance/userOptions.inc b/maintenance/userOptions.inc index cbe6b057..51da80d3 100644 --- a/maintenance/userOptions.inc +++ b/maintenance/userOptions.inc @@ -25,7 +25,7 @@ $options = array( 'list', 'nowarn', 'quiet', 'usage', 'dry' ); $optionsWithArgs = array( 'old', 'new' ); -require_once( __DIR__ . '/commandLine.inc' ); +require_once __DIR__ . '/commandLine.inc'; /** * @ingroup Maintenance @@ -38,7 +38,7 @@ class userOptions { public $mOldValue; public $mNewValue; - private $mMode, $mReady ; + private $mMode, $mReady; /** Constructor. Will show usage and exit if script options are not correct */ function __construct( $opts, $args ) { @@ -60,9 +60,9 @@ class userOptions { */ private function checkOpts( $opts, $args ) { // The three possible ways to run the script: - $list = isset( $opts['list'] ); - $usage = isset( $opts['usage'] ) && ( count( $args ) <= 1 ); - $change = isset( $opts['old'] ) && isset( $opts['new'] ) && ( count( $args ) <= 1 ) ; + $list = isset( $opts['list'] ); + $usage = isset( $opts['usage'] ) && ( count( $args ) <= 1 ); + $change = isset( $opts['old'] ) && isset( $opts['new'] ) && ( count( $args ) <= 1 ); // We want only one of them $isValid = ( ( $list + $usage + $change ) == 1 ); @@ -82,18 +82,18 @@ class userOptions { $this->mQuick = isset( $opts['nowarn'] ); $this->mQuiet = isset( $opts['quiet'] ); - $this->mDry = isset( $opts['dry'] ); + $this->mDry = isset( $opts['dry'] ); // Set object properties, specially 'mMode' used by run() if ( isset( $opts['list'] ) ) { - $this->mMode = 'LISTER' ; + $this->mMode = 'LISTER'; } elseif ( isset( $opts['usage'] ) ) { - $this->mMode = 'USAGER' ; - $this->mAnOption = isset( $args[0] ) ? $args[0] : false ; + $this->mMode = 'USAGER'; + $this->mAnOption = isset( $args[0] ) ? $args[0] : false; } elseif ( isset( $opts['old'] ) && isset( $opts['new'] ) ) { - $this->mMode = 'CHANGER' ; - $this->mOldValue = $opts['old'] ; - $this->mNewValue = $opts['new'] ; + $this->mMode = 'CHANGER'; + $this->mOldValue = $opts['old']; + $this->mNewValue = $opts['new']; $this->mAnOption = $args[0]; } else { die( "There is a bug in the software, this should never happen\n" ); @@ -212,7 +212,9 @@ class userOptions { if ( !$this->mDry ) { $user->saveSettings(); } - if ( !$this->mQuiet ) { print " OK\n"; } + if ( !$this->mQuiet ) { + print " OK\n"; + } } elseif ( !$this->mQuiet ) { print "Not changing '$username' using <{$this->mAnOption}> = '$curValue'\n"; diff --git a/maintenance/userOptions.php b/maintenance/userOptions.php index 1e1f24b5..e0de3574 100644 --- a/maintenance/userOptions.php +++ b/maintenance/userOptions.php @@ -25,7 +25,7 @@ */ // This is a command line script, load tools and parse args -require_once( 'userOptions.inc' ); +require_once 'userOptions.inc'; // Load up our tool system, exit with usage() if options are not fine $uo = new userOptions( $options, $args ); diff --git a/maintenance/waitForSlave.php b/maintenance/waitForSlave.php index df83928b..a62d1618 100644 --- a/maintenance/waitForSlave.php +++ b/maintenance/waitForSlave.php @@ -22,7 +22,7 @@ * @see wfWaitForSlaves() */ -require_once( __DIR__ . '/Maintenance.php' ); +require_once __DIR__ . '/Maintenance.php'; /** * Maintenance script to wait until slave lag goes under a certain value. @@ -40,4 +40,4 @@ class WaitForSlave extends Maintenance { } $maintClass = "WaitForSlave"; -require_once( RUN_MAINTENANCE_IF_MAIN ); +require_once RUN_MAINTENANCE_IF_MAIN; |