summaryrefslogtreecommitdiff
path: root/maintenance
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2013-01-18 16:46:04 +0100
committerPierre Schmitz <pierre@archlinux.de>2013-01-18 16:46:04 +0100
commit63601400e476c6cf43d985f3e7b9864681695ed4 (patch)
treef7846203a952e38aaf66989d0a4702779f549962 /maintenance
parent8ff01378c9e0207f9169b81966a51def645b6a51 (diff)
Update to MediaWiki 1.20.2
this update includes: * adjusted Arch Linux skin * updated FluxBBAuthPlugin * patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024
Diffstat (limited to 'maintenance')
-rw-r--r--maintenance/Doxyfile6
-rw-r--r--maintenance/Maintenance.php80
-rw-r--r--maintenance/archives/patch-cat_hidden.sql3
-rw-r--r--maintenance/archives/patch-filejournal.sql20
-rw-r--r--maintenance/archives/patch-ipb-parent-block-id-index.sql2
-rw-r--r--maintenance/archives/patch-ipb-parent-block-id.sql3
-rw-r--r--maintenance/archives/patch-revision-user-page-index.sql4
-rw-r--r--maintenance/archives/upgradeLogging.php24
-rw-r--r--maintenance/attachLatest.php11
-rw-r--r--maintenance/backup.inc42
-rw-r--r--maintenance/backupTextPass.inc794
-rw-r--r--maintenance/benchmarks/Benchmarker.php16
-rw-r--r--maintenance/benchmarks/bench_HTTP_HTTPS.php12
-rw-r--r--maintenance/benchmarks/bench_delete_truncate.php36
-rw-r--r--maintenance/benchmarks/bench_if_switch.php10
-rw-r--r--maintenance/benchmarks/bench_strtr_str_replace.php26
-rw-r--r--maintenance/benchmarks/bench_utf8_title_check.php126
-rw-r--r--maintenance/benchmarks/bench_wfIsWindows.php12
-rw-r--r--maintenance/benchmarks/benchmarkHooks.php17
-rw-r--r--maintenance/benchmarks/benchmarkPurge.php13
-rw-r--r--maintenance/cdb.php2
-rw-r--r--maintenance/changePassword.php7
-rw-r--r--maintenance/checkAutoLoader.php7
-rw-r--r--maintenance/checkBadRedirects.php10
-rw-r--r--maintenance/checkImages.php9
-rw-r--r--maintenance/checkSyntax.php78
-rw-r--r--maintenance/checkUsernames.php14
-rw-r--r--maintenance/cleanupAncientTables.php113
-rw-r--r--maintenance/cleanupCaps.php9
-rw-r--r--maintenance/cleanupImages.php22
-rw-r--r--maintenance/cleanupPreferences.php (renamed from maintenance/refreshImageCount.php)106
-rw-r--r--maintenance/cleanupRemovedModules.php11
-rw-r--r--maintenance/cleanupSpam.php35
-rw-r--r--maintenance/cleanupTable.inc13
-rw-r--r--maintenance/cleanupTitles.php9
-rw-r--r--maintenance/cleanupUploadStash.php16
-rw-r--r--maintenance/cleanupWatchlist.php11
-rw-r--r--maintenance/clear_interwiki_cache.php10
-rw-r--r--maintenance/clear_stats.php9
-rw-r--r--maintenance/commandLine.inc2
-rw-r--r--maintenance/compareParsers.php47
-rw-r--r--maintenance/convertLinks.php15
-rw-r--r--maintenance/convertUserOptions.php11
-rw-r--r--maintenance/copyFileBackend.php201
-rw-r--r--maintenance/createAndPromote.php11
-rw-r--r--maintenance/deleteArchivedFiles.inc16
-rw-r--r--maintenance/deleteArchivedFiles.php14
-rw-r--r--maintenance/deleteArchivedRevisions.inc13
-rw-r--r--maintenance/deleteArchivedRevisions.php15
-rw-r--r--maintenance/deleteBatch.php14
-rw-r--r--maintenance/deleteDefaultMessages.php15
-rw-r--r--maintenance/deleteImageMemcached.php10
-rw-r--r--maintenance/deleteOldRevisions.php13
-rw-r--r--maintenance/deleteOrphanedRevisions.php17
-rw-r--r--maintenance/deleteRevision.php9
-rw-r--r--maintenance/deleteSelfExternals.php18
-rw-r--r--maintenance/dev/includes/php.sh22
-rw-r--r--maintenance/dev/includes/router.php26
-rw-r--r--maintenance/doMaintenance.php5
-rw-r--r--maintenance/dumpBackup.php8
-rw-r--r--maintenance/dumpIterator.php19
-rw-r--r--maintenance/dumpLinks.php14
-rw-r--r--maintenance/dumpSisterSites.php10
-rw-r--r--maintenance/dumpTextPass.php630
-rw-r--r--maintenance/dumpUploads.php11
-rw-r--r--maintenance/edit.php10
-rw-r--r--maintenance/eval.php2
-rw-r--r--maintenance/fetchText.php10
-rw-r--r--maintenance/fileOpPerfTest.php146
-rw-r--r--maintenance/findHooks.php13
-rw-r--r--maintenance/fixDoubleRedirects.php13
-rw-r--r--maintenance/fixExtLinksProtocolRelative.php9
-rw-r--r--maintenance/fixSlaveDesync.php19
-rw-r--r--maintenance/fixTimestamps.php19
-rw-r--r--maintenance/fixUserRegistration.php8
-rw-r--r--maintenance/formatInstallDoc.php25
-rw-r--r--maintenance/fuzz-tester.php6
-rw-r--r--maintenance/generateSitemap.php32
-rw-r--r--maintenance/getLagTimes.php10
-rw-r--r--maintenance/getSlaveServer.php10
-rw-r--r--maintenance/getText.php11
-rw-r--r--maintenance/hiphop/make6
-rw-r--r--maintenance/hiphop/run-server6
-rw-r--r--maintenance/ibm_db2/tables.sql14
-rw-r--r--maintenance/importDump.php12
-rw-r--r--maintenance/importImages.inc10
-rw-r--r--maintenance/importImages.php9
-rw-r--r--maintenance/importSiteScripts.php53
-rw-r--r--maintenance/importTextFile.php6
-rw-r--r--maintenance/initEditCount.php2
-rw-r--r--maintenance/initStats.php9
-rw-r--r--maintenance/install.php20
-rw-r--r--maintenance/interwiki.list9
-rw-r--r--maintenance/interwiki.sql9
-rw-r--r--maintenance/jsparse.php12
-rw-r--r--maintenance/lag.php7
-rw-r--r--maintenance/language/StatOutputs.php4
-rw-r--r--maintenance/language/alltrans.php9
-rw-r--r--maintenance/language/checkDupeMessages.php6
-rw-r--r--maintenance/language/checkExtensions.php2
-rw-r--r--maintenance/language/checkLanguage.inc47
-rw-r--r--maintenance/language/checkLanguage.php2
-rw-r--r--maintenance/language/countMessages.php9
-rw-r--r--maintenance/language/date-formats.php8
-rw-r--r--maintenance/language/digit2html.php10
-rw-r--r--maintenance/language/dumpMessages.php14
-rw-r--r--maintenance/language/generateCollationData.php24
-rw-r--r--maintenance/language/generateNormalizerData.php7
-rw-r--r--maintenance/language/lang2po.php166
-rw-r--r--maintenance/language/langmemusage.php4
-rw-r--r--maintenance/language/languages.inc16
-rw-r--r--maintenance/language/messageTypes.inc63
-rw-r--r--maintenance/language/messages.inc197
-rw-r--r--maintenance/language/rebuildLanguage.php21
-rw-r--r--maintenance/language/transstat.php8
-rw-r--r--maintenance/language/validate.php3
-rw-r--r--maintenance/language/writeMessagesArray.inc23
-rw-r--r--maintenance/locking/LockServerDaemon.php36
-rw-r--r--maintenance/mcc.php2
-rw-r--r--maintenance/mctest.php20
-rw-r--r--maintenance/mergeMessageFileList.php101
-rw-r--r--maintenance/migrateUserGroup.php22
-rw-r--r--maintenance/minify.php7
-rw-r--r--maintenance/moveBatch.php16
-rw-r--r--maintenance/mssql/tables.sql1
-rw-r--r--maintenance/mwdoc-filter.php19
-rw-r--r--maintenance/mwdocgen.php56
-rw-r--r--maintenance/namespaceDupes.php15
-rw-r--r--maintenance/nextJobDB.php11
-rw-r--r--maintenance/nukeNS.php16
-rw-r--r--maintenance/nukePage.php18
-rw-r--r--maintenance/oracle/alterSharedConstraints.php2
-rw-r--r--maintenance/oracle/archives/patch-ipblocks_i05_index.sql4
-rw-r--r--maintenance/oracle/archives/patch-revision_i05_index.sql4
-rw-r--r--maintenance/oracle/tables.sql14
-rw-r--r--maintenance/orphans.php17
-rw-r--r--maintenance/parse.php30
-rw-r--r--maintenance/patchSql.php8
-rw-r--r--maintenance/populateCategory.php10
-rw-r--r--maintenance/populateImageSha1.php74
-rw-r--r--maintenance/populateLogSearch.php9
-rw-r--r--maintenance/populateLogUsertext.php13
-rw-r--r--maintenance/populateParentId.php11
-rw-r--r--maintenance/populateRevisionLength.php9
-rw-r--r--maintenance/populateRevisionSha1.php48
-rw-r--r--maintenance/postgres/archives/patch-add_interwiki.sql14
-rw-r--r--maintenance/postgres/archives/patch-category.sql4
-rw-r--r--maintenance/postgres/archives/patch-external_user.sql6
-rw-r--r--maintenance/postgres/archives/patch-ipb_address_unique.sql1
-rw-r--r--maintenance/postgres/archives/patch-log_search.sql2
-rw-r--r--maintenance/postgres/archives/patch-module_deps.sql2
-rw-r--r--maintenance/postgres/archives/patch-msg_resource.sql2
-rw-r--r--maintenance/postgres/archives/patch-msg_resource_links.sql2
-rw-r--r--maintenance/postgres/compare_schemas.pl35
-rw-r--r--maintenance/postgres/tables.sql7
-rw-r--r--maintenance/preprocessDump.php12
-rw-r--r--maintenance/preprocessorFuzzTest.php2
-rw-r--r--maintenance/protect.php14
-rw-r--r--maintenance/proxy_check.php17
-rw-r--r--maintenance/pruneFileCache.php10
-rw-r--r--maintenance/purgeDeletedFiles.php13
-rw-r--r--maintenance/purgeList.php8
-rw-r--r--maintenance/purgeOldText.inc4
-rw-r--r--maintenance/purgeOldText.php8
-rw-r--r--maintenance/purgeParserCache.php35
-rw-r--r--maintenance/purgeStaleMemcachedText.php38
-rw-r--r--maintenance/reassignEdits.php19
-rw-r--r--maintenance/rebuildFileCache.php14
-rw-r--r--maintenance/rebuildImages.php15
-rw-r--r--maintenance/rebuildLocalisationCache.php22
-rw-r--r--maintenance/rebuildall.php8
-rw-r--r--maintenance/rebuildmessages.php10
-rw-r--r--maintenance/rebuildrecentchanges.php12
-rw-r--r--maintenance/rebuildtextindex.php8
-rw-r--r--maintenance/refreshImageMetadata.php9
-rw-r--r--maintenance/refreshLinks.php43
-rw-r--r--maintenance/removeUnusedAccounts.php14
-rw-r--r--maintenance/renameDbPrefix.php9
-rw-r--r--maintenance/renderDump.php12
-rw-r--r--maintenance/resetUserTokens.php27
-rw-r--r--maintenance/rollbackEdits.php9
-rw-r--r--maintenance/runBatchedQuery.php8
-rw-r--r--maintenance/runJobs.php24
-rw-r--r--maintenance/showJobs.php13
-rw-r--r--maintenance/showStats.php10
-rw-r--r--maintenance/sql.php8
-rw-r--r--maintenance/sqlite.inc4
-rw-r--r--maintenance/sqlite.php10
-rw-r--r--maintenance/sqlite/archives/patch-cat_hidden.sql20
-rw-r--r--maintenance/sqlite/archives/patch-revision-user-page-index.sql4
-rw-r--r--maintenance/stats.php10
-rw-r--r--maintenance/storage/checkStorage.php14
-rw-r--r--maintenance/storage/compressOld.php15
-rw-r--r--maintenance/storage/dumpRev.php2
-rw-r--r--maintenance/storage/fixBug20757.php6
-rw-r--r--maintenance/storage/moveToExternal.php4
-rw-r--r--maintenance/storage/orphanStats.php4
-rw-r--r--maintenance/storage/recompressTracked.php14
-rw-r--r--maintenance/storage/resolveStubs.php2
-rw-r--r--maintenance/storage/storageTypeStats.php2
-rw-r--r--maintenance/storage/testCompression.php2
-rw-r--r--maintenance/storage/trackBlobs.php4
-rw-r--r--maintenance/syncFileBackend.php252
-rw-r--r--maintenance/tables.sql88
-rw-r--r--maintenance/term/MWTerm.php27
-rw-r--r--maintenance/undelete.php2
-rw-r--r--maintenance/update.php11
-rw-r--r--maintenance/updateArticleCount.php12
-rw-r--r--maintenance/updateCollation.php168
-rw-r--r--maintenance/updateDoubleWidthSearch.php9
-rw-r--r--maintenance/updateRestrictions.php8
-rw-r--r--maintenance/updateSearchIndex.php9
-rw-r--r--maintenance/updateSpecialPages.php13
-rw-r--r--maintenance/upgrade1_5.php12
-rw-r--r--maintenance/userOptions.inc4
-rw-r--r--maintenance/userOptions.php4
-rw-r--r--maintenance/waitForSlave.php9
217 files changed, 4180 insertions, 1792 deletions
diff --git a/maintenance/Doxyfile b/maintenance/Doxyfile
index b7c1e5e8..b60a1962 100644
--- a/maintenance/Doxyfile
+++ b/maintenance/Doxyfile
@@ -182,7 +182,7 @@ EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
-INPUT_FILTER =
+INPUT_FILTER = "{{INPUT_FILTER}}"
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
@@ -345,8 +345,8 @@ UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
-CALL_GRAPH = YES
-CALLER_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php
index 082cf8be..69d11313 100644
--- a/maintenance/Maintenance.php
+++ b/maintenance/Maintenance.php
@@ -20,23 +20,24 @@
* @defgroup Maintenance Maintenance
*/
+// 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' );
+ wfPHPVersionError( 'cli' );
+}
+
/**
* @defgroup MaintenanceArchive Maintenance archives
* @ingroup Maintenance
*/
// Define this so scripts can easily find doMaintenance.php
-define( 'RUN_MAINTENANCE_IF_MAIN', dirname( __FILE__ ) . '/doMaintenance.php' );
+define( 'RUN_MAINTENANCE_IF_MAIN', __DIR__ . '/doMaintenance.php' );
define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless
$maintClass = false;
-// Make sure we're on PHP5 or better
-if ( !function_exists( 'version_compare' ) || version_compare( PHP_VERSION, '5.2.3' ) < 0 ) {
- require_once( dirname( __FILE__ ) . '/../includes/PHPVersionError.php' );
- wfPHPVersionError( 'cli' );
-}
-
/**
* Abstract maintenance class for quickly writing and churning out
* maintenance scripts with minimal effort. All that _must_ be defined
@@ -101,7 +102,10 @@ abstract class Maintenance {
// Generic options which might or not be supported by the script
private $mDependantParameters = array();
- // Used by getDD() / setDB()
+ /**
+ * Used by getDD() / setDB()
+ * @var DatabaseBase
+ */
private $mDb = null;
/**
@@ -120,7 +124,7 @@ abstract class Maintenance {
global $IP;
$IP = strval( getenv( 'MW_INSTALL_PATH' ) ) !== ''
? getenv( 'MW_INSTALL_PATH' )
- : realpath( dirname( __FILE__ ) . '/..' );
+ : realpath( __DIR__ . '/..' );
$this->addDefaultParams();
register_shutdown_function( array( $this, 'outputChanneled' ), false );
@@ -297,6 +301,9 @@ abstract class Maintenance {
return rtrim( $input );
}
+ /**
+ * @return bool
+ */
public function isQuiet() {
return $this->mQuiet;
}
@@ -314,11 +321,7 @@ abstract class Maintenance {
}
if ( $channel === null ) {
$this->cleanupChanneled();
- if( php_sapi_name() == 'cli' ) {
- fwrite( STDOUT, $out );
- } else {
- print( $out );
- }
+ print( $out );
} else {
$out = preg_replace( '/\n\z/', '', $out );
$this->outputChanneled( $out, $channel );
@@ -352,11 +355,7 @@ abstract class Maintenance {
*/
public function cleanupChanneled() {
if ( !$this->atLineStart ) {
- if( php_sapi_name() == 'cli' ) {
- fwrite( STDOUT, "\n" );
- } else {
- print "\n";
- }
+ print "\n";
$this->atLineStart = true;
}
}
@@ -366,7 +365,7 @@ abstract class Maintenance {
* same channel are concatenated, but any intervening messages in another
* channel start a new line.
* @param $msg String: the message without trailing newline
- * @param $channel Channel identifier or null for no
+ * @param $channel string Channel identifier or null for no
* channel. Channel comparison uses ===.
*/
public function outputChanneled( $msg, $channel = null ) {
@@ -375,31 +374,17 @@ abstract class Maintenance {
return;
}
- $cli = php_sapi_name() == 'cli';
-
// End the current line if necessary
if ( !$this->atLineStart && $channel !== $this->lastChannel ) {
- if( $cli ) {
- fwrite( STDOUT, "\n" );
- } else {
- print "\n";
- }
+ print "\n";
}
- if( $cli ) {
- fwrite( STDOUT, $msg );
- } else {
- print $msg;
- }
+ print $msg;
$this->atLineStart = false;
if ( $channel === null ) {
// For unchanneled messages, output trailing newline immediately
- if( $cli ) {
- fwrite( STDOUT, "\n" );
- } else {
- print "\n";
- }
+ print "\n";
$this->atLineStart = true;
}
$this->lastChannel = $channel;
@@ -951,7 +936,7 @@ abstract class Maintenance {
public function purgeRedundantText( $delete = true ) {
# Data should come off the master, wrapped in a transaction
$dbw = $this->getDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_arc = $dbw->tableName( 'archive' );
$tbl_rev = $dbw->tableName( 'revision' );
@@ -996,7 +981,7 @@ abstract class Maintenance {
}
# Done
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
/**
@@ -1004,7 +989,7 @@ abstract class Maintenance {
* @return string
*/
protected function getDir() {
- return dirname( __FILE__ );
+ return __DIR__;
}
/**
@@ -1025,10 +1010,9 @@ abstract class Maintenance {
protected static function getCoreScripts() {
if ( !self::$mCoreScripts ) {
$paths = array(
- dirname( __FILE__ ),
- dirname( __FILE__ ) . '/gearman',
- dirname( __FILE__ ) . '/language',
- dirname( __FILE__ ) . '/storage',
+ __DIR__,
+ __DIR__ . '/language',
+ __DIR__ . '/storage',
);
self::$mCoreScripts = array();
foreach ( $paths as $p ) {
@@ -1080,7 +1064,7 @@ abstract class Maintenance {
/**
* Lock the search index
- * @param &$db Database object
+ * @param &$db DatabaseBase object
*/
private function lockSearchindex( &$db ) {
$write = array( 'searchindex' );
@@ -1090,7 +1074,7 @@ abstract class Maintenance {
/**
* Unlock the tables
- * @param &$db Database object
+ * @param &$db DatabaseBase object
*/
private function unlockSearchindex( &$db ) {
$db->unlockTables( __CLASS__ . '::' . __METHOD__ );
@@ -1099,7 +1083,7 @@ abstract class Maintenance {
/**
* Unlock and lock again
* Since the lock is low-priority, queued reads will be able to complete
- * @param &$db Database object
+ * @param &$db DatabaseBase object
*/
private function relockSearchindex( &$db ) {
$this->unlockSearchindex( $db );
@@ -1147,7 +1131,7 @@ abstract class Maintenance {
/**
* Update the searchindex table for a given pageid
- * @param $dbw Database: a database write handle
+ * @param $dbw DatabaseBase a database write handle
* @param $pageId Integer: the page ID to update.
* @return null|string
*/
diff --git a/maintenance/archives/patch-cat_hidden.sql b/maintenance/archives/patch-cat_hidden.sql
new file mode 100644
index 00000000..933188ce
--- /dev/null
+++ b/maintenance/archives/patch-cat_hidden.sql
@@ -0,0 +1,3 @@
+-- cat_hidden is no longer used, delete it
+
+ALTER TABLE /*$wgDBprefix*/category DROP COLUMN cat_hidden;
diff --git a/maintenance/archives/patch-filejournal.sql b/maintenance/archives/patch-filejournal.sql
new file mode 100644
index 00000000..4356d70d
--- /dev/null
+++ b/maintenance/archives/patch-filejournal.sql
@@ -0,0 +1,20 @@
+-- File backend operation journal
+CREATE TABLE /*_*/filejournal (
+ -- Unique ID for each file operation
+ fj_id bigint unsigned NOT NULL PRIMARY KEY auto_increment,
+ -- UUID of the batch this operation belongs to
+ fj_batch_uuid varbinary(32) NOT NULL,
+ -- The registered file backend name
+ fj_backend varchar(255) NOT NULL,
+ -- The storage path that was affected (may be internal paths)
+ fj_path blob NOT NULL,
+ -- Primitive operation description (create/update/delete)
+ fj_op varchar(16) NOT NULL default '',
+ -- SHA-1 file content hash in base-36
+ fj_new_sha1 varbinary(32) NOT NULL default '',
+ -- Timestamp of the batch operation
+ fj_timestamp varbinary(14) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+CREATE INDEX /*i*/fj_batch_id ON /*_*/filejournal (fj_batch_uuid);
+CREATE INDEX /*i*/fj_timestamp ON /*_*/filejournal (fj_timestamp);
diff --git a/maintenance/archives/patch-ipb-parent-block-id-index.sql b/maintenance/archives/patch-ipb-parent-block-id-index.sql
new file mode 100644
index 00000000..1f413f37
--- /dev/null
+++ b/maintenance/archives/patch-ipb-parent-block-id-index.sql
@@ -0,0 +1,2 @@
+-- index for ipblocks.ipb_parent_block_id
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
diff --git a/maintenance/archives/patch-ipb-parent-block-id.sql b/maintenance/archives/patch-ipb-parent-block-id.sql
new file mode 100644
index 00000000..8ebcf786
--- /dev/null
+++ b/maintenance/archives/patch-ipb-parent-block-id.sql
@@ -0,0 +1,3 @@
+-- Adding ipb_parent_block_id to track the block that caused an autoblock
+ALTER TABLE /*$wgDBprefix*/ipblocks
+ ADD ipb_parent_block_id int DEFAULT NULL;
diff --git a/maintenance/archives/patch-revision-user-page-index.sql b/maintenance/archives/patch-revision-user-page-index.sql
new file mode 100644
index 00000000..a4554c8f
--- /dev/null
+++ b/maintenance/archives/patch-revision-user-page-index.sql
@@ -0,0 +1,4 @@
+-- New index on revision table to allow searches for all edits by a given user
+-- to a given page. Added 2007-08-28
+
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
diff --git a/maintenance/archives/upgradeLogging.php b/maintenance/archives/upgradeLogging.php
index 1765bd9f..2c28011b 100644
--- a/maintenance/archives/upgradeLogging.php
+++ b/maintenance/archives/upgradeLogging.php
@@ -1,6 +1,6 @@
<?php
/**
- * Replication-safe online upgrade script for log_id/log_deleted
+ * Replication-safe online upgrade for log_id/log_deleted fields.
*
* 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
@@ -21,8 +21,14 @@
* @ingroup MaintenanceArchive
*/
-require( dirname( __FILE__ ) . '/../commandLine.inc' );
+require( __DIR__ . '/../commandLine.inc' );
+/**
+ * Maintenance script that upgrade for log_id/log_deleted fields in a
+ * replication-safe way.
+ *
+ * @ingroup Maintenance
+ */
class UpdateLogging {
/**
@@ -63,21 +69,21 @@ CREATE TABLE $logging_1_10 (
-- action field, but only the type controls categorization.
log_type varbinary(10) NOT NULL default '',
log_action varbinary(10) NOT NULL default '',
-
+
-- Timestamp. Duh.
log_timestamp binary(14) NOT NULL default '19700101000000',
-
+
-- The user who performed this action; key to user_id
log_user int unsigned NOT NULL default 0,
-
+
-- Key to the page affected. Where a user is the target,
-- this will point to the user page.
log_namespace int NOT NULL default 0,
log_title varchar(255) binary NOT NULL default '',
-
+
-- Freeform text. Interpreted as edit history comments.
log_comment varchar(255) NOT NULL default '',
-
+
-- LF separated list of miscellaneous parameters
log_params blob NOT NULL,
@@ -124,7 +130,7 @@ EOT;
$minTs = $this->dbw->selectField( $srcTable, 'MIN(log_timestamp)', false, __METHOD__ );
$minTsUnix = wfTimestamp( TS_UNIX, $minTs );
$numRowsCopied = 0;
-
+
while ( true ) {
$maxTs = $this->dbw->selectField( $srcTable, 'MAX(log_timestamp)', false, __METHOD__ );
$copyPos = $this->dbw->selectField( $dstTable, 'MAX(log_timestamp)', false, __METHOD__ );
@@ -137,7 +143,7 @@ EOT;
$percent = ( $copyPosUnix - $minTsUnix ) / ( $maxTsUnix - $minTsUnix ) * 100;
}
printf( "%s %.2f%%\n", $copyPos, $percent );
-
+
# Handle all entries with timestamp equal to $copyPos
if ( $copyPos !== null ) {
$numRowsCopied += $this->copyExactMatch( $srcTable, $dstTable, $copyPos );
diff --git a/maintenance/attachLatest.php b/maintenance/attachLatest.php
index 6e09671a..475cafc9 100644
--- a/maintenance/attachLatest.php
+++ b/maintenance/attachLatest.php
@@ -1,7 +1,6 @@
<?php
/**
- * quick hackjob to fix damages imports on wikisource
- * page records have page_latest wrong
+ * Corrects wrong values in the `page_latest` field in the database.
*
* Copyright © 2005 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
@@ -25,8 +24,14 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to correct wrong values in the `page_latest` field
+ * in the database.
+ *
+ * @ingroup Maintenance
+ */
class AttachLatest extends Maintenance {
public function __construct() {
diff --git a/maintenance/backup.inc b/maintenance/backup.inc
index 9f67a1ac..e3dc488b 100644
--- a/maintenance/backup.inc
+++ b/maintenance/backup.inc
@@ -28,7 +28,7 @@
* @ingroup Dump Maintenance
*/
class DumpDBZip2Output extends DumpPipeOutput {
- function DumpDBZip2Output( $file ) {
+ function __construct( $file ) {
parent::__construct( "dbzip2", $file );
}
}
@@ -61,6 +61,15 @@ class BackupDumper {
var $outputTypes = array(), $filterTypes = array();
/**
+ * The dependency-injected database to use.
+ *
+ * @var DatabaseBase|null
+ *
+ * @see self::setDb
+ */
+ protected $forcedDb = null;
+
+ /**
* @var LoadBalancer
*/
protected $lb;
@@ -245,9 +254,12 @@ class BackupDumper {
$table = ( $history == WikiExporter::CURRENT ) ? 'page' : 'revision';
$field = ( $history == WikiExporter::CURRENT ) ? 'page_id' : 'rev_id';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = $this->forcedDb;
+ if ( $this->forcedDb === null ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ }
$this->maxCount = $dbr->selectField( $table, "MAX($field)", '', __METHOD__ );
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
$this->lastTime = $this->startTime;
$this->ID = getmypid();
}
@@ -259,16 +271,32 @@ class BackupDumper {
* @return DatabaseBase
*/
function backupDb() {
+ if ( $this->forcedDb !== null ) {
+ return $this->forcedDb;
+ }
+
$this->lb = wfGetLBFactory()->newMainLB();
$db = $this->lb->getConnection( DB_SLAVE, 'backup' );
// Discourage the server from disconnecting us if it takes a long time
// to read out the big ol' batch query.
- $db->setTimeout( 3600 * 24 );
+ $db->setSessionOptions( array( 'connTimeout' => 3600 * 24 ) );
return $db;
}
+ /**
+ * Force the dump to use the provided database connection for database
+ * operations, wherever possible.
+ *
+ * @param $db DatabaseBase|null: (Optional) the database connection to
+ * use. If null, resort to use the globally provided ways to
+ * get database connections.
+ */
+ function setDb( DatabaseBase $db = null ) {
+ $this->forcedDb = $db;
+ }
+
function __destruct() {
if ( isset( $this->lb ) ) {
$this->lb->closeAll();
@@ -300,9 +328,9 @@ class BackupDumper {
function showReport() {
if ( $this->reporting ) {
$now = wfTimestamp( TS_DB );
- $nowts = wfTime();
- $deltaAll = wfTime() - $this->startTime;
- $deltaPart = wfTime() - $this->lastTime;
+ $nowts = microtime( true );
+ $deltaAll = $nowts - $this->startTime;
+ $deltaPart = $nowts - $this->lastTime;
$this->pageCountPart = $this->pageCount - $this->pageCountLast;
$this->revCountPart = $this->revCount - $this->revCountLast;
diff --git a/maintenance/backupTextPass.inc b/maintenance/backupTextPass.inc
new file mode 100644
index 00000000..f1f09546
--- /dev/null
+++ b/maintenance/backupTextPass.inc
@@ -0,0 +1,794 @@
+<?php
+/**
+ * BackupDumper that postprocesses XML dumps from dumpBackup.php to add page text
+ *
+ * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.org/
+ *
+ * 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__ . '/backup.inc' );
+
+/**
+ * @ingroup Maintenance
+ */
+class TextPassDumper extends BackupDumper {
+ var $prefetch = null;
+ var $input = "php://stdin";
+ var $history = WikiExporter::FULL;
+ var $fetchCount = 0;
+ var $prefetchCount = 0;
+ var $prefetchCountLast = 0;
+ var $fetchCountLast = 0;
+
+ var $maxFailures = 5;
+ var $maxConsecutiveFailedTextRetrievals = 200;
+ var $failureTimeout = 5; // Seconds to sleep after db failure
+
+ var $php = "php";
+ var $spawn = false;
+
+ /**
+ * @var bool|resource
+ */
+ var $spawnProc = false;
+
+ /**
+ * @var bool|resource
+ */
+ var $spawnWrite = false;
+
+ /**
+ * @var bool|resource
+ */
+ var $spawnRead = false;
+
+ /**
+ * @var bool|resource
+ */
+ var $spawnErr = false;
+
+ var $xmlwriterobj = false;
+
+ // when we spend more than maxTimeAllowed seconds on this run, we continue
+ // processing until we write out the next complete page, then save output file(s),
+ // rename it/them and open new one(s)
+ var $maxTimeAllowed = 0; // 0 = no limit
+ var $timeExceeded = false;
+ var $firstPageWritten = false;
+ var $lastPageWritten = false;
+ var $checkpointJustWritten = false;
+ var $checkpointFiles = array();
+
+ /**
+ * @var DatabaseBase
+ */
+ protected $db;
+
+
+ /**
+ * Drop the database connection $this->db and try to get a new one.
+ *
+ * This function tries to get a /different/ connection if this is
+ * possible. Hence, (if this is possible) it switches to a different
+ * failover upon each call.
+ *
+ * This function resets $this->lb and closes all connections on it.
+ *
+ * @throws MWException
+ */
+ function rotateDb() {
+ // Cleaning up old connections
+ if ( isset( $this->lb ) ) {
+ $this->lb->closeAll();
+ unset( $this->lb );
+ }
+
+ if ( $this->forcedDb !== null ) {
+ $this->db = $this->forcedDb;
+ return;
+ }
+
+ if ( isset( $this->db ) && $this->db->isOpen() ) {
+ throw new MWException( 'DB is set and has not been closed by the Load Balancer' );
+ }
+
+ unset( $this->db );
+
+ // Trying to set up new connection.
+ // We do /not/ retry upon failure, but delegate to encapsulating logic, to avoid
+ // individually retrying at different layers of code.
+
+ // 1. The LoadBalancer.
+ try {
+ $this->lb = wfGetLBFactory()->newMainLB();
+ } catch ( Exception $e ) {
+ throw new MWException( __METHOD__ . " rotating DB failed to obtain new load balancer (" . $e->getMessage() . ")" );
+ }
+
+
+ // 2. The Connection, through the load balancer.
+ try {
+ $this->db = $this->lb->getConnection( DB_SLAVE, 'backup' );
+ } catch ( Exception $e ) {
+ throw new MWException( __METHOD__ . " rotating DB failed to obtain new database (" . $e->getMessage() . ")" );
+ }
+ }
+
+
+ function initProgress( $history = WikiExporter::FULL ) {
+ parent::initProgress();
+ $this->timeOfCheckpoint = $this->startTime;
+ }
+
+ 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' ) )
+ ini_set( 'display_errors', 'stderr' );
+
+ $this->initProgress( $this->history );
+
+ // We are trying to get an initial database connection to avoid that the
+ // first try of this request's first call to getText fails. However, if
+ // obtaining a good DB connection fails it's not a serious issue, as
+ // getText does retry upon failure and can start without having a working
+ // DB connection.
+ try {
+ $this->rotateDb();
+ } catch ( Exception $e ) {
+ // We do not even count this as failure. Just let eventual
+ // watchdogs know.
+ $this->progress( "Getting initial DB connection failed (" .
+ $e->getMessage() . ")" );
+ }
+
+ $this->egress = new ExportProgressFilter( $this->sink, $this );
+
+ // it would be nice to do it in the constructor, oh well. need egress set
+ $this->finalOptionCheck();
+
+ // we only want this so we know how to close a stream :-P
+ $this->xmlwriterobj = new XmlDumpWriter();
+
+ $input = fopen( $this->input, "rt" );
+ $result = $this->readDump( $input );
+
+ if ( $this->spawnProc ) {
+ $this->closeSpawn();
+ }
+
+ $this->report( true );
+ }
+
+ function processOption( $opt, $val, $param ) {
+ global $IP;
+ $url = $this->processFileOpt( $val, $param );
+
+ switch( $opt ) {
+ case 'prefetch':
+ require_once "$IP/maintenance/backupPrefetch.inc";
+ $this->prefetch = new BaseDump( $url );
+ break;
+ case 'stub':
+ $this->input = $url;
+ break;
+ case 'maxtime':
+ $this->maxTimeAllowed = intval( $val ) * 60;
+ break;
+ case 'checkpointfile':
+ $this->checkpointFiles[] = $val;
+ break;
+ case 'current':
+ $this->history = WikiExporter::CURRENT;
+ break;
+ case 'full':
+ $this->history = WikiExporter::FULL;
+ break;
+ case 'spawn':
+ $this->spawn = true;
+ if ( $val ) {
+ $this->php = $val;
+ }
+ break;
+ }
+ }
+
+ function processFileOpt( $val, $param ) {
+ $fileURIs = explode( ';', $param );
+ foreach ( $fileURIs as $URI ) {
+ switch( $val ) {
+ case "file":
+ $newURI = $URI;
+ break;
+ case "gzip":
+ $newURI = "compress.zlib://$URI";
+ break;
+ case "bzip2":
+ $newURI = "compress.bzip2://$URI";
+ break;
+ case "7zip":
+ $newURI = "mediawiki.compress.7z://$URI";
+ break;
+ default:
+ $newURI = $URI;
+ }
+ $newFileURIs[] = $newURI;
+ }
+ $val = implode( ';', $newFileURIs );
+ return $val;
+ }
+
+ /**
+ * Overridden to include prefetch ratio if enabled.
+ */
+ function showReport() {
+ if ( !$this->prefetch ) {
+ parent::showReport();
+ return;
+ }
+
+ if ( $this->reporting ) {
+ $now = wfTimestamp( TS_DB );
+ $nowts = microtime( true );
+ $deltaAll = $nowts - $this->startTime;
+ $deltaPart = $nowts - $this->lastTime;
+ $this->pageCountPart = $this->pageCount - $this->pageCountLast;
+ $this->revCountPart = $this->revCount - $this->revCountLast;
+
+ if ( $deltaAll ) {
+ $portion = $this->revCount / $this->maxCount;
+ $eta = $this->startTime + $deltaAll / $portion;
+ $etats = wfTimestamp( TS_DB, intval( $eta ) );
+ if ( $this->fetchCount ) {
+ $fetchRate = 100.0 * $this->prefetchCount / $this->fetchCount;
+ } else {
+ $fetchRate = '-';
+ }
+ $pageRate = $this->pageCount / $deltaAll;
+ $revRate = $this->revCount / $deltaAll;
+ } else {
+ $pageRate = '-';
+ $revRate = '-';
+ $etats = '-';
+ $fetchRate = '-';
+ }
+ if ( $deltaPart ) {
+ if ( $this->fetchCountLast ) {
+ $fetchRatePart = 100.0 * $this->prefetchCountLast / $this->fetchCountLast;
+ } else {
+ $fetchRatePart = '-';
+ }
+ $pageRatePart = $this->pageCountPart / $deltaPart;
+ $revRatePart = $this->revCountPart / $deltaPart;
+
+ } else {
+ $fetchRatePart = '-';
+ $pageRatePart = '-';
+ $revRatePart = '-';
+ }
+ $this->progress( sprintf( "%s: %s (ID %d) %d pages (%0.1f|%0.1f/sec all|curr), %d revs (%0.1f|%0.1f/sec all|curr), %0.1f%%|%0.1f%% prefetched (all|curr), ETA %s [max %d]",
+ $now, wfWikiID(), $this->ID, $this->pageCount, $pageRate, $pageRatePart, $this->revCount, $revRate, $revRatePart, $fetchRate, $fetchRatePart, $etats, $this->maxCount ) );
+ $this->lastTime = $nowts;
+ $this->revCountLast = $this->revCount;
+ $this->prefetchCountLast = $this->prefetchCount;
+ $this->fetchCountLast = $this->fetchCount;
+ }
+ }
+
+ function setTimeExceeded() {
+ $this->timeExceeded = True;
+ }
+
+ function checkIfTimeExceeded() {
+ if ( $this->maxTimeAllowed && ( $this->lastTime - $this->timeOfCheckpoint > $this->maxTimeAllowed ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ function finalOptionCheck() {
+ if ( ( $this->checkpointFiles && ! $this->maxTimeAllowed ) ||
+ ( $this->maxTimeAllowed && !$this->checkpointFiles ) ) {
+ throw new MWException( "Options checkpointfile and maxtime must be specified together.\n" );
+ }
+ foreach ( $this->checkpointFiles as $checkpointFile ) {
+ $count = substr_count ( $checkpointFile, "%s" );
+ if ( $count != 2 ) {
+ throw new MWException( "Option checkpointfile must contain two '%s' for substitution of first and last pageids, count is $count instead, file is $checkpointFile.\n" );
+ }
+ }
+
+ if ( $this->checkpointFiles ) {
+ $filenameList = (array)$this->egress->getFilenames();
+ if ( count( $filenameList ) != count( $this->checkpointFiles ) ) {
+ throw new MWException( "One checkpointfile must be specified for each output option, if maxtime is used.\n" );
+ }
+ }
+ }
+
+ /**
+ * @throws MWException Failure to parse XML input
+ * @return true
+ */
+ function readDump( $input ) {
+ $this->buffer = "";
+ $this->openElement = false;
+ $this->atStart = true;
+ $this->state = "";
+ $this->lastName = "";
+ $this->thisPage = 0;
+ $this->thisRev = 0;
+
+ $parser = xml_parser_create( "UTF-8" );
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ xml_set_element_handler( $parser, array( &$this, 'startElement' ), array( &$this, 'endElement' ) );
+ xml_set_character_data_handler( $parser, array( &$this, 'characterData' ) );
+
+ $offset = 0; // for context extraction on error reporting
+ $bufferSize = 512 * 1024;
+ do {
+ if ( $this->checkIfTimeExceeded() ) {
+ $this->setTimeExceeded();
+ }
+ $chunk = fread( $input, $bufferSize );
+ if ( !xml_parse( $parser, $chunk, feof( $input ) ) ) {
+ wfDebug( "TextDumpPass::readDump encountered XML parsing error\n" );
+
+ $byte = xml_get_current_byte_index( $parser );
+ $msg = wfMessage( 'xml-error-string',
+ 'XML import parse failure',
+ xml_get_current_line_number( $parser ),
+ xml_get_current_column_number( $parser ),
+ $byte . ( is_null( $chunk ) ? null : ( '; "' . substr( $chunk, $byte -$offset, 16 ) . '"' ) ),
+ xml_error_string( xml_get_error_code( $parser ) ) )->escaped();
+
+ xml_parser_free( $parser );
+
+ throw new MWException( $msg );
+ }
+ $offset += strlen( $chunk );
+ } while ( $chunk !== false && !feof( $input ) );
+ if ( $this->maxTimeAllowed ) {
+ $filenameList = (array)$this->egress->getFilenames();
+ // we wrote some stuff after last checkpoint that needs renamed
+ if ( file_exists( $filenameList[0] ) ) {
+ $newFilenames = array();
+ # we might have just written the header and footer and had no
+ # pages or revisions written... perhaps they were all deleted
+ # there's no pageID 0 so we use that. the caller is responsible
+ # for deciding what to do with a file containing only the
+ # siteinfo information and the mw tags.
+ if ( ! $this->firstPageWritten ) {
+ $firstPageID = str_pad( 0, 9, "0", STR_PAD_LEFT );
+ $lastPageID = str_pad( 0, 9, "0", STR_PAD_LEFT );
+ }
+ else {
+ $firstPageID = str_pad( $this->firstPageWritten, 9, "0", STR_PAD_LEFT );
+ $lastPageID = str_pad( $this->lastPageWritten, 9, "0", STR_PAD_LEFT );
+ }
+ for ( $i = 0; $i < count( $filenameList ); $i++ ) {
+ $checkpointNameFilledIn = sprintf( $this->checkpointFiles[$i], $firstPageID, $lastPageID );
+ $fileinfo = pathinfo( $filenameList[$i] );
+ $newFilenames[] = $fileinfo['dirname'] . '/' . $checkpointNameFilledIn;
+ }
+ $this->egress->closeAndRename( $newFilenames );
+ }
+ }
+ xml_parser_free( $parser );
+
+ return true;
+ }
+
+ /**
+ * Tries to get the revision text for a revision id.
+ *
+ * Upon errors, retries (Up to $this->maxFailures tries each call).
+ * If still no good revision get could be found even after this retrying, "" is returned.
+ * If no good revision text could be returned for
+ * $this->maxConsecutiveFailedTextRetrievals consecutive calls to getText, MWException
+ * is thrown.
+ *
+ * @param $id string The revision id to get the text for
+ *
+ * @return string The revision text for $id, or ""
+ * @throws MWException
+ */
+ function getText( $id ) {
+ $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.
+
+ static $consecutiveFailedTextRetrievals = 0; // The number of times getText failed without
+ // yielding a good text in between.
+
+ $this->fetchCount++;
+
+ // To allow to simply return on success and do not have to worry about book keeping,
+ // we assume, this fetch works (possible after some retries). Nevertheless, we koop
+ // the old value, so we can restore it, if problems occur (See after the while loop).
+ $oldConsecutiveFailedTextRetrievals = $consecutiveFailedTextRetrievals;
+ $consecutiveFailedTextRetrievals = 0;
+
+ while ( $failures < $this->maxFailures ) {
+
+ // As soon as we found a good text for the $id, we will return immediately.
+ // Hence, if we make it past the try catch block, we know that we did not
+ // find a good text.
+
+ try {
+ // Step 1: Get some text (or reuse from previous iteratuon if checking
+ // for plausibility failed)
+
+ // Trying to get prefetch, if it has not been tried before
+ if ( $text === false && isset( $this->prefetch ) && $prefetchNotTried ) {
+ $prefetchNotTried = false;
+ $tryIsPrefetch = true;
+ $text = $this->prefetch->prefetch( intval( $this->thisPage ),
+ intval( $this->thisRev ) );
+ if ( $text === null ) {
+ $text = false;
+ }
+ }
+
+ if ( $text === false ) {
+ // Fallback to asking the database
+ $tryIsPrefetch = false;
+ if ( $this->spawn ) {
+ $text = $this->getTextSpawned( $id );
+ } else {
+ $text = $this->getTextDb( $id );
+ }
+
+ // No more checks for texts from DB for now.
+ // If we received something that is not false,
+ // We treat it as good text, regardless of whether it actually is or is not
+ if ( $text !== false ) {
+ return $text;
+ }
+ }
+
+ if ( $text === false ) {
+ throw new MWException( "Generic error while obtaining text for id " . $id );
+ }
+
+ // We received a good candidate for the text of $id via some method
+
+ // Step 2: Checking for plausibility and return the text if it is
+ // plausible
+ $revID = intval( $this->thisRev );
+ if ( ! isset( $this->db ) ) {
+ throw new MWException( "No database available" );
+ }
+ $revLength = $this->db->selectField( 'revision', 'rev_len', array( 'rev_id' => $revID ) );
+ if ( strlen( $text ) == $revLength ) {
+ if ( $tryIsPrefetch ) {
+ $this->prefetchCount++;
+ }
+ return $text;
+ }
+
+ $text = false;
+ throw new MWException( "Received text is unplausible for id " . $id );
+
+ } catch ( Exception $e ) {
+ $msg = "getting/checking text " . $id . " failed (" . $e->getMessage() . ")";
+ if ( $failures + 1 < $this->maxFailures ) {
+ $msg .= " (Will retry " . ( $this->maxFailures - $failures - 1 ) . " more times)";
+ }
+ $this->progress( $msg );
+ }
+
+ // Something went wrong; we did not a text that was plausible :(
+ $failures++;
+
+ // A failure in a prefetch hit does not warrant resetting db connection etc.
+ if ( ! $tryIsPrefetch ) {
+ // After backing off for some time, we try to reboot the whole process as
+ // much as possible to not carry over failures from one part to the other
+ // parts
+ sleep( $this->failureTimeout );
+ try {
+ $this->rotateDb();
+ if ( $this->spawn ) {
+ $this->closeSpawn();
+ $this->openSpawn();
+ }
+ } catch ( Exception $e ) {
+ $this->progress( "Rebooting getText infrastructure failed (" . $e->getMessage() . ")" .
+ " Trying to continue anyways" );
+ }
+ }
+ }
+
+ // Retirieving a good text for $id failed (at least) maxFailures times.
+ // We abort for this $id.
+
+ // Restoring the consecutive failures, and maybe aborting, if the dump
+ // is too broken.
+ $consecutiveFailedTextRetrievals = $oldConsecutiveFailedTextRetrievals + 1;
+ if ( $consecutiveFailedTextRetrievals > $this->maxConsecutiveFailedTextRetrievals ) {
+ throw new MWException( "Graceful storage failure" );
+ }
+
+ return "";
+ }
+
+
+ /**
+ * May throw a database error if, say, the server dies during query.
+ * @param $id
+ * @return bool|string
+ * @throws MWException
+ */
+ private function getTextDb( $id ) {
+ global $wgContLang;
+ if ( ! isset( $this->db ) ) {
+ throw new MWException( __METHOD__ . "No database available" );
+ }
+ $row = $this->db->selectRow( 'text',
+ array( 'old_text', 'old_flags' ),
+ array( 'old_id' => $id ),
+ __METHOD__ );
+ $text = Revision::getRevisionText( $row );
+ if ( $text === false ) {
+ return false;
+ }
+ $stripped = str_replace( "\r", "", $text );
+ $normalized = $wgContLang->normalize( $stripped );
+ return $normalized;
+ }
+
+ private function getTextSpawned( $id ) {
+ wfSuppressWarnings();
+ if ( !$this->spawnProc ) {
+ // First time?
+ $this->openSpawn();
+ }
+ $text = $this->getTextSpawnedOnce( $id );
+ wfRestoreWarnings();
+ return $text;
+ }
+
+ function openSpawn() {
+ global $IP;
+
+ if ( file_exists( "$IP/../multiversion/MWScript.php" ) ) {
+ $cmd = implode( " ",
+ array_map( 'wfEscapeShellArg',
+ array(
+ $this->php,
+ "$IP/../multiversion/MWScript.php",
+ "fetchText.php",
+ '--wiki', wfWikiID() ) ) );
+ }
+ else {
+ $cmd = implode( " ",
+ array_map( 'wfEscapeShellArg',
+ array(
+ $this->php,
+ "$IP/maintenance/fetchText.php",
+ '--wiki', wfWikiID() ) ) );
+ }
+ $spec = array(
+ 0 => array( "pipe", "r" ),
+ 1 => array( "pipe", "w" ),
+ 2 => array( "file", "/dev/null", "a" ) );
+ $pipes = array();
+
+ $this->progress( "Spawning database subprocess: $cmd" );
+ $this->spawnProc = proc_open( $cmd, $spec, $pipes );
+ if ( !$this->spawnProc ) {
+ // shit
+ $this->progress( "Subprocess spawn failed." );
+ return false;
+ }
+ list(
+ $this->spawnWrite, // -> stdin
+ $this->spawnRead, // <- stdout
+ ) = $pipes;
+
+ return true;
+ }
+
+ private function closeSpawn() {
+ wfSuppressWarnings();
+ if ( $this->spawnRead )
+ fclose( $this->spawnRead );
+ $this->spawnRead = false;
+ if ( $this->spawnWrite )
+ fclose( $this->spawnWrite );
+ $this->spawnWrite = false;
+ if ( $this->spawnErr )
+ fclose( $this->spawnErr );
+ $this->spawnErr = false;
+ if ( $this->spawnProc )
+ pclose( $this->spawnProc );
+ $this->spawnProc = false;
+ wfRestoreWarnings();
+ }
+
+ private function getTextSpawnedOnce( $id ) {
+ global $wgContLang;
+
+ $ok = fwrite( $this->spawnWrite, "$id\n" );
+ // $this->progress( ">> $id" );
+ if ( !$ok ) return false;
+
+ $ok = fflush( $this->spawnWrite );
+ // $this->progress( ">> [flush]" );
+ 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
+ $newId = fgets( $this->spawnRead );
+ if ( $newId === false ) {
+ return false;
+ }
+ if ( $id != intval( $newId ) ) {
+ return false;
+ }
+
+ $len = fgets( $this->spawnRead );
+ // $this->progress( "<< " . trim( $len ) );
+ if ( $len === false ) return false;
+
+ $nbytes = intval( $len );
+ // actual error, not zero-length text
+ 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;
+ $text .= $buffer;
+ }
+
+ $gotbytes = strlen( $text );
+ if ( $gotbytes != $nbytes ) {
+ $this->progress( "Expected $nbytes bytes from database subprocess, got $gotbytes " );
+ return false;
+ }
+
+ // Do normalization in the dump thread...
+ $stripped = str_replace( "\r", "", $text );
+ $normalized = $wgContLang->normalize( $stripped );
+ return $normalized;
+ }
+
+ function startElement( $parser, $name, $attribs ) {
+ $this->checkpointJustWritten = false;
+
+ $this->clearOpenElement( null );
+ $this->lastName = $name;
+
+ if ( $name == 'revision' ) {
+ $this->state = $name;
+ $this->egress->writeOpenPage( null, $this->buffer );
+ $this->buffer = "";
+ } elseif ( $name == 'page' ) {
+ $this->state = $name;
+ if ( $this->atStart ) {
+ $this->egress->writeOpenStream( $this->buffer );
+ $this->buffer = "";
+ $this->atStart = false;
+ }
+ }
+
+ if ( $name == "text" && isset( $attribs['id'] ) ) {
+ $text = $this->getText( $attribs['id'] );
+ $this->openElement = array( $name, array( 'xml:space' => 'preserve' ) );
+ if ( strlen( $text ) > 0 ) {
+ $this->characterData( $parser, $text );
+ }
+ } else {
+ $this->openElement = array( $name, $attribs );
+ }
+ }
+
+ function endElement( $parser, $name ) {
+ $this->checkpointJustWritten = false;
+
+ if ( $this->openElement ) {
+ $this->clearOpenElement( "" );
+ } else {
+ $this->buffer .= "</$name>";
+ }
+
+ if ( $name == 'revision' ) {
+ $this->egress->writeRevision( null, $this->buffer );
+ $this->buffer = "";
+ $this->thisRev = "";
+ } elseif ( $name == 'page' ) {
+ if ( ! $this->firstPageWritten ) {
+ $this->firstPageWritten = trim( $this->thisPage );
+ }
+ $this->lastPageWritten = trim( $this->thisPage );
+ if ( $this->timeExceeded ) {
+ $this->egress->writeClosePage( $this->buffer );
+ // nasty hack, we can't just write the chardata after the
+ // page tag, it will include leading blanks from the next line
+ $this->egress->sink->write( "\n" );
+
+ $this->buffer = $this->xmlwriterobj->closeStream();
+ $this->egress->writeCloseStream( $this->buffer );
+
+ $this->buffer = "";
+ $this->thisPage = "";
+ // this could be more than one file if we had more than one output arg
+
+ $filenameList = (array)$this->egress->getFilenames();
+ $newFilenames = array();
+ $firstPageID = str_pad( $this->firstPageWritten, 9, "0", STR_PAD_LEFT );
+ $lastPageID = str_pad( $this->lastPageWritten, 9, "0", STR_PAD_LEFT );
+ for ( $i = 0; $i < count( $filenameList ); $i++ ) {
+ $checkpointNameFilledIn = sprintf( $this->checkpointFiles[$i], $firstPageID, $lastPageID );
+ $fileinfo = pathinfo( $filenameList[$i] );
+ $newFilenames[] = $fileinfo['dirname'] . '/' . $checkpointNameFilledIn;
+ }
+ $this->egress->closeRenameAndReopen( $newFilenames );
+ $this->buffer = $this->xmlwriterobj->openStream();
+ $this->timeExceeded = false;
+ $this->timeOfCheckpoint = $this->lastTime;
+ $this->firstPageWritten = false;
+ $this->checkpointJustWritten = true;
+ }
+ else {
+ $this->egress->writeClosePage( $this->buffer );
+ $this->buffer = "";
+ $this->thisPage = "";
+ }
+
+ } elseif ( $name == 'mediawiki' ) {
+ $this->egress->writeCloseStream( $this->buffer );
+ $this->buffer = "";
+ }
+ }
+
+ function characterData( $parser, $data ) {
+ $this->clearOpenElement( null );
+ if ( $this->lastName == "id" ) {
+ if ( $this->state == "revision" ) {
+ $this->thisRev .= $data;
+ } elseif ( $this->state == "page" ) {
+ $this->thisPage .= $data;
+ }
+ }
+ // have to skip the newline left over from closepagetag line of
+ // end of checkpoint files. nasty hack!!
+ if ( $this->checkpointJustWritten ) {
+ if ( $data[0] == "\n" ) {
+ $data = substr( $data, 1 );
+ }
+ $this->checkpointJustWritten = false;
+ }
+ $this->buffer .= htmlspecialchars( $data );
+ }
+
+ function clearOpenElement( $style ) {
+ if ( $this->openElement ) {
+ $this->buffer .= Xml::element( $this->openElement[0], $this->openElement[1], $style );
+ $this->openElement = false;
+ }
+ }
+}
diff --git a/maintenance/benchmarks/Benchmarker.php b/maintenance/benchmarks/Benchmarker.php
index 0056c3c7..c198e0ff 100644
--- a/maintenance/benchmarks/Benchmarker.php
+++ b/maintenance/benchmarks/Benchmarker.php
@@ -5,7 +5,7 @@
*/
/**
- * Create a doxygen subgroup of Maintenance for benchmarks
+ * Base code for benchmark scripts.
*
* 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
@@ -27,7 +27,13 @@
* @ingroup Benchmark
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+
+/**
+ * Base class for benchmark scripts.
+ *
+ * @ingroup Benchmark
+ */
abstract class Benchmarker extends Maintenance {
private $results;
@@ -47,11 +53,11 @@ abstract class Benchmarker extends Maintenance {
}
$bench_number++;
- $start = wfTime();
+ $start = microtime( true );
for( $i=0; $i<$count; $i++ ) {
call_user_func_array( $bench['function'], $bench['args'] );
}
- $delta = wfTime() - $start;
+ $delta = microtime( true ) - $start;
// function passed as a callback
if( is_array( $bench['function'] ) ) {
@@ -61,7 +67,7 @@ abstract class Benchmarker extends Maintenance {
$this->results[$bench_number] = array(
'function' => $bench['function'],
- 'arguments' => $bench['args'],
+ 'arguments' => $bench['args'],
'count' => $count,
'delta' => $delta,
'average' => $delta / $count,
diff --git a/maintenance/benchmarks/bench_HTTP_HTTPS.php b/maintenance/benchmarks/bench_HTTP_HTTPS.php
index cf62aadb..fa76ae22 100644
--- a/maintenance/benchmarks/bench_HTTP_HTTPS.php
+++ b/maintenance/benchmarks/bench_HTTP_HTTPS.php
@@ -1,6 +1,8 @@
<?php
/**
- * This come from r75429 message
+ * Benchmark HTTP request vs HTTPS request.
+ *
+ * This come from r75429 message.
*
* 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
@@ -22,7 +24,13 @@
* @author Platonides
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+
+/**
+ * Maintenance script that benchmarks HTTP request vs HTTPS request.
+ *
+ * @ingroup Benchmark
+ */
class bench_HTTP_HTTPS extends Benchmarker {
public function __construct() {
diff --git a/maintenance/benchmarks/bench_delete_truncate.php b/maintenance/benchmarks/bench_delete_truncate.php
index 71385520..d9741496 100644
--- a/maintenance/benchmarks/bench_delete_truncate.php
+++ b/maintenance/benchmarks/bench_delete_truncate.php
@@ -1,11 +1,33 @@
<?php
/**
+ * Benchmark SQL DELETE vs SQL TRUNCATE.
+ *
+ * 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 Benchmark
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+/**
+ * Maintenance script that benchmarks SQL DELETE vs SQL TRUNCATE.
+ *
+ * @ingroup Benchmark
+ */
class BenchmarkDeleteTruncate extends Benchmarker {
public function __construct() {
@@ -24,24 +46,24 @@ class BenchmarkDeleteTruncate extends Benchmarker {
$this->insertData( $dbw );
- $start = wfTime();
+ $start = microtime( true );
$this->delete( $dbw );
- $end = wfTime();
+ $end = microtime( true );
- echo "Delete: " . $end - $start;
+ echo "Delete: " . sprintf( "%6.3fms", ( $end - $start ) * 1000 );
echo "\r\n";
$this->insertData( $dbw );
- $start = wfTime();
+ $start = microtime( true );
$this->truncate( $dbw );
- $end = wfTime();
+ $end = microtime( true );
- echo "Truncate: " . $end - $start;
+ echo "Truncate: " . sprintf( "%6.3fms", ( $end - $start ) * 1000 );
echo "\r\n";
$dbw->dropTable( 'test' );
diff --git a/maintenance/benchmarks/bench_if_switch.php b/maintenance/benchmarks/bench_if_switch.php
index dafce050..1f590d4d 100644
--- a/maintenance/benchmarks/bench_if_switch.php
+++ b/maintenance/benchmarks/bench_if_switch.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Benchmark if elseif... versus switch case.
+ *
* This come from r75429 message
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +24,13 @@
* @author Platonides
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+
+/**
+ * Maintenance script that benchmark if elseif... versus switch case.
+ *
+ * @ingroup Maintenance
+ */
class bench_if_switch extends Benchmarker {
public function __construct() {
diff --git a/maintenance/benchmarks/bench_strtr_str_replace.php b/maintenance/benchmarks/bench_strtr_str_replace.php
index 73ace2bd..9fa7c8e3 100644
--- a/maintenance/benchmarks/bench_strtr_str_replace.php
+++ b/maintenance/benchmarks/bench_strtr_str_replace.php
@@ -1,10 +1,29 @@
<?php
/**
+ * Benchmark for strtr() vs str_replace().
+ *
+ * This come from r75429 message.
+ *
+ * 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 Benchmark
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
function bfNormalizeTitleStrTr( $str ) {
return strtr( $str, '_', ' ' );
@@ -14,6 +33,11 @@ function bfNormalizeTitleStrReplace( $str ) {
return str_replace( '_', ' ', $str );
}
+/**
+ * Maintenance script that benchmarks for strtr() vs str_replace().
+ *
+ * @ingroup Benchmark
+ */
class bench_strtr_str_replace extends Benchmarker {
public function __construct() {
diff --git a/maintenance/benchmarks/bench_utf8_title_check.php b/maintenance/benchmarks/bench_utf8_title_check.php
new file mode 100644
index 00000000..f5987800
--- /dev/null
+++ b/maintenance/benchmarks/bench_utf8_title_check.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Benchmark for using a regexp vs. mb_check_encoding to check for UTF-8 encoding.
+ *
+ * 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 Benchmark
+ */
+
+require_once( __DIR__ . '/Benchmarker.php' );
+
+/**
+ * This little benchmark executes the regexp used in Language->checkTitleEncoding()
+ * and compares its execution time against that of mb_check_encoding, if available.
+ *
+ * @ingroup Benchmark
+ */
+class bench_utf8_title_check extends Benchmarker {
+
+ private $canRun;
+
+ private $data;
+
+ public function __construct() {
+ parent::__construct();
+
+ $this->data = array (
+ "",
+ "United States of America", // 7bit ASCII
+ "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e",
+ "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn",
+ // This comes from bug 36839
+ "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
+ . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
+ . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
+ . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
+ . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
+ . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
+ . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
+ . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
+ . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
+ . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
+ . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
+ . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
+ . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
+ . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
+ );
+
+ $this->canRun = function_exists ( 'mb_check_encoding' );
+
+ if ( $this->canRun ) {
+ $this->mDescription = "Benchmark for using a regexp vs. mb_check_encoding to check for UTF-8 encoding.";
+ mb_internal_encoding( 'UTF-8' );
+ } else {
+ $this->mDescription = "CANNOT RUN benchmark using mb_check_encoding: function not available.";
+ }
+ }
+
+ public function execute() {
+ if ( !$this->canRun ) {
+ return;
+ }
+ $benchmarks = array();
+ foreach ($this->data as $val) {
+ $benchmarks[] = array(
+ 'function' => array( $this, 'use_regexp' ),
+ 'args' => array( rawurldecode ( $val ) )
+ );
+ $benchmarks[] = array(
+ 'function' => array( $this, 'use_regexp_non_capturing' ),
+ 'args' => array( rawurldecode ( $val ) )
+ );
+ $benchmarks[] = array(
+ 'function' => array( $this, 'use_regexp_once_only' ),
+ 'args' => array( rawurldecode ( $val ) )
+ );
+ $benchmarks[] = array(
+ 'function' => array( $this, 'use_mb_check_encoding' ),
+ 'args' => array( rawurldecode ( $val ) )
+ );
+ }
+ $this->bench( $benchmarks );
+ print $this->getFormattedResults();
+ }
+
+ private $isutf8;
+
+ function use_regexp( $s ) {
+ $this->isutf8 = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+ }
+
+ function use_regexp_non_capturing( $s ) {
+ // Same as above with a non-capturing subgroup.
+ $this->isutf8 = preg_match( '/^(?:[\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+ }
+
+ function use_regexp_once_only( $s ) {
+ // Same as above with a once-only subgroup.
+ $this->isutf8 = preg_match( '/^(?>[\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
+ '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
+ }
+
+ function use_mb_check_encoding( $s ) {
+ $this->isutf8 = mb_check_encoding( $s, 'UTF-8' );
+ }
+
+}
+
+$maintClass = 'bench_utf8_title_check';
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/benchmarks/bench_wfIsWindows.php b/maintenance/benchmarks/bench_wfIsWindows.php
index 4caebc5e..85439827 100644
--- a/maintenance/benchmarks/bench_wfIsWindows.php
+++ b/maintenance/benchmarks/bench_wfIsWindows.php
@@ -1,6 +1,8 @@
<?php
/**
- * This come from r75429 message
+ * Benchmark for wfIsWindows().
+ *
+ * This come from r75429 message.
*
* 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
@@ -22,7 +24,13 @@
* @author Platonides
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+
+/**
+ * Maintenance script that benchmarks wfIsWindows().
+ *
+ * @ingroup Benchmark
+ */
class bench_wfIsWindows extends Benchmarker {
public function __construct() {
diff --git a/maintenance/benchmarks/benchmarkHooks.php b/maintenance/benchmarks/benchmarkHooks.php
index 4ec26168..fdb016f4 100644
--- a/maintenance/benchmarks/benchmarkHooks.php
+++ b/maintenance/benchmarks/benchmarkHooks.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Benchmark %MediaWiki hooks.
+ *
* 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
@@ -19,8 +21,13 @@
* @ingroup Benchmark
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+/**
+ * Maintenance script that benchmarks %MediaWiki hooks.
+ *
+ * @ingroup Benchmark
+ */
class BenchmarkHooks extends Benchmarker {
public function __construct() {
@@ -58,14 +65,14 @@ class BenchmarkHooks extends Benchmarker {
* @return string
*/
private function benchHooks( $trials = 10 ) {
- $start = wfTime();
+ $start = microtime( true );
for ( $i = 0; $i < $trials; $i++ ) {
wfRunHooks( 'Test' );
}
- $delta = wfTime() - $start;
+ $delta = microtime( true ) - $start;
$pertrial = $delta / $trials;
- return sprintf( "Took %6.2fs",
- $pertrial );
+ return sprintf( "Took %6.3fms",
+ $pertrial * 1000 );
}
/**
diff --git a/maintenance/benchmarks/benchmarkPurge.php b/maintenance/benchmarks/benchmarkPurge.php
index e9d2ec7a..ec686b2a 100644
--- a/maintenance/benchmarks/benchmarkPurge.php
+++ b/maintenance/benchmarks/benchmarkPurge.php
@@ -1,6 +1,6 @@
<?php
/**
- * Squid purge benchmark script
+ * Benchmark for Squid purge.
*
* 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
@@ -21,8 +21,13 @@
* @ingroup Benchmark
*/
-require_once( dirname( __FILE__ ) . '/Benchmarker.php' );
+require_once( __DIR__ . '/Benchmarker.php' );
+/**
+ * Maintenance script that benchmarks Squid purge.
+ *
+ * @ingroup Benchmark
+ */
class BenchmarkPurge extends Benchmarker {
public function __construct() {
@@ -57,11 +62,11 @@ class BenchmarkPurge extends Benchmarker {
* @return string
*/
private function benchSquid( $urls, $trials = 1 ) {
- $start = wfTime();
+ $start = microtime( true );
for ( $i = 0; $i < $trials; $i++ ) {
SquidUpdate::purge( $urls );
}
- $delta = wfTime() - $start;
+ $delta = microtime( true ) - $start;
$pertrial = $delta / $trials;
$pertitle = $pertrial / count( $urls );
return sprintf( "%4d titles in %6.2fms (%6.2fms each)",
diff --git a/maintenance/cdb.php b/maintenance/cdb.php
index 270f7a60..c06c2cd0 100644
--- a/maintenance/cdb.php
+++ b/maintenance/cdb.php
@@ -23,7 +23,7 @@
*/
/** */
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
function cdbShowHelp( $command ) {
$commandList = array(
diff --git a/maintenance/changePassword.php b/maintenance/changePassword.php
index cfcac406..f276fc16 100644
--- a/maintenance/changePassword.php
+++ b/maintenance/changePassword.php
@@ -24,8 +24,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to change the password of a given user.
+ *
+ * @ingroup Maintenance
+ */
class ChangePassword extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/checkAutoLoader.php b/maintenance/checkAutoLoader.php
index d199b6fe..8d0e442b 100644
--- a/maintenance/checkAutoLoader.php
+++ b/maintenance/checkAutoLoader.php
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to check classes definitions in the autoloader.
+ *
+ * @ingroup Maintenance
+ */
class CheckAutoLoader extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/checkBadRedirects.php b/maintenance/checkBadRedirects.php
index bac2ff69..670b93de 100644
--- a/maintenance/checkBadRedirects.php
+++ b/maintenance/checkBadRedirects.php
@@ -1,7 +1,6 @@
<?php
/**
- * CheckBadRedirects - See if pages marked as being redirects
- * really are.
+ * Check that pages marked as being redirects really are.
*
* 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
@@ -22,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to check that pages marked as being redirects really are.
+ *
+ * @ingroup Maintenance
+ */
class CheckBadRedirects extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/checkImages.php b/maintenance/checkImages.php
index 484217d9..c05d9151 100644
--- a/maintenance/checkImages.php
+++ b/maintenance/checkImages.php
@@ -1,6 +1,6 @@
<?php
/**
- * Check images to see if they exist, are readable, etc etc
+ * Check images to see if they exist, are readable, etc.
*
* 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,8 +20,13 @@
* @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to check images to see if they exist, are readable, etc.
+ *
+ * @ingroup Maintenance
+ */
class CheckImages extends Maintenance {
public function __construct() {
diff --git a/maintenance/checkSyntax.php b/maintenance/checkSyntax.php
index cc4e5af5..0a22f58c 100644
--- a/maintenance/checkSyntax.php
+++ b/maintenance/checkSyntax.php
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to check syntax of all PHP files in MediaWiki.
+ *
+ * @ingroup Maintenance
+ */
class CheckSyntax extends Maintenance {
// List of files we're going to check
@@ -36,7 +41,7 @@ class CheckSyntax extends Maintenance {
$this->addOption( 'path', 'Specific path (file or directory) to check, either with absolute path or relative to the root of this MediaWiki installation',
false, true );
$this->addOption( 'list-file', 'Text file containing list of files or directories to check', false, true );
- $this->addOption( 'modified', 'Check only files that were modified (requires SVN command-line client)' );
+ $this->addOption( 'modified', 'Check only files that were modified (requires Git command-line client)' );
$this->addOption( 'syntax-only', 'Check for syntax validity only, skip code style warnings' );
}
@@ -114,18 +119,10 @@ class CheckSyntax extends Maintenance {
fclose( $f );
return;
} elseif ( $this->hasOption( 'modified' ) ) {
- $this->output( "Retrieving list from Subversion... " );
- $parentDir = wfEscapeShellArg( dirname( __FILE__ ) . '/..' );
- $retval = null;
- $output = wfShellExec( "svn status --ignore-externals $parentDir", $retval );
- if ( $retval ) {
- $this->error( "Error retrieving list from Subversion!\n", true );
- } else {
- $this->output( "done\n" );
- }
-
- preg_match_all( '/^\s*[AM].{7}(.*?)\r?$/m', $output, $matches );
- foreach ( $matches[1] as $file ) {
+ $this->output( "Retrieving list from Git... " );
+ $files = $this->getGitModifiedFiles( $IP );
+ $this->output( "done\n" );
+ foreach ( $files as $file ) {
if ( $this->isSuitableFile( $file ) && !is_dir( $file ) ) {
$this->mFiles[] = $file;
}
@@ -164,6 +161,59 @@ class CheckSyntax extends Maintenance {
}
/**
+ * Returns a list of tracked files in a Git work tree differing from the master branch.
+ * @param $path string: Path to the repository
+ * @return array: Resulting list of changed files
+ */
+ private function getGitModifiedFiles( $path ) {
+
+ global $wgMaxShellMemory;
+
+ if ( !is_dir( "$path/.git" ) ) {
+ $this->error( "Error: Not a Git repository!\n", true );
+ }
+
+ // git diff eats memory.
+ $oldMaxShellMemory = $wgMaxShellMemory;
+ if ( $wgMaxShellMemory < 1024000 ) {
+ $wgMaxShellMemory = 1024000;
+ }
+
+ $ePath = wfEscapeShellArg( $path );
+
+ // Find an ancestor in common with master (rather than just using its HEAD)
+ // to prevent files only modified there from showing up in the list.
+ $cmd = "cd $ePath && git merge-base master HEAD";
+ $retval = 0;
+ $output = wfShellExec( $cmd, $retval );
+ if ( $retval !== 0 ) {
+ $this->error( "Error retrieving base SHA1 from Git!\n", true );
+ }
+
+ // Find files in the working tree that changed since then.
+ $eBase = wfEscapeShellArg( rtrim( $output, "\n" ) );
+ $cmd = "cd $ePath && git diff --name-only --diff-filter AM $eBase";
+ $retval = 0;
+ $output = wfShellExec( $cmd, $retval );
+ if ( $retval !== 0 ) {
+ $this->error( "Error retrieving list from Git!\n", true );
+ }
+
+ $wgMaxShellMemory = $oldMaxShellMemory;
+
+ $arr = array();
+ $filename = strtok( $output, "\n" );
+ while ( $filename !== false ) {
+ if ( $filename !== '' ) {
+ $arr[] = "$path/$filename";
+ }
+ $filename = strtok( "\n" );
+ }
+
+ return $arr;
+ }
+
+ /**
* Returns true if $file is of a type we can check
* @param $file string
* @return bool
diff --git a/maintenance/checkUsernames.php b/maintenance/checkUsernames.php
index 9b98721d..dd5e0022 100644
--- a/maintenance/checkUsernames.php
+++ b/maintenance/checkUsernames.php
@@ -1,8 +1,6 @@
<?php
/**
- * This script verifies that database usernames are actually valid.
- * An existing usernames can become invalid if User::isValidUserName()
- * is altered or if we change the $wgMaxNameChars
+ * Check that database usernames are actually valid.
*
* 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
@@ -24,8 +22,16 @@
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to check that database usernames are actually valid.
+ *
+ * An existing usernames can become invalid if User::isValidUserName()
+ * is altered or if we change the $wgMaxNameChars
+ *
+ * @ingroup Maintenance
+ */
class CheckUsernames extends Maintenance {
public function __construct() {
diff --git a/maintenance/cleanupAncientTables.php b/maintenance/cleanupAncientTables.php
new file mode 100644
index 00000000..dbc2e0d3
--- /dev/null
+++ b/maintenance/cleanupAncientTables.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Cleans up old database tables, dropping old indexes and fields.
+ *
+ * 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 to cleans up old database tables, dropping old indexes
+ * and fields.
+ *
+ * @ingroup Maintenance
+ */
+class CleanupAncientTables extends Maintenance {
+
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Cleanup ancient tables and indexes";
+ $this->addOption( 'force', 'Actually run this script' );
+ }
+
+ public function execute() {
+ 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"
+ );
+ }
+
+ $db = wfGetDB( DB_MASTER );
+ $ancientTables = array(
+ 'blobs', // 1.4
+ 'brokenlinks', // 1.4
+ 'cur', // 1.4
+ 'ip_blocks_old', // Temporary in 1.6
+ 'links', // 1.4
+ 'linkscc', // 1.4
+ // 'math', // 1.18, but don't want to drop if math extension is enabled...
+ 'old', // 1.4
+ 'oldwatchlist', // pre 1.1?
+ 'trackback', // 1.19
+ 'user_rights', // 1.5
+ 'validate', // 1.6
+ );
+
+ foreach( $ancientTables as $table ) {
+ if ( $db->tableExists( $table, __METHOD__ ) ) {
+ $this->output( "Dropping table $table..." );
+ $db->dropTable( $table, __METHOD__ );
+ $this->output( "done.\n" );
+ }
+ }
+
+ $this->output( "Cleaning up text table\n" );
+
+ $oldIndexes = array(
+ 'old_namespace',
+ 'old_timestamp',
+ 'name_title_timestamp',
+ 'user_timestamp',
+ 'usertext_timestamp',
+ );
+ 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 )
+ . " ON " . $db->tableName( 'text' ) );
+ $this->output( "done.\n" );
+ }
+ }
+
+ $oldFields = array(
+ 'old_namespace',
+ 'old_title',
+ 'old_comment',
+ 'old_user',
+ 'old_user_text',
+ 'old_timestamp',
+ 'old_minor_edit',
+ 'inverse_timestamp',
+ );
+ 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' )
+ . " DROP COLUMN " . $db->addIdentifierQuotes( $field ) );
+ $this->output( "done.\n" );
+ }
+ }
+ $this->output( "Done!\n" );
+ }
+}
+
+$maintClass = "CleanupAncientTables";
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/cleanupCaps.php b/maintenance/cleanupCaps.php
index 6f8e180c..ec2aa957 100644
--- a/maintenance/cleanupCaps.php
+++ b/maintenance/cleanupCaps.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to clean up broken page links when somebody turns on $wgCapitalLinks.
+ * Clean up broken page links when somebody turns on $wgCapitalLinks.
*
* Usage: php cleanupCaps.php [--dry-run]
* Options:
@@ -29,8 +29,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/cleanupTable.inc' );
+require_once( __DIR__ . '/cleanupTable.inc' );
+/**
+ * Maintenance script to clean up broken page links when somebody turns on $wgCapitalLinks.
+ *
+ * @ingroup Maintenance
+ */
class CapsCleanup extends TableCleanup {
public function __construct() {
parent::__construct();
diff --git a/maintenance/cleanupImages.php b/maintenance/cleanupImages.php
index 81d1c85b..4e7b937d 100644
--- a/maintenance/cleanupImages.php
+++ b/maintenance/cleanupImages.php
@@ -1,12 +1,12 @@
<?php
/**
- * Script to clean up broken, unparseable upload filenames.
+ * Clean up broken, unparseable upload filenames.
*
* Usage: php cleanupImages.php [--fix]
* Options:
* --fix Actually clean up titles; otherwise just checks for them
*
- * Copyright (C) 2005-2006 Brion Vibber <brion@pobox.com>
+ * Copyright © 2005-2006 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -29,8 +29,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/cleanupTable.inc' );
+require_once( __DIR__ . '/cleanupTable.inc' );
+/**
+ * Maintenance script to clean up broken, unparseable upload filenames.
+ *
+ * @ingroup Maintenance
+ */
class ImageCleanup extends TableCleanup {
protected $defaultParams = array(
'table' => 'image',
@@ -156,7 +161,7 @@ class ImageCleanup extends TableCleanup {
} else {
$this->output( "renaming $path to $finalPath\n" );
// @todo FIXME: Should this use File::move()?
- $db->begin();
+ $db->begin( __METHOD__ );
$db->update( 'image',
array( 'img_name' => $final ),
array( 'img_name' => $orig ),
@@ -173,15 +178,15 @@ class ImageCleanup extends TableCleanup {
if ( !file_exists( $dir ) ) {
if ( !wfMkdirParents( $dir, null, __METHOD__ ) ) {
$this->output( "RENAME FAILED, COULD NOT CREATE $dir" );
- $db->rollback();
+ $db->rollback( __METHOD__ );
return;
}
}
if ( rename( $path, $finalPath ) ) {
- $db->commit();
+ $db->commit( __METHOD__ );
} else {
$this->error( "RENAME FAILED" );
- $db->rollback();
+ $db->rollback( __METHOD__ );
}
}
}
@@ -192,9 +197,8 @@ class ImageCleanup extends TableCleanup {
}
private function buildSafeTitle( $name ) {
- global $wgLegalTitleChars;
$x = preg_replace_callback(
- "/([^$wgLegalTitleChars]|~)/",
+ '/([^' . Title::legalChars() . ']|~)/',
array( $this, 'hexChar' ),
$name );
diff --git a/maintenance/refreshImageCount.php b/maintenance/cleanupPreferences.php
index f9bdeea7..f37af775 100644
--- a/maintenance/refreshImageCount.php
+++ b/maintenance/cleanupPreferences.php
@@ -1,54 +1,52 @@
-<?php
-/**
- * Quickie hack; patch-ss_images.sql uses variables which don't
- * replicate properly.
- *
- * 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
- *
- * @ingroup Maintenance
- */
-
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-
-class RefreshImageCount extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->mDescription = "Resets ss_image count, forcing slaves to pick it up.";
- }
-
- public function execute() {
- $dbw = wfGetDB( DB_MASTER );
-
- // Load the current value from the master
- $count = $dbw->selectField( 'site_stats', 'ss_images' );
-
- $this->output( wfWikiID() . ": forcing ss_images to $count\n" );
-
- // First set to NULL so that it changes on the master
- $dbw->update( 'site_stats',
- array( 'ss_images' => null ),
- array( 'ss_row_id' => 1 ) );
-
- // Now this update will be forced to go out
- $dbw->update( 'site_stats',
- array( 'ss_images' => $count ),
- array( 'ss_row_id' => 1 ) );
- }
-}
-
-$maintClass = "RefreshImageCount";
-require_once( RUN_MAINTENANCE_IF_MAIN );
-
+<?php
+/**
+ * Remove hidden preferences from the database.
+ *
+ * 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
+ * @author TyA <tya.wiki@gmail.com>
+ * @see [[bugzilla:30976]]
+ * @ingroup Maintenance
+ */
+
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Maintenance script that removes hidden preferences from the database.
+ *
+ * @ingroup Maintenance
+ */
+class CleanupPreferences extends Maintenance {
+ public function execute() {
+ global $wgHiddenPrefs;
+
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+ foreach( $wgHiddenPrefs as $item ) {
+ $dbw->delete(
+ 'user_properties',
+ array( 'up_property' => $item ),
+ __METHOD__
+ );
+ };
+ $dbw->commit();
+ $this->output( "Finished!\n" );
+ }
+}
+
+$maintClass = 'CleanupPreferences'; // Tells it to run the class
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/cleanupRemovedModules.php b/maintenance/cleanupRemovedModules.php
index fb8afd2d..2085da94 100644
--- a/maintenance/cleanupRemovedModules.php
+++ b/maintenance/cleanupRemovedModules.php
@@ -1,7 +1,6 @@
<?php
/**
- * Maintenance script to remove cache entries for removed ResourceLoader modules
- * from the database
+ * Remove cache entries for removed ResourceLoader modules from the database.
*
* 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,8 +22,14 @@
* @author Roan Kattouw
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to remove cache entries for removed ResourceLoader modules
+ * from the database.
+ *
+ * @ingroup Maintenance
+ */
class CleanupRemovedModules extends Maintenance {
public function __construct() {
diff --git a/maintenance/cleanupSpam.php b/maintenance/cleanupSpam.php
index ca1e302b..e20bcd87 100644
--- a/maintenance/cleanupSpam.php
+++ b/maintenance/cleanupSpam.php
@@ -1,6 +1,6 @@
<?php
/**
- * Cleanup all spam from a given hostname
+ * Cleanup all spam from a given hostname.
*
* 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
@@ -21,20 +21,27 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to cleanup all spam from a given hostname.
+ *
+ * @ingroup Maintenance
+ */
class CleanupSpam extends Maintenance {
+
public function __construct() {
parent::__construct();
$this->mDescription = "Cleanup all spam from a given hostname";
$this->addOption( 'all', 'Check all wikis in $wgLocalDatabases' );
- $this->addArg( 'hostname', 'Hostname that was spamming' );
+ $this->addOption( 'delete', 'Delete pages containing only spam instead of blanking them' );
+ $this->addArg( 'hostname', 'Hostname that was spamming, single * wildcard in the beginning allowed' );
}
public function execute() {
global $wgLocalDatabases, $wgUser;
- $username = wfMsg( 'spambot_username' );
+ $username = wfMessage( 'spambot_username' )->text();
$wgUser = User::newFromName( $username );
if ( !$wgUser ) {
$this->error( "Invalid username", true );
@@ -106,19 +113,23 @@ class CleanupSpam extends Maintenance {
$this->output( "False match\n" );
} else {
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$page = WikiPage::factory( $title );
- if ( !$rev ) {
- // Didn't find a non-spammy revision, blank the page
- $this->output( "blanking\n" );
- $page->doEdit( '', wfMsgForContent( 'spam_blanking', $domain ) );
- } else {
+ if ( $rev ) {
// Revert to this revision
$this->output( "reverting\n" );
- $page->doEdit( $rev->getText(), wfMsgForContent( 'spam_reverting', $domain ),
+ $page->doEdit( $rev->getText(), wfMessage( 'spam_reverting', $domain )->inContentLanguage()->text(),
EDIT_UPDATE, $rev->getId() );
+ } elseif ( $this->hasOption( 'delete' ) ) {
+ // Didn't find a non-spammy revision, blank the page
+ $this->output( "deleting\n" );
+ $page->doDeleteArticle( wfMessage( 'spam_deleting', $domain )->inContentLanguage()->text() );
+ } else {
+ // Didn't find a non-spammy revision, blank the page
+ $this->output( "blanking\n" );
+ $page->doEdit( '', wfMessage( 'spam_blanking', $domain )->inContentLanguage()->text() );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
}
}
diff --git a/maintenance/cleanupTable.inc b/maintenance/cleanupTable.inc
index 1c279762..57acfd82 100644
--- a/maintenance/cleanupTable.inc
+++ b/maintenance/cleanupTable.inc
@@ -1,6 +1,6 @@
<?php
/**
- * Generic table cleanup class. Already subclasses maintenance
+ * Generic class to cleanup a database table.
*
* 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
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Generic class to cleanup a database table. Already subclasses Maintenance.
+ *
+ * @ingroup Maintenance
+ */
class TableCleanup extends Maintenance {
protected $defaultParams = array(
'table' => 'page',
@@ -57,7 +62,7 @@ class TableCleanup extends Maintenance {
$this->processed = 0;
$this->updated = 0;
$this->count = $count;
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
$this->table = $table;
}
@@ -70,7 +75,7 @@ class TableCleanup extends Maintenance {
$portion = $this->processed / $this->count;
$updateRate = $this->updated / $this->processed;
- $now = wfTime();
+ $now = microtime( true );
$delta = $now - $this->startTime;
$estimatedTotalTime = $delta / $portion;
$eta = $this->startTime + $estimatedTotalTime;
diff --git a/maintenance/cleanupTitles.php b/maintenance/cleanupTitles.php
index 4fc6415e..ad2577aa 100644
--- a/maintenance/cleanupTitles.php
+++ b/maintenance/cleanupTitles.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to clean up broken, unparseable titles.
+ * Clean up broken, unparseable titles.
*
* Usage: php cleanupTitles.php [--fix]
* Options:
@@ -29,8 +29,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/cleanupTable.inc' );
+require_once( __DIR__ . '/cleanupTable.inc' );
+/**
+ * Maintenance script to clean up broken, unparseable titles.
+ *
+ * @ingroup Maintenance
+ */
class TitleCleanup extends TableCleanup {
public function __construct() {
parent::__construct();
diff --git a/maintenance/cleanupUploadStash.php b/maintenance/cleanupUploadStash.php
index 5f57ffdf..cc329461 100644
--- a/maintenance/cleanupUploadStash.php
+++ b/maintenance/cleanupUploadStash.php
@@ -25,8 +25,14 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to remove old or broken uploads from temporary uploaded
+ * file storage and clean up associated database records.
+ *
+ * @ingroup Maintenance
+ */
class UploadStashCleanup extends Maintenance {
public function __construct() {
@@ -68,15 +74,21 @@ class UploadStashCleanup extends Maintenance {
// out-of-date someday
$stash = new UploadStash( $repo );
+ $i = 0;
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" );
}
+ if ( $i % 100 == 0 ) {
+ $this->output( "$i\n" );
+ }
}
- }
+ $this->output( "$i done\n" );
+ }
}
$maintClass = "UploadStashCleanup";
diff --git a/maintenance/cleanupWatchlist.php b/maintenance/cleanupWatchlist.php
index a9b20fea..fbab6a3c 100644
--- a/maintenance/cleanupWatchlist.php
+++ b/maintenance/cleanupWatchlist.php
@@ -1,12 +1,12 @@
<?php
/**
- * Script to remove broken, unparseable titles in the Watchlist.
+ * Remove broken, unparseable titles in the watchlist table.
*
* Usage: php cleanupWatchlist.php [--fix]
* Options:
* --fix Actually remove entries; without will only report.
*
- * Copyright (C) 2005,2006 Brion Vibber <brion@pobox.com>
+ * Copyright © 2005,2006 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -29,8 +29,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/cleanupTable.inc' );
+require_once( __DIR__ . '/cleanupTable.inc' );
+/**
+ * Maintenance script to remove broken, unparseable titles in the watchlist table.
+ *
+ * @ingroup Maintenance
+ */
class WatchlistCleanup extends TableCleanup {
protected $defaultParams = array(
'table' => 'watchlist',
diff --git a/maintenance/clear_interwiki_cache.php b/maintenance/clear_interwiki_cache.php
index 953bd4ce..88769df2 100644
--- a/maintenance/clear_interwiki_cache.php
+++ b/maintenance/clear_interwiki_cache.php
@@ -1,7 +1,6 @@
<?php
/**
- * This script is used to clear the interwiki links for ALL languages in
- * the cache.
+ * Clear the cache of interwiki prefixes for all local wikis.
*
* 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
@@ -22,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to clear the cache of interwiki prefixes for all local wikis.
+ *
+ * @ingroup Maintenance
+ */
class ClearInterwikiCache extends Maintenance {
public function __construct() {
diff --git a/maintenance/clear_stats.php b/maintenance/clear_stats.php
index 61314e67..4581d532 100644
--- a/maintenance/clear_stats.php
+++ b/maintenance/clear_stats.php
@@ -1,6 +1,6 @@
<?php
/**
- * This script remove all statistics tracking from the cache
+ * Removes all statistics tracking from the cache.
*
* 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
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to remove all statistics tracking from the cache.
+ *
+ * @ingroup Maintenance
+ */
class clear_stats extends Maintenance {
public function __construct() {
diff --git a/maintenance/commandLine.inc b/maintenance/commandLine.inc
index c7adbfbc..86a558d0 100644
--- a/maintenance/commandLine.inc
+++ b/maintenance/commandLine.inc
@@ -21,7 +21,7 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
global $optionsWithArgs;
if ( !isset( $optionsWithArgs ) ) {
diff --git a/maintenance/compareParsers.php b/maintenance/compareParsers.php
index 4fe4e4d0..a3337173 100644
--- a/maintenance/compareParsers.php
+++ b/maintenance/compareParsers.php
@@ -6,8 +6,9 @@
*
* Templates etc are pulled from the local wiki database, not from the dump.
*
- * Copyright (C) 2011 Platonides - http://www.mediawiki.org/
- *
+ * Copyright © 2011 Platonides
+ * http://www.mediawiki.org/
+ *
* 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
@@ -26,9 +27,15 @@
* @file
* @ingroup Maintenance
*/
-
-require_once( dirname( __FILE__ ) . '/dumpIterator.php' );
+require_once( __DIR__ . '/dumpIterator.php' );
+
+/**
+ * Maintenance script to take page text out of an XML dump file and render
+ * basic HTML out to files.
+ *
+ * @ingroup Maintenance
+ */
class CompareParsers extends DumpIterator {
private $count = 0;
@@ -51,10 +58,10 @@ class CompareParsers extends DumpIterator {
if ( $this->hasOption('save-failed') ) {
$this->saveFailed = $this->getOption('save-failed');
}
-
+
$this->stripParametersEnabled = $this->hasOption( 'strip-parameters' );
$this->showParsedOutput = $this->hasOption( 'show-parsed-output' );
-
+
$this->showDiff = $this->hasOption( 'show-diff' );
if ( $this->showDiff ) {
$bin = $this->getOption( 'diff-bin', getenv( 'DIFF' ) );
@@ -63,10 +70,10 @@ class CompareParsers extends DumpIterator {
$wgDiff = $bin;
}
}
-
- $user = new User();
+
+ $user = new User();
$this->options = ParserOptions::newFromUser( $user );
-
+
if ( $this->hasOption( 'tidy' ) ) {
global $wgUseTidy;
if ( !$wgUseTidy ) {
@@ -74,46 +81,46 @@ class CompareParsers extends DumpIterator {
}
$this->options->setTidy( true );
}
-
+
$this->failed = 0;
}
-
- public function conclusions() {
+
+ public function conclusions() {
$this->error( "{$this->failed} failed revisions out of {$this->count}" );
if ($this->count > 0)
$this->output( " (" . ( $this->failed / $this->count ) . "%)\n" );
}
-
+
function stripParameters( $text ) {
if ( !$this->stripParametersEnabled ) {
return $text;
}
return preg_replace( '/(<a) [^>]+>/', '$1>', $text );
}
-
+
/**
* Callback function for each revision, parse with both parsers and compare
* @param $rev Revision
*/
public function processRevision( $rev ) {
$title = $rev->getTitle();
-
+
$parser1Name = $this->getOption( 'parser1' );
$parser2Name = $this->getOption( 'parser2' );
-
+
self::checkParserLocally( $parser1Name );
self::checkParserLocally( $parser2Name );
-
+
$parser1 = new $parser1Name();
$parser2 = new $parser2Name();
-
+
$output1 = $parser1->parse( $rev->getText(), $title, $this->options );
$output2 = $parser2->parse( $rev->getText(), $title, $this->options );
if ( $output1->getText() != $output2->getText() ) {
$this->failed++;
$this->error( "Parsing for {$title->getPrefixedText()} differs\n" );
-
+
if ( $this->saveFailed ) {
file_put_contents( $this->saveFailed . '/' . rawurlencode( $title->getPrefixedText() ) . ".txt", $rev->getText());
}
@@ -127,7 +134,7 @@ class CompareParsers extends DumpIterator {
}
}
}
-
+
private static function checkParserLocally( $parserName ) {
/* Look for the parser in a file appropiately named in the current folder */
if ( !class_exists( $parserName ) && file_exists( "$parserName.php" ) ) {
diff --git a/maintenance/convertLinks.php b/maintenance/convertLinks.php
index 85ef5c8c..5f7b02e4 100644
--- a/maintenance/convertLinks.php
+++ b/maintenance/convertLinks.php
@@ -1,7 +1,6 @@
<?php
/**
- * Convert from the old links schema (string->ID) to the new schema (ID->ID)
- * The wiki should be put into read-only mode while this script executes
+ * Convert from the old links schema (string->ID) to the new schema (ID->ID).
*
* 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
@@ -22,14 +21,22 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to convert from the old links schema (string->ID)
+ * to the new schema (ID->ID).
+ *
+ * The wiki should be put into read-only mode while this script executes.
+ *
+ * @ingroup Maintenance
+ */
class ConvertLinks extends Maintenance {
private $logPerformance;
public function __construct() {
parent::__construct();
- $this->mDescription = "Convert from the old links schema (string->ID) to the new schema (ID->ID)
+ $this->mDescription = "Convert from the old links schema (string->ID) to the new schema (ID->ID).
The wiki should be put into read-only mode while this script executes";
$this->addArg( 'logperformance', "Log performance to perfLogFilename.", false );
diff --git a/maintenance/convertUserOptions.php b/maintenance/convertUserOptions.php
index da6ff9b6..7c9ca269 100644
--- a/maintenance/convertUserOptions.php
+++ b/maintenance/convertUserOptions.php
@@ -1,6 +1,6 @@
<?php
/**
- * Do each user sequentially, since accounts can't be deleted
+ * Convert user options to the new `user_properties` table.
*
* 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
@@ -21,8 +21,15 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to convert user options to the new `user_properties` table.
+ *
+ * Do each user sequentially, since accounts can't be deleted
+ *
+ * @ingroup Maintenance
+ */
class ConvertUserOptions extends Maintenance {
private $mConversionCount = 0;
diff --git a/maintenance/copyFileBackend.php b/maintenance/copyFileBackend.php
new file mode 100644
index 00000000..aebdee17
--- /dev/null
+++ b/maintenance/copyFileBackend.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Copy all files in some containers of one backend 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 files in one container of one backend to another.
+ *
+ * This can also be used to re-shard the files for one backend using the
+ * config of second backend. The second backend should have the same config
+ * as the first, except for it having a different name and different sharding
+ * configuration. The backend should be made read-only while this runs.
+ * After this script finishes, the old files in the containers can be deleted.
+ *
+ * @ingroup Maintenance
+ */
+class CopyFileBackend extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Copy files in one backend to another.";
+ $this->addOption( 'src', 'Backend containing the source files', true, true );
+ $this->addOption( 'dst', 'Backend where files should be copied to', true, true );
+ $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( 'skiphash', 'Skip SHA-1 sync checks for files' );
+ $this->addOption( 'missingonly', 'Only copy files missing from destination listing' );
+ $this->addOption( 'utf8only', 'Skip source files that do not have valid UTF-8 names' );
+ $this->setBatchSize( 50 );
+ }
+
+ public function execute() {
+ $src = FileBackendGroup::singleton()->get( $this->getOption( 'src' ) );
+ $dst = FileBackendGroup::singleton()->get( $this->getOption( 'dst' ) );
+ $containers = explode( '|', $this->getOption( 'containers' ) );
+ $subDir = $this->getOption( rtrim( 'subdir', '/' ), '' );
+
+ $rateFile = $this->getOption( 'ratefile' );
+
+ if ( $this->hasOption( 'utf8only' ) && !extension_loaded( 'mbstring' ) ) {
+ $this->error( "Cannot check for UTF-8, mbstring extension missing.", 1 ); // die
+ }
+
+ $count = 0;
+ foreach ( $containers as $container ) {
+ if ( $subDir != '' ) {
+ $backendRel = "$container/$subDir";
+ $this->output( "Doing container '$container', directory '$subDir'...\n" );
+ } else {
+ $backendRel = $container;
+ $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;
+ }
+ $dstPathsRel = $dst->getFileList( array(
+ 'dir' => $dst->getRootStoragePath() . "/$backendRel" ) );
+ if ( $dstPathsRel === null ) {
+ $this->error( "Could not list files in $container.", 1 ); // die
+ }
+ foreach ( $dstPathsRel as $dstPathRel ) {
+ $relFilesDst[] = $dstPathRel;
+ }
+ // 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 );
+ }
+
+ $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" );
+ }
+ $batchPaths[$srcPathRel] = 1; // remove duplicates
+ if ( count( $batchPaths ) >= $this->mBatchSize ) {
+ $this->copyFileBatch( array_keys( $batchPaths ), $backendRel, $src, $dst );
+ $batchPaths = array(); // done
+ }
+ ++$count;
+ }
+ if ( count( $batchPaths ) ) { // left-overs
+ $this->copyFileBatch( array_keys( $batchPaths ), $backendRel, $src, $dst );
+ $batchPaths = array(); // done
+ }
+
+ if ( $subDir != '' ) {
+ $this->output( "Finished container '$container', directory '$subDir'.\n" );
+ } else {
+ $this->output( "Finished container '$container'.\n" );
+ }
+ }
+
+ $this->output( "Done [$count file(s)].\n" );
+ }
+
+ protected function copyFileBatch(
+ array $srcPathsRel, $backendRel, FileBackend $src, FileBackend $dst
+ ) {
+ $ops = array();
+ $fsFiles = array();
+ $copiedRel = array(); // for output message
+ foreach ( $srcPathsRel as $srcPathRel ) {
+ $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." );
+ continue;
+ } elseif ( $this->filesAreSame( $src, $dst, $srcPath, $dstPath ) ) {
+ $this->output( "Already have $srcPathRel.\n" );
+ continue; // assume already copied...
+ }
+ // Note: getLocalReference() is fast for FS backends
+ $fsFile = $src->getLocalReference( array( 'src' => $srcPath, 'latest' => 1 ) );
+ if ( !$fsFile ) {
+ $this->error( "Could not get local copy of $srcPath.", 1 ); // die
+ } 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." );
+ continue;
+ }
+ $fsFiles[] = $fsFile; // keep TempFSFile objects alive as needed
+ // Note: prepare() is usually fast for key/value backends
+ $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
+ }
+ $ops[] = array( 'op' => 'store',
+ 'src' => $fsFile->getPath(), 'dst' => $dstPath, 'overwrite' => 1 );
+ $copiedRel[] = $srcPathRel;
+ }
+
+ $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( "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" );
+ }
+ }
+
+ protected function filesAreSame( FileBackend $src, FileBackend $dst, $sPath, $dPath ) {
+ $skipHash = $this->hasOption( 'skiphash' );
+ 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 ) )
+ === $dst->getFileSha1Base36( array( 'src' => $dPath, 'latest' => 1 ) )
+ ) )
+ );
+ }
+}
+
+$maintClass = 'CopyFileBackend';
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/createAndPromote.php b/maintenance/createAndPromote.php
index 0d7de9a9..ad5333fc 100644
--- a/maintenance/createAndPromote.php
+++ b/maintenance/createAndPromote.php
@@ -1,6 +1,6 @@
<?php
/**
- * Maintenance script to create an account and grant it administrator rights
+ * Creates an account and grant it administrator 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
@@ -22,8 +22,13 @@
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to create an account and grant it administrator rights.
+ *
+ * @ingroup Maintenance
+ */
class CreateAndPromote extends Maintenance {
public function __construct() {
@@ -76,4 +81,4 @@ class CreateAndPromote extends Maintenance {
}
$maintClass = "CreateAndPromote";
-require_once( RUN_MAINTENANCE_IF_MAIN ); \ No newline at end of file
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/deleteArchivedFiles.inc b/maintenance/deleteArchivedFiles.inc
index 68394b4a..e638b17c 100644
--- a/maintenance/deleteArchivedFiles.inc
+++ b/maintenance/deleteArchivedFiles.inc
@@ -17,14 +17,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
+/**
+ * Core functions for deleteArchivedFiles.php
+ *
+ * @ingroup Maintenance
+ */
class DeleteArchivedFilesImplementation {
static public function doDelete( $output, $force ) {
# Data should come off the master, wrapped in a transaction
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_arch = $dbw->tableName( 'filearchive' );
$repo = RepoGroup::singleton()->getLocalRepo();
# Get "active" revisions from the filearchive table
@@ -44,8 +50,8 @@ class DeleteArchivedFilesImplementation {
__METHOD__,
array( 'FOR UPDATE' )
);
- if ( $path && file_exists( $path ) && !$inuse ) {
- if( unlink( $path ) ) { // delete
+ if ( $path && $repo->fileExists( $path ) && !$inuse ) {
+ if ( $repo->quickPurge( $path ) ) {
$count++;
$dbw->query( "DELETE FROM $tbl_arch WHERE fa_id = $id" );
} else {
@@ -59,7 +65,7 @@ class DeleteArchivedFilesImplementation {
}
}
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$output->handleOutput( "Done! [$count file(s)]\n" );
}
-} \ No newline at end of file
+}
diff --git a/maintenance/deleteArchivedFiles.php b/maintenance/deleteArchivedFiles.php
index 6067c807..85ffc23b 100644
--- a/maintenance/deleteArchivedFiles.php
+++ b/maintenance/deleteArchivedFiles.php
@@ -1,8 +1,9 @@
<?php
-
/**
* Delete archived (non-current) files from the database
*
+ * Based on deleteOldRevisions.php by Rob Church.
+ *
* 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
@@ -18,14 +19,19 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Aaron Schulz
- * Based on deleteOldRevisions.php by Rob Church
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/deleteArchivedFiles.inc' );
+require_once( __DIR__ . '/Maintenance.php' );
+require_once( __DIR__ . '/deleteArchivedFiles.inc' );
+/**
+ * Maintenance script to delete archived (non-current) files from the database.
+ *
+ * @ingroup Maintenance
+ */
class DeleteArchivedFiles extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/deleteArchivedRevisions.inc b/maintenance/deleteArchivedRevisions.inc
index 7628985c..414d41ad 100644
--- a/maintenance/deleteArchivedRevisions.inc
+++ b/maintenance/deleteArchivedRevisions.inc
@@ -1,7 +1,6 @@
<?php
-
/**
- * Delete archived (deleted from public) revisions from the database
+ * Helper methods for the deleteArchivedRevisions.php maintenance script.
*
* 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
@@ -18,9 +17,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
+/**
+ * Helper methods for the deleteArchivedRevisions.php maintenance script.
+ *
+ * @ingroup Maintenance
+ */
class DeleteArchivedRevisionsImplementation {
/**
@@ -34,7 +39,7 @@ class DeleteArchivedRevisionsImplementation {
static public function doDelete( $maint ) {
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_arch = $dbw->tableName( 'archive' );
@@ -49,7 +54,7 @@ class DeleteArchivedRevisionsImplementation {
# This bit's done
# Purge redundant text records
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
if ( $deletedRows ) {
$maint->purgeRedundantText( true );
}
diff --git a/maintenance/deleteArchivedRevisions.php b/maintenance/deleteArchivedRevisions.php
index 0faa0abb..4b658bbb 100644
--- a/maintenance/deleteArchivedRevisions.php
+++ b/maintenance/deleteArchivedRevisions.php
@@ -1,8 +1,9 @@
<?php
-
/**
* Delete archived (deleted from public) revisions from the database
*
+ * Shamelessly stolen from deleteOldRevisions.php by Rob Church :)
+ *
* 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
@@ -18,14 +19,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Aaron Schulz
- * Shamelessly stolen from deleteOldRevisions.php by Rob Church :)
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/deleteArchivedRevisions.inc' );
+require_once( __DIR__ . '/Maintenance.php' );
+require_once( __DIR__ . '/deleteArchivedRevisions.inc' );
+/**
+ * Maintenance script to delete archived (deleted from public) revisions
+ * from the database.
+ *
+ * @ingroup Maintenance
+ */
class DeleteArchivedRevisions extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/deleteBatch.php b/maintenance/deleteBatch.php
index 56fe13a4..936a52b8 100644
--- a/maintenance/deleteBatch.php
+++ b/maintenance/deleteBatch.php
@@ -1,6 +1,6 @@
<?php
/**
- * Deletes a batch of pages
+ * Deletes a batch of pages.
* Usage: php deleteBatch.php [-u <user>] [-r <reason>] [-i <interval>] [listfile]
* where
* [listfile] is a file where each line contains the title of a page to be
@@ -24,11 +24,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to delete a batch of pages.
+ *
+ * @ingroup Maintenance
+ */
class DeleteBatch extends Maintenance {
public function __construct() {
@@ -89,7 +95,7 @@ class DeleteBatch extends Maintenance {
}
$this->output( $title->getPrefixedText() );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
if ( $title->getNamespace() == NS_FILE ) {
$img = wfFindFile( $title );
if ( $img && $img->isLocal() && !$img->delete( $reason ) ) {
@@ -99,7 +105,7 @@ class DeleteBatch extends Maintenance {
$page = WikiPage::factory( $title );
$error = '';
$success = $page->doDeleteArticle( $reason, false, 0, false, $error, $user );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
if ( $success ) {
$this->output( " Deleted!\n" );
} else {
diff --git a/maintenance/deleteDefaultMessages.php b/maintenance/deleteDefaultMessages.php
index 21d7755f..4ab6d1d9 100644
--- a/maintenance/deleteDefaultMessages.php
+++ b/maintenance/deleteDefaultMessages.php
@@ -18,11 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes all pages in the MediaWiki namespace
+ * which were last edited by "MediaWiki default".
+ *
+ * @ingroup Maintenance
+ */
class DeleteDefaultMessages extends Maintenance {
public function __construct() {
parent::__construct();
@@ -68,13 +75,13 @@ class DeleteDefaultMessages extends Maintenance {
$dbw->ping();
$title = Title::makeTitle( $row->page_namespace, $row->page_title );
$page = WikiPage::factory( $title );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$error = ''; // Passed by ref
$page->doDeleteArticle( 'No longer required', false, 0, false, $error, $user );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
- $this->output( 'done!', 'msg' );
+ $this->output( "done!\n", 'msg' );
}
}
diff --git a/maintenance/deleteImageMemcached.php b/maintenance/deleteImageMemcached.php
index 007f0d17..3c8c5fdd 100644
--- a/maintenance/deleteImageMemcached.php
+++ b/maintenance/deleteImageMemcached.php
@@ -1,6 +1,6 @@
<?php
/**
- * This script delete image information from the cache.
+ * Delete image information from the object cache.
*
* Usage example:
* php deleteImageMemcached.php --until "2005-09-05 00:00:00" --sleep 0
@@ -20,11 +20,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes image information from the object cache.
+ *
+ * @ingroup Maintenance
+ */
class DeleteImageCache extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/deleteOldRevisions.php b/maintenance/deleteOldRevisions.php
index 2cb347fc..6a3e211b 100644
--- a/maintenance/deleteOldRevisions.php
+++ b/maintenance/deleteOldRevisions.php
@@ -1,5 +1,4 @@
<?php
-
/**
* Delete old (non-current) revisions from the database
*
@@ -18,12 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes old (non-current) revisions from the database.
+ *
+ * @ingroup Maintenance
+ */
class DeleteOldRevisions extends Maintenance {
public function __construct() {
parent::__construct();
@@ -41,7 +46,7 @@ class DeleteOldRevisions extends Maintenance {
# Data should come off the master, wrapped in a transaction
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_pag = $dbw->tableName( 'page' );
$tbl_rev = $dbw->tableName( 'revision' );
@@ -90,7 +95,7 @@ class DeleteOldRevisions extends Maintenance {
# This bit's done
# Purge redundant text records
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
if ( $delete ) {
$this->purgeRedundantText( true );
}
diff --git a/maintenance/deleteOrphanedRevisions.php b/maintenance/deleteOrphanedRevisions.php
index c322320b..5dc7567f 100644
--- a/maintenance/deleteOrphanedRevisions.php
+++ b/maintenance/deleteOrphanedRevisions.php
@@ -1,8 +1,7 @@
<?php
-
/**
- * Maintenance script to delete revisions which refer to a nonexisting page
- * Sometimes manual deletion done in a rush leaves crap in the database
+ * Delete revisions which refer to a nonexisting page.
+ * Sometimes manual deletion done in a rush leaves crap in the database.
*
* 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
@@ -19,13 +18,19 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
* @todo More efficient cleanup of text records
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes revisions which refer to a nonexisting page.
+ *
+ * @ingroup Maintenance
+ */
class DeleteOrphanedRevisions extends Maintenance {
public function __construct() {
parent::__construct();
@@ -39,7 +44,7 @@ class DeleteOrphanedRevisions extends Maintenance {
$report = $this->hasOption( 'report' );
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
list( $page, $revision ) = $dbw->tableNamesN( 'page', 'revision' );
# Find all the orphaned revisions
@@ -66,7 +71,7 @@ class DeleteOrphanedRevisions extends Maintenance {
$this->output( "done.\n" );
# Close the transaction and call the script to purge unused text records
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$this->purgeRedundantText( true );
}
diff --git a/maintenance/deleteRevision.php b/maintenance/deleteRevision.php
index 5e8ecaac..ad6470d9 100644
--- a/maintenance/deleteRevision.php
+++ b/maintenance/deleteRevision.php
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes one or more revisions by moving them
+ * to the archive table.
+ *
+ * @ingroup Maintenance
+ */
class DeleteRevision extends Maintenance {
public function __construct() {
diff --git a/maintenance/deleteSelfExternals.php b/maintenance/deleteSelfExternals.php
index 4e9f54f2..da220d64 100644
--- a/maintenance/deleteSelfExternals.php
+++ b/maintenance/deleteSelfExternals.php
@@ -1,10 +1,6 @@
<?php
/**
- * We want to make this whole thing as seamless as possible to the
- * end-user. Unfortunately, we can't do _all_ of the work in the class
- * because A) included files are not in global scope, but in the scope
- * of their caller, and B) MediaWiki has way too many globals. So instead
- * we'll kinda fake it, and do the requires() inline. <3 PHP
+ * Delete self-references to $wgServer from the externallinks table.
*
* 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
@@ -21,12 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that deletes self-references to $wgServer
+ * from the externallinks table.
+ *
+ * @ingroup Maintenance
+ */
class DeleteSelfExternals extends Maintenance {
public function __construct() {
parent::__construct();
@@ -40,7 +42,7 @@ class DeleteSelfExternals extends Maintenance {
$db = wfGetDB( DB_MASTER );
while ( 1 ) {
wfWaitForSlaves();
- $db->commit();
+ $db->commit( __METHOD__ );
$q = $db->limitResult( "DELETE /* deleteSelfExternals */ FROM externallinks WHERE el_to"
. $db->buildLike( $wgServer . '/', $db->anyString() ), $this->mBatchSize );
$this->output( "Deleting a batch\n" );
diff --git a/maintenance/dev/includes/php.sh b/maintenance/dev/includes/php.sh
index 3021b93b..7ce87944 100644
--- a/maintenance/dev/includes/php.sh
+++ b/maintenance/dev/includes/php.sh
@@ -1,12 +1,14 @@
# Include-able script to determine the location of our php if any
+# We search for a environment var called PHP, native php,
+# a local copy, home directory location used by installphp.sh
+# and previous home directory location
+# The binary path is returned in $PHP if any
-if [ -d "$DEV/php" -a -x "$DEV/php/bin/php" ]; then
- # Quick local copy
- PHP="$DEV/php/bin/php"
-elif [ -d "$HOME/.mediawiki/php" -a -x "$HOME/.mediawiki/php/bin/php" ]; then
- # Previous home directory location to install php in
- PHP="$HOME/.mediawiki/php/bin/php"
-elif [ -d "$HOME/.mwphp" -a -x "$HOME/.mwphp/bin/php" ]; then
- # Previous home directory location to install php in
- PHP="$HOME/.mwphp/bin/php"
-fi
+for binary in $PHP `which php || true` "$DEV/php/bin/php" "$HOME/.mediawiki/php/bin/php" "$HOME/.mwphp/bin/php" ]; do
+ if [ -x "$binary" ]; then
+ if "$binary" -r 'exit((int)!version_compare(PHP_VERSION, "5.4", ">="));'; then
+ PHP="$binary"
+ break
+ fi
+ fi
+done
diff --git a/maintenance/dev/includes/router.php b/maintenance/dev/includes/router.php
index f6a062b6..ac96f459 100644
--- a/maintenance/dev/includes/router.php
+++ b/maintenance/dev/includes/router.php
@@ -1,7 +1,25 @@
<?php
-
-# Router for the php cli-server built-in webserver
-# http://ca2.php.net/manual/en/features.commandline.webserver.php
+/**
+ * Router for the php cli-server built-in webserver.
+ * http://www.php.net/manual/en/features.commandline.webserver.php
+ *
+ * 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
+ */
if ( php_sapi_name() != 'cli-server' ) {
die( "This script can only be run by php's cli-server sapi." );
@@ -66,7 +84,7 @@ if ( $mime ) {
# PHP webserver doesn't understand.
# ;) Nicely enough we just happen to bundle a mime.types file
$f = fopen($file, 'rb');
- if ( preg_match( '^text/', $mime ) ) {
+ 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");
} else {
diff --git a/maintenance/doMaintenance.php b/maintenance/doMaintenance.php
index 6b29c5fd..2bb2a0f4 100644
--- a/maintenance/doMaintenance.php
+++ b/maintenance/doMaintenance.php
@@ -93,6 +93,11 @@ if ( $maintenance->getDbType() === Maintenance::DB_ADMIN &&
{
require( MWInit::interpretedPath( 'AdminSettings.php' ) );
}
+
+if ( $maintenance->getDbType() === Maintenance::DB_NONE ) {
+ 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' ) );
diff --git a/maintenance/dumpBackup.php b/maintenance/dumpBackup.php
index c49a2963..c9546c60 100644
--- a/maintenance/dumpBackup.php
+++ b/maintenance/dumpBackup.php
@@ -29,8 +29,8 @@ $originalDir = getcwd();
$optionsWithArgs = array( 'pagelist', 'start', 'end', 'revstart', 'revend');
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
-require_once( 'backup.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
+require_once( __DIR__ . '/backup.inc' );
$dumper = new BackupDumper( $argv );
@@ -88,6 +88,10 @@ XML interchange wrapper format for export or backup.
XML output is sent to stdout; progress reports are sent to stderr.
+WARNING: this is not a full database dump! It is merely for public export
+ of your wiki. For full backup, see our online help at:
+ https://www.mediawiki.org/wiki/Backup
+
Usage: php dumpBackup.php <action> [<options>]
Actions:
--full Dump all revisions of every page.
diff --git a/maintenance/dumpIterator.php b/maintenance/dumpIterator.php
index 470bc56e..3657f960 100644
--- a/maintenance/dumpIterator.php
+++ b/maintenance/dumpIterator.php
@@ -4,7 +4,8 @@
* Used as a base class for CompareParsers and PreprocessDump.
* We implement below the simple task of searching inside a dump.
*
- * Copyright (C) 2011 Platonides - http://www.mediawiki.org/
+ * Copyright © 2011 Platonides
+ * http://www.mediawiki.org/
*
* 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
@@ -25,8 +26,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Base class for interating over a dump.
+ *
+ * @ingroup Maintenance
+ */
abstract class DumpIterator extends Maintenance {
private $count = 0;
@@ -56,7 +62,7 @@ abstract class DumpIterator extends Maintenance {
return;
}
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
if ( $this->getOption('dump') == '-' ) {
$source = new ImportStreamSource( $this->getStdin() );
@@ -74,7 +80,7 @@ abstract class DumpIterator extends Maintenance {
$this->conclusions();
- $delta = wfTime() - $this->startTime;
+ $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" );
@@ -141,6 +147,11 @@ abstract class DumpIterator extends Maintenance {
abstract public function processRevision( $rev );
}
+/**
+ * Maintenance script that runs a regex in the revisions from a dump.
+ *
+ * @ingroup Maintenance
+ */
class SearchDump extends DumpIterator {
public function __construct() {
diff --git a/maintenance/dumpLinks.php b/maintenance/dumpLinks.php
index 0101dc8d..153fdd79 100644
--- a/maintenance/dumpLinks.php
+++ b/maintenance/dumpLinks.php
@@ -1,8 +1,5 @@
<?php
/**
- * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
- * http://www.mediawiki.org/
- *
* Quick demo hack to generate a plaintext link dump,
* per the proposed wiki link database standard:
* http://www.usemod.com/cgi-bin/mb.pl?LinkDatabase
@@ -11,6 +8,9 @@
* Does not include interwiki or URL links.
* Dumps ASCII text to stdout; command-line.
*
+ * Copyright © 2005 Brion Vibber <brion@pobox.com>
+ * http://www.mediawiki.org/
+ *
* 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
@@ -26,11 +26,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that generates a plaintext link dump.
+ *
+ * @ingroup Maintenance
+ */
class DumpLinks extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/dumpSisterSites.php b/maintenance/dumpSisterSites.php
index f5abcd1b..e05e154e 100644
--- a/maintenance/dumpSisterSites.php
+++ b/maintenance/dumpSisterSites.php
@@ -3,7 +3,7 @@
* Quickie page name dump script for SisterSites usage.
* http://www.eekim.com/cgi-bin/wiki.pl?SisterSites
*
- * Copyright (C) 2006 Brion Vibber <brion@pobox.com>
+ * Copyright © 2006 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -21,11 +21,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that generates a page name dump for SisterSites usage.
+ *
+ * @ingroup Maintenance
+ */
class DumpSisterSites extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/dumpTextPass.php b/maintenance/dumpTextPass.php
index 0fed29fc..72d7d97c 100644
--- a/maintenance/dumpTextPass.php
+++ b/maintenance/dumpTextPass.php
@@ -26,634 +26,8 @@
$originalDir = getcwd();
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
-require_once( 'backup.inc' );
-
-/**
- * @ingroup Maintenance
- */
-class TextPassDumper extends BackupDumper {
- var $prefetch = null;
- var $input = "php://stdin";
- var $history = WikiExporter::FULL;
- var $fetchCount = 0;
- var $prefetchCount = 0;
- var $prefetchCountLast = 0;
- var $fetchCountLast = 0;
-
- var $failures = 0;
- var $maxFailures = 5;
- var $failedTextRetrievals = 0;
- var $maxConsecutiveFailedTextRetrievals = 200;
- var $failureTimeout = 5; // Seconds to sleep after db failure
-
- var $php = "php";
- var $spawn = false;
- var $spawnProc = false;
- var $spawnWrite = false;
- var $spawnRead = false;
- var $spawnErr = false;
-
- var $xmlwriterobj = false;
-
- // when we spend more than maxTimeAllowed seconds on this run, we continue
- // processing until we write out the next complete page, then save output file(s),
- // rename it/them and open new one(s)
- var $maxTimeAllowed = 0; // 0 = no limit
- var $timeExceeded = false;
- var $firstPageWritten = false;
- var $lastPageWritten = false;
- var $checkpointJustWritten = false;
- var $checkpointFiles = array();
-
- /**
- * @var DatabaseBase
- */
- protected $db;
-
- function initProgress( $history ) {
- parent::initProgress();
- $this->timeOfCheckpoint = $this->startTime;
- }
-
- function dump( $history, $text = WikiExporter::TEXT ) {
- // This shouldn't happen if on console... ;)
- header( 'Content-type: text/html; charset=UTF-8' );
-
- // Notice messages will foul up your XML output even if they're
- // relatively harmless.
- if ( ini_get( 'display_errors' ) )
- ini_set( 'display_errors', 'stderr' );
-
- $this->initProgress( $this->history );
-
- $this->db = $this->backupDb();
-
- $this->egress = new ExportProgressFilter( $this->sink, $this );
-
- // it would be nice to do it in the constructor, oh well. need egress set
- $this->finalOptionCheck();
-
- // we only want this so we know how to close a stream :-P
- $this->xmlwriterobj = new XmlDumpWriter();
-
- $input = fopen( $this->input, "rt" );
- $result = $this->readDump( $input );
-
- if ( WikiError::isError( $result ) ) {
- throw new MWException( $result->getMessage() );
- }
-
- if ( $this->spawnProc ) {
- $this->closeSpawn();
- }
-
- $this->report( true );
- }
-
- function processOption( $opt, $val, $param ) {
- global $IP;
- $url = $this->processFileOpt( $val, $param );
-
- switch( $opt ) {
- case 'prefetch':
- require_once "$IP/maintenance/backupPrefetch.inc";
- $this->prefetch = new BaseDump( $url );
- break;
- case 'stub':
- $this->input = $url;
- break;
- case 'maxtime':
- $this->maxTimeAllowed = intval($val)*60;
- break;
- case 'checkpointfile':
- $this->checkpointFiles[] = $val;
- break;
- case 'current':
- $this->history = WikiExporter::CURRENT;
- break;
- case 'full':
- $this->history = WikiExporter::FULL;
- break;
- case 'spawn':
- $this->spawn = true;
- if ( $val ) {
- $this->php = $val;
- }
- break;
- }
- }
-
- function processFileOpt( $val, $param ) {
- $fileURIs = explode(';',$param);
- foreach ( $fileURIs as $URI ) {
- switch( $val ) {
- case "file":
- $newURI = $URI;
- break;
- case "gzip":
- $newURI = "compress.zlib://$URI";
- break;
- case "bzip2":
- $newURI = "compress.bzip2://$URI";
- break;
- case "7zip":
- $newURI = "mediawiki.compress.7z://$URI";
- break;
- default:
- $newURI = $URI;
- }
- $newFileURIs[] = $newURI;
- }
- $val = implode( ';', $newFileURIs );
- return $val;
- }
-
- /**
- * Overridden to include prefetch ratio if enabled.
- */
- function showReport() {
- if ( !$this->prefetch ) {
- parent::showReport();
- return;
- }
-
- if ( $this->reporting ) {
- $now = wfTimestamp( TS_DB );
- $nowts = wfTime();
- $deltaAll = wfTime() - $this->startTime;
- $deltaPart = wfTime() - $this->lastTime;
- $this->pageCountPart = $this->pageCount - $this->pageCountLast;
- $this->revCountPart = $this->revCount - $this->revCountLast;
-
- if ( $deltaAll ) {
- $portion = $this->revCount / $this->maxCount;
- $eta = $this->startTime + $deltaAll / $portion;
- $etats = wfTimestamp( TS_DB, intval( $eta ) );
- if ( $this->fetchCount ) {
- $fetchRate = 100.0 * $this->prefetchCount / $this->fetchCount;
- } else {
- $fetchRate = '-';
- }
- $pageRate = $this->pageCount / $deltaAll;
- $revRate = $this->revCount / $deltaAll;
- } else {
- $pageRate = '-';
- $revRate = '-';
- $etats = '-';
- $fetchRate = '-';
- }
- if ( $deltaPart ) {
- if ( $this->fetchCountLast ) {
- $fetchRatePart = 100.0 * $this->prefetchCountLast / $this->fetchCountLast;
- } else {
- $fetchRatePart = '-';
- }
- $pageRatePart = $this->pageCountPart / $deltaPart;
- $revRatePart = $this->revCountPart / $deltaPart;
-
- } else {
- $fetchRatePart = '-';
- $pageRatePart = '-';
- $revRatePart = '-';
- }
- $this->progress( sprintf( "%s: %s (ID %d) %d pages (%0.1f|%0.1f/sec all|curr), %d revs (%0.1f|%0.1f/sec all|curr), %0.1f%%|%0.1f%% prefetched (all|curr), ETA %s [max %d]",
- $now, wfWikiID(), $this->ID, $this->pageCount, $pageRate, $pageRatePart, $this->revCount, $revRate, $revRatePart, $fetchRate, $fetchRatePart, $etats, $this->maxCount ) );
- $this->lastTime = $nowts;
- $this->revCountLast = $this->revCount;
- $this->prefetchCountLast = $this->prefetchCount;
- $this->fetchCountLast = $this->fetchCount;
- }
- }
-
- function setTimeExceeded() {
- $this->timeExceeded = True;
- }
-
- function checkIfTimeExceeded() {
- if ( $this->maxTimeAllowed && ( $this->lastTime - $this->timeOfCheckpoint > $this->maxTimeAllowed ) ) {
- return true;
- }
- return false;
- }
-
- function finalOptionCheck() {
- if ( ( $this->checkpointFiles && ! $this->maxTimeAllowed ) ||
- ( $this->maxTimeAllowed && !$this->checkpointFiles ) ) {
- throw new MWException("Options checkpointfile and maxtime must be specified together.\n");
- }
- foreach ($this->checkpointFiles as $checkpointFile) {
- $count = substr_count ( $checkpointFile,"%s" );
- if ( $count != 2 ) {
- throw new MWException("Option checkpointfile must contain two '%s' for substitution of first and last pageids, count is $count instead, file is $checkpointFile.\n");
- }
- }
-
- if ( $this->checkpointFiles ) {
- $filenameList = (array)$this->egress->getFilenames();
- if ( count( $filenameList ) != count( $this->checkpointFiles ) ) {
- throw new MWException("One checkpointfile must be specified for each output option, if maxtime is used.\n");
- }
- }
- }
-
- function readDump( $input ) {
- $this->buffer = "";
- $this->openElement = false;
- $this->atStart = true;
- $this->state = "";
- $this->lastName = "";
- $this->thisPage = 0;
- $this->thisRev = 0;
-
- $parser = xml_parser_create( "UTF-8" );
- xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
-
- xml_set_element_handler( $parser, array( &$this, 'startElement' ), array( &$this, 'endElement' ) );
- xml_set_character_data_handler( $parser, array( &$this, 'characterData' ) );
-
- $offset = 0; // for context extraction on error reporting
- $bufferSize = 512 * 1024;
- do {
- if ($this->checkIfTimeExceeded()) {
- $this->setTimeExceeded();
- }
- $chunk = fread( $input, $bufferSize );
- if ( !xml_parse( $parser, $chunk, feof( $input ) ) ) {
- wfDebug( "TextDumpPass::readDump encountered XML parsing error\n" );
- return new WikiXmlError( $parser, 'XML import parse failure', $chunk, $offset );
- }
- $offset += strlen( $chunk );
- } while ( $chunk !== false && !feof( $input ) );
- if ($this->maxTimeAllowed) {
- $filenameList = (array)$this->egress->getFilenames();
- // we wrote some stuff after last checkpoint that needs renamed
- if (file_exists($filenameList[0])) {
- $newFilenames = array();
- # we might have just written the header and footer and had no
- # pages or revisions written... perhaps they were all deleted
- # there's no pageID 0 so we use that. the caller is responsible
- # for deciding what to do with a file containing only the
- # siteinfo information and the mw tags.
- if (! $this->firstPageWritten) {
- $firstPageID = str_pad(0,9,"0",STR_PAD_LEFT);
- $lastPageID = str_pad(0,9,"0",STR_PAD_LEFT);
- }
- else {
- $firstPageID = str_pad($this->firstPageWritten,9,"0",STR_PAD_LEFT);
- $lastPageID = str_pad($this->lastPageWritten,9,"0",STR_PAD_LEFT);
- }
- for ( $i = 0; $i < count( $filenameList ); $i++ ) {
- $checkpointNameFilledIn = sprintf( $this->checkpointFiles[$i], $firstPageID, $lastPageID );
- $fileinfo = pathinfo($filenameList[$i]);
- $newFilenames[] = $fileinfo['dirname'] . '/' . $checkpointNameFilledIn;
- }
- $this->egress->closeAndRename( $newFilenames );
- }
- }
- xml_parser_free( $parser );
-
- return true;
- }
-
- function getText( $id ) {
- $this->fetchCount++;
- if ( isset( $this->prefetch ) ) {
- $text = $this->prefetch->prefetch( $this->thisPage, $this->thisRev );
- if ( $text !== null ) { // Entry missing from prefetch dump
- $dbr = wfGetDB( DB_SLAVE );
- $revID = intval( $this->thisRev );
- $revLength = $dbr->selectField( 'revision', 'rev_len', array( 'rev_id' => $revID ) );
- // if length of rev text in file doesn't match length in db, we reload
- // this avoids carrying forward broken data from previous xml dumps
- if( strlen( $text ) == $revLength ) {
- $this->prefetchCount++;
- return $text;
- }
- }
- }
- return $this->doGetText( $id );
- }
-
- private function doGetText( $id ) {
- $id = intval( $id );
- $this->failures = 0;
- $ex = new MWException( "Graceful storage failure" );
- while (true) {
- if ( $this->spawn ) {
- if ($this->failures) {
- // we don't know why it failed, could be the child process
- // borked, could be db entry busted, could be db server out to lunch,
- // so cover all bases
- $this->closeSpawn();
- $this->openSpawn();
- }
- $text = $this->getTextSpawned( $id );
- } else {
- $text = $this->getTextDbSafe( $id );
- }
- if ( $text === false ) {
- $this->failures++;
- if ( $this->failures > $this->maxFailures) {
- $this->progress( "Failed to retrieve revision text for text id ".
- "$id after $this->maxFailures tries, giving up" );
- // were there so many bad retrievals in a row we want to bail?
- // at some point we have to declare the dump irretrievably broken
- $this->failedTextRetrievals++;
- if ($this->failedTextRetrievals > $this->maxConsecutiveFailedTextRetrievals) {
- throw $ex;
- } else {
- // would be nice to return something better to the caller someday,
- // log what we know about the failure and about the revision
- return "";
- }
- } else {
- $this->progress( "Error $this->failures " .
- "of allowed $this->maxFailures retrieving revision text for text id $id! " .
- "Pausing $this->failureTimeout seconds before retry..." );
- sleep( $this->failureTimeout );
- }
- } else {
- $this->failedTextRetrievals= 0;
- return $text;
- }
- }
- return '';
- }
-
- /**
- * Fetch a text revision from the database, retrying in case of failure.
- * This may survive some transitory errors by reconnecting, but
- * may not survive a long-term server outage.
- *
- * FIXME: WTF? Why is it using a loop and then returning unconditionally?
- */
- private function getTextDbSafe( $id ) {
- while ( true ) {
- try {
- $text = $this->getTextDb( $id );
- } catch ( DBQueryError $ex ) {
- $text = false;
- }
- return $text;
- }
- }
-
- /**
- * May throw a database error if, say, the server dies during query.
- * @param $id
- * @return bool|string
- */
- private function getTextDb( $id ) {
- global $wgContLang;
- $row = $this->db->selectRow( 'text',
- array( 'old_text', 'old_flags' ),
- array( 'old_id' => $id ),
- __METHOD__ );
- $text = Revision::getRevisionText( $row );
- if ( $text === false ) {
- return false;
- }
- $stripped = str_replace( "\r", "", $text );
- $normalized = $wgContLang->normalize( $stripped );
- return $normalized;
- }
-
- private function getTextSpawned( $id ) {
- wfSuppressWarnings();
- if ( !$this->spawnProc ) {
- // First time?
- $this->openSpawn();
- }
- $text = $this->getTextSpawnedOnce( $id );
- wfRestoreWarnings();
- return $text;
- }
-
- function openSpawn() {
- global $IP;
-
- if ( file_exists( "$IP/../multiversion/MWScript.php" ) ) {
- $cmd = implode( " ",
- array_map( 'wfEscapeShellArg',
- array(
- $this->php,
- "$IP/../multiversion/MWScript.php",
- "fetchText.php",
- '--wiki', wfWikiID() ) ) );
- }
- else {
- $cmd = implode( " ",
- array_map( 'wfEscapeShellArg',
- array(
- $this->php,
- "$IP/maintenance/fetchText.php",
- '--wiki', wfWikiID() ) ) );
- }
- $spec = array(
- 0 => array( "pipe", "r" ),
- 1 => array( "pipe", "w" ),
- 2 => array( "file", "/dev/null", "a" ) );
- $pipes = array();
-
- $this->progress( "Spawning database subprocess: $cmd" );
- $this->spawnProc = proc_open( $cmd, $spec, $pipes );
- if ( !$this->spawnProc ) {
- // shit
- $this->progress( "Subprocess spawn failed." );
- return false;
- }
- list(
- $this->spawnWrite, // -> stdin
- $this->spawnRead, // <- stdout
- ) = $pipes;
-
- return true;
- }
-
- private function closeSpawn() {
- wfSuppressWarnings();
- if ( $this->spawnRead )
- fclose( $this->spawnRead );
- $this->spawnRead = false;
- if ( $this->spawnWrite )
- fclose( $this->spawnWrite );
- $this->spawnWrite = false;
- if ( $this->spawnErr )
- fclose( $this->spawnErr );
- $this->spawnErr = false;
- if ( $this->spawnProc )
- pclose( $this->spawnProc );
- $this->spawnProc = false;
- wfRestoreWarnings();
- }
-
- private function getTextSpawnedOnce( $id ) {
- global $wgContLang;
-
- $ok = fwrite( $this->spawnWrite, "$id\n" );
- // $this->progress( ">> $id" );
- if ( !$ok ) return false;
-
- $ok = fflush( $this->spawnWrite );
- // $this->progress( ">> [flush]" );
- 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
- $newId = fgets( $this->spawnRead );
- if ( $newId === false ) {
- return false;
- }
- if ( $id != intval( $newId ) ) {
- return false;
- }
-
- $len = fgets( $this->spawnRead );
- // $this->progress( "<< " . trim( $len ) );
- if ( $len === false ) return false;
-
- $nbytes = intval( $len );
- // actual error, not zero-length text
- 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;
- $text .= $buffer;
- }
-
- $gotbytes = strlen( $text );
- if ( $gotbytes != $nbytes ) {
- $this->progress( "Expected $nbytes bytes from database subprocess, got $gotbytes " );
- return false;
- }
-
- // Do normalization in the dump thread...
- $stripped = str_replace( "\r", "", $text );
- $normalized = $wgContLang->normalize( $stripped );
- return $normalized;
- }
-
- function startElement( $parser, $name, $attribs ) {
- $this->checkpointJustWritten = false;
-
- $this->clearOpenElement( null );
- $this->lastName = $name;
-
- if ( $name == 'revision' ) {
- $this->state = $name;
- $this->egress->writeOpenPage( null, $this->buffer );
- $this->buffer = "";
- } elseif ( $name == 'page' ) {
- $this->state = $name;
- if ( $this->atStart ) {
- $this->egress->writeOpenStream( $this->buffer );
- $this->buffer = "";
- $this->atStart = false;
- }
- }
-
- if ( $name == "text" && isset( $attribs['id'] ) ) {
- $text = $this->getText( $attribs['id'] );
- $this->openElement = array( $name, array( 'xml:space' => 'preserve' ) );
- if ( strlen( $text ) > 0 ) {
- $this->characterData( $parser, $text );
- }
- } else {
- $this->openElement = array( $name, $attribs );
- }
- }
-
- function endElement( $parser, $name ) {
- $this->checkpointJustWritten = false;
-
- if ( $this->openElement ) {
- $this->clearOpenElement( "" );
- } else {
- $this->buffer .= "</$name>";
- }
-
- if ( $name == 'revision' ) {
- $this->egress->writeRevision( null, $this->buffer );
- $this->buffer = "";
- $this->thisRev = "";
- } elseif ( $name == 'page' ) {
- if (! $this->firstPageWritten) {
- $this->firstPageWritten = trim($this->thisPage);
- }
- $this->lastPageWritten = trim($this->thisPage);
- if ($this->timeExceeded) {
- $this->egress->writeClosePage( $this->buffer );
- // nasty hack, we can't just write the chardata after the
- // page tag, it will include leading blanks from the next line
- $this->egress->sink->write("\n");
-
- $this->buffer = $this->xmlwriterobj->closeStream();
- $this->egress->writeCloseStream( $this->buffer );
-
- $this->buffer = "";
- $this->thisPage = "";
- // this could be more than one file if we had more than one output arg
-
- $filenameList = (array)$this->egress->getFilenames();
- $newFilenames = array();
- $firstPageID = str_pad($this->firstPageWritten,9,"0",STR_PAD_LEFT);
- $lastPageID = str_pad($this->lastPageWritten,9,"0",STR_PAD_LEFT);
- for ( $i = 0; $i < count( $filenameList ); $i++ ) {
- $checkpointNameFilledIn = sprintf( $this->checkpointFiles[$i], $firstPageID, $lastPageID );
- $fileinfo = pathinfo($filenameList[$i]);
- $newFilenames[] = $fileinfo['dirname'] . '/' . $checkpointNameFilledIn;
- }
- $this->egress->closeRenameAndReopen( $newFilenames );
- $this->buffer = $this->xmlwriterobj->openStream();
- $this->timeExceeded = false;
- $this->timeOfCheckpoint = $this->lastTime;
- $this->firstPageWritten = false;
- $this->checkpointJustWritten = true;
- }
- else {
- $this->egress->writeClosePage( $this->buffer );
- $this->buffer = "";
- $this->thisPage = "";
- }
-
- } elseif ( $name == 'mediawiki' ) {
- $this->egress->writeCloseStream( $this->buffer );
- $this->buffer = "";
- }
- }
-
- function characterData( $parser, $data ) {
- $this->clearOpenElement( null );
- if ( $this->lastName == "id" ) {
- if ( $this->state == "revision" ) {
- $this->thisRev .= $data;
- } elseif ( $this->state == "page" ) {
- $this->thisPage .= $data;
- }
- }
- // have to skip the newline left over from closepagetag line of
- // end of checkpoint files. nasty hack!!
- if ($this->checkpointJustWritten) {
- if ($data[0] == "\n") {
- $data = substr($data,1);
- }
- $this->checkpointJustWritten = false;
- }
- $this->buffer .= htmlspecialchars( $data );
- }
-
- function clearOpenElement( $style ) {
- if ( $this->openElement ) {
- $this->buffer .= Xml::element( $this->openElement[0], $this->openElement[1], $style );
- $this->openElement = false;
- }
- }
-}
+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 919bb4df..0d0dfcf3 100644
--- a/maintenance/dumpUploads.php
+++ b/maintenance/dumpUploads.php
@@ -1,6 +1,6 @@
<?php
/**
- * Dump a the list of files uploaded, for feeding to tar or similar
+ * Dump a the list of files uploaded, for feeding to tar or similar.
*
* 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
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to dump a the list of files uploaded,
+ * for feeding to tar or similar.
+ *
+ * @ingroup Maintenance
+ */
class UploadDumper extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/edit.php b/maintenance/edit.php
index 88573714..59df5e88 100644
--- a/maintenance/edit.php
+++ b/maintenance/edit.php
@@ -1,6 +1,6 @@
<?php
/**
- * Make an edit
+ * Make a page edit.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to make a page edit.
+ *
+ * @ingroup Maintenance
+ */
class EditCLI extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/eval.php b/maintenance/eval.php
index 3bd164fd..5aefe1c9 100644
--- a/maintenance/eval.php
+++ b/maintenance/eval.php
@@ -34,7 +34,7 @@
$optionsWithArgs = array( 'd' );
/** */
-require_once( dirname( __FILE__ ) . "/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 3b43bcd5..a705bcca 100644
--- a/maintenance/fetchText.php
+++ b/maintenance/fetchText.php
@@ -1,6 +1,6 @@
<?php
/**
- * Communications protocol...
+ * Communications protocol.
* This is used by dumpTextPass.php when the --spawn option is present.
*
* This program is free software; you can redistribute it and/or modify
@@ -18,11 +18,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script used to fetch page text in a subprocess.
+ *
+ * @ingroup Maintenance
+ */
class FetchText extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/fileOpPerfTest.php b/maintenance/fileOpPerfTest.php
new file mode 100644
index 00000000..501bcfc3
--- /dev/null
+++ b/maintenance/fileOpPerfTest.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Test for fileop performance.
+ *
+ * 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
+ */
+
+$initialTime = microtime( true );
+$wgProfiler = array( 'class' => 'ProfilerSimpleText' );
+error_reporting( E_ALL );
+
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Maintenance script to test fileop performance.
+ *
+ * @ingroup Maintenance
+ */
+class TestFileOpPerformance extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Test fileop performance";
+ $this->addOption( 'b1', 'Backend 1', true, true );
+ $this->addOption( 'b2', 'Backend 2', false, true );
+ $this->addOption( 'srcdir', 'File source directory', true, true );
+ $this->addOption( 'maxfiles', 'Max files', false, true );
+ $this->addOption( 'quick', 'Avoid operation pre-checks' );
+ }
+
+ public function execute() {
+ $backend = FileBackendGroup::singleton()->get( $this->getOption( 'b1' ) );
+ $this->doPerfTest( $backend );
+
+ if ( $this->getOption( 'b2' ) ) {
+ $backend = FileBackendGroup::singleton()->get( $this->getOption( 'b2' ) );
+ $this->doPerfTest( $backend );
+ }
+
+ $profiler = Profiler::instance();
+ $profiler->setTemplated( true );
+ $profiler->logData(); // prints
+ }
+
+ protected function doPerfTest( FileBackend $backend ) {
+ $ops1 = array();
+ $ops2 = array();
+ $ops3 = array();
+ $ops4 = array();
+ $ops5 = array();
+
+ $baseDir = 'mwstore://' . $backend->getName() . '/testing-cont1';
+ $backend->prepare( array( 'dir' => $baseDir ) );
+
+ $dirname = $this->getOption( 'srcdir' );
+ $dir = opendir( $dirname );
+ if ( !$dir ) {
+ return;
+ }
+
+ while ( $dir && ( $file = readdir( $dir ) ) !== false ) {
+ if ( $file[0] != '.' ) {
+ $this->output( "Using '$dirname/$file' in operations.\n" );
+ $dst = $baseDir . '/' . wfBaseName( $file );
+ $ops1[] = array( 'op' => 'store',
+ 'src' => "$dirname/$file", 'dst' => $dst, 'overwrite' => 1);
+ $ops2[] = array( 'op' => 'copy',
+ 'src' => "$dst", 'dst' => "$dst-1", 'overwrite' => 1 );
+ $ops3[] = array( 'op' => 'move',
+ 'src' => $dst, 'dst' => "$dst-2", 'overwrite' => 1 );
+ $ops4[] = array( 'op' => 'delete', 'src' => "$dst-1" );
+ $ops5[] = array( 'op' => 'delete', 'src' => "$dst-2" );
+ }
+ if ( count( $ops1 ) >= $this->getOption( 'maxfiles', 20 ) ) {
+ break; // enough
+ }
+ }
+ closedir( $dir );
+ $this->output( "\n" );
+
+ $method = $this->hasOption( 'quick' ) ? 'doQuickOperations' : 'doOperations';
+
+ $start = microtime( true );
+ $status = $backend->$method( $ops1, array( 'force' => 1 ) );
+ $e = ( microtime( true ) - $start ) * 1000;
+ if ( $status->getErrorsArray() ) {
+ print_r( $status->getErrorsArray() );
+ exit(0);
+ }
+ $this->output( $backend->getName() . ": Stored " . count( $ops1 ) . " files in $e ms.\n" );
+
+ $start = microtime( true );
+ $backend->$method( $ops2, array( 'force' => 1 ) );
+ $e = ( microtime( true ) - $start ) * 1000;
+ if ( $status->getErrorsArray() ) {
+ print_r( $status->getErrorsArray() );
+ exit(0);
+ }
+ $this->output( $backend->getName() . ": Copied " . count( $ops2 ) . " files in $e ms.\n" );
+
+ $start = microtime( true );
+ $backend->$method( $ops3, array( 'force' => 1 ) );
+ $e = ( microtime( true ) - $start ) * 1000;
+ if ( $status->getErrorsArray() ) {
+ print_r( $status->getErrorsArray() );
+ exit(0);
+ }
+ $this->output( $backend->getName() . ": Moved " . count( $ops3 ) . " files in $e ms.\n" );
+
+ $start = microtime( true );
+ $backend->$method( $ops4, array( 'force' => 1 ) );
+ $e = ( microtime( true ) - $start ) * 1000;
+ if ( $status->getErrorsArray() ) {
+ print_r( $status->getErrorsArray() );
+ exit(0);
+ }
+ $this->output( $backend->getName() . ": Deleted " . count( $ops4 ) . " files in $e ms.\n" );
+
+ $start = microtime( true );
+ $backend->$method( $ops5, array( 'force' => 1 ) );
+ $e = ( microtime( true ) - $start ) * 1000;
+ if ( $status->getErrorsArray() ) {
+ print_r( $status->getErrorsArray() );
+ exit(0);
+ }
+ $this->output( $backend->getName() . ": Deleted " . count( $ops5 ) . " files in $e ms.\n" );
+ }
+}
+
+$maintClass = "TestFileOpPerformance";
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/findHooks.php b/maintenance/findHooks.php
index cb582857..e273c545 100644
--- a/maintenance/findHooks.php
+++ b/maintenance/findHooks.php
@@ -34,8 +34,13 @@
* @author Antoine Musso <hashar at free dot fr>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that compares documented and actually present mismatches.
+ *
+ * @ingroup Maintenance
+ */
class FindHooks extends Maintenance {
public function __construct() {
parent::__construct();
@@ -63,8 +68,10 @@ class FindHooks extends Maintenance {
$IP . '/includes/db/',
$IP . '/includes/diff/',
$IP . '/includes/filerepo/',
+ $IP . '/includes/filerepo/file/',
$IP . '/includes/installer/',
$IP . '/includes/interwiki/',
+ $IP . '/includes/logging/',
$IP . '/includes/media/',
$IP . '/includes/parser/',
$IP . '/includes/resourceloader/',
@@ -157,7 +164,7 @@ class FindHooks extends Maintenance {
/**
* Get hooks from a PHP file
- * @param $file Full filename to the PHP file.
+ * @param $file string Full filename to the PHP file.
* @return array of hooks found.
*/
private function getHooksFromFile( $file ) {
@@ -188,7 +195,7 @@ class FindHooks extends Maintenance {
/**
* Get bad hooks (where the hook name could not be determined) from a PHP file
- * @param $file Full filename to the PHP file.
+ * @param $file string Full filename to the PHP file.
* @return array of bad wfRunHooks() lines
*/
private function getBadHooksFromFile( $file ) {
diff --git a/maintenance/fixDoubleRedirects.php b/maintenance/fixDoubleRedirects.php
index c1d14dd8..6f017eca 100644
--- a/maintenance/fixDoubleRedirects.php
+++ b/maintenance/fixDoubleRedirects.php
@@ -1,8 +1,8 @@
<?php
/**
- * Script to fix double redirects.
+ * Fix double redirects.
*
- * Copyright (C) 2011 Ilmari Karonen <nospam@vyznev.net>
+ * Copyright © 2011 Ilmari Karonen <nospam@vyznev.net>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -25,15 +25,20 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fixes double redirects.
+ *
+ * @ingroup Maintenance
+ */
class FixDoubleRedirects extends Maintenance {
public function __construct() {
parent::__construct();
$this->mDescription = "Script to fix double redirects";
$this->addOption( 'async', 'Don\'t fix anything directly, just queue the jobs' );
$this->addOption( 'title', 'Fix only redirects pointing to this page', false, true );
- $this->addOption( 'dry-run', 'Perform a dry run, fix nothing' );
+ $this->addOption( 'dry-run', 'Perform a dry run, fix nothing' );
}
public function execute() {
diff --git a/maintenance/fixExtLinksProtocolRelative.php b/maintenance/fixExtLinksProtocolRelative.php
index 0cabe816..2403ec68 100644
--- a/maintenance/fixExtLinksProtocolRelative.php
+++ b/maintenance/fixExtLinksProtocolRelative.php
@@ -19,11 +19,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fixes any entriy for protocol-relative URLs
+ * in the externallinks table.
+ *
+ * @ingroup Maintenance
+ */
class FixExtLinksProtocolRelative extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/fixSlaveDesync.php b/maintenance/fixSlaveDesync.php
index 3c6888ae..8bf556f0 100644
--- a/maintenance/fixSlaveDesync.php
+++ b/maintenance/fixSlaveDesync.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Fix erroneous page_latest values due to slave desynchronisation.
+ *
* 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
@@ -15,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fixes erroneous page_latest values
+ * due to slave desynchronisation.
+ *
+ * @ingroup Maintenance
+ */
class FixSlaveDesync extends Maintenance {
public function __construct() {
parent::__construct();
@@ -88,7 +97,7 @@ class FixSlaveDesync extends Maintenance {
private function desyncFixPage( $pageID ) {
# Check for a corrupted page_latest
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ),
__METHOD__, 'FOR UPDATE' );
# list( $masterFile, $masterPos ) = $dbw->getMasterPos();
@@ -98,7 +107,7 @@ class FixSlaveDesync extends Maintenance {
/*
if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) {
$this->output( "Slave is too lagged, aborting\n" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
sleep(10);
return;
}*/
@@ -112,7 +121,7 @@ class FixSlaveDesync extends Maintenance {
}
if ( !$found ) {
$this->output( "page_id $pageID seems fine\n" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
return;
}
@@ -199,7 +208,7 @@ class FixSlaveDesync extends Maintenance {
}
$this->output( "done\n" );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
}
diff --git a/maintenance/fixTimestamps.php b/maintenance/fixTimestamps.php
index 3e3bd0a5..84d08d39 100644
--- a/maintenance/fixTimestamps.php
+++ b/maintenance/fixTimestamps.php
@@ -1,10 +1,10 @@
<?php
/**
- * This script fixes timestamp corruption caused by one or more webservers
- * temporarily being set to the wrong time. The time offset must be known and
- * consistent. Start and end times (in 14-character format) restrict the search,
- * and must bracket the damage. There must be a majority of good timestamps in the
- * search period.
+ * Fixes timestamp corruption caused by one or more webservers temporarily
+ * being set to the wrong time.
+ * The time offset must be known and consistent. Start and end times
+ * (in 14-character format) restrict the search, and must bracket the damage.
+ * There must be a majority of good timestamps in the search period.
*
* 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
@@ -21,11 +21,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fixes timestamp corruption caused by one or
+ * more webservers temporarily being set to the wrong time.
+ *
+ * @ingroup Maintenance
+ */
class FixTimestamps extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/fixUserRegistration.php b/maintenance/fixUserRegistration.php
index d4ff7c23..91d42a5d 100644
--- a/maintenance/fixUserRegistration.php
+++ b/maintenance/fixUserRegistration.php
@@ -18,11 +18,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fixes the user_registration field.
+ *
+ * @ingroup Maintenance
+ */
class FixUserRegistration extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/formatInstallDoc.php b/maintenance/formatInstallDoc.php
index b3bb50ca..600ca976 100644
--- a/maintenance/formatInstallDoc.php
+++ b/maintenance/formatInstallDoc.php
@@ -1,10 +1,33 @@
<?php
/**
+ * Format RELEASE-NOTE file to wiki text or HTML markup.
+ *
+ * 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( dirname( __FILE__ ) .'/Maintenance.php' );
+require_once( __DIR__ .'/Maintenance.php' );
+/**
+ * Maintenance script that formats RELEASE-NOTE file to wiki text or HTML markup.
+ *
+ * @ingroup Maintenance
+ */
class MaintenanceFormatInstallDoc extends Maintenance {
function __construct() {
parent::__construct();
diff --git a/maintenance/fuzz-tester.php b/maintenance/fuzz-tester.php
index d87d6281..1c96a571 100644
--- a/maintenance/fuzz-tester.php
+++ b/maintenance/fuzz-tester.php
@@ -181,7 +181,7 @@ TODO:
// ///////////////////////// COMMAND LINE HELP ////////////////////////////////////
// This is a command line script, load MediaWiki env (gives command line options);
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
// if the user asked for an explanation of command line options.
if ( isset( $options["help"] ) ) {
@@ -381,7 +381,6 @@ class wikiFuzz {
"br" => array( "CLASS", "ID", "STYLE", "title", "clear" ),
"cite" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
"var" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
- "dl" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
"ruby" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
"rt" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
"rp" => array( "CLASS", "ID", "STYLE", "lang", "dir", "title" ),
@@ -817,7 +816,7 @@ class wikiFuzz {
* Returns the matched character slash-escaped as in a C string
* Helper for makeTitleSafe callback
* @param $matches
- * @return atring
+ * @return string
*/
static private function stringEscape( $matches ) {
return sprintf( "\\x%02x", ord( $matches[1] ) );
@@ -1360,6 +1359,7 @@ class viewPageTest extends pageTest {
"rdfrom" => wikiFuzz::makeFuzz( 2 ), // things from Article.php from here on:
"token" => wikiFuzz::makeFuzz( 2 ),
"tbid" => wikiFuzz::makeFuzz( 2 ),
+ // @todo FIXME: Duplicate array key.
"action" => wikiFuzz::chooseInput( array( "purge", wikiFuzz::makeFuzz( 2 ) ) ),
"wpReason" => wikiFuzz::makeFuzz( 2 ),
"wpEditToken" => wikiFuzz::makeFuzz( 2 ),
diff --git a/maintenance/generateSitemap.php b/maintenance/generateSitemap.php
index 80d31f97..f3a5d875 100644
--- a/maintenance/generateSitemap.php
+++ b/maintenance/generateSitemap.php
@@ -1,6 +1,6 @@
<?php
/**
- * Creates a sitemap for the site
+ * Creates a sitemap for the site.
*
* Copyright © 2005, Ævar Arnfjörð Bjarmason, Jens Frank <jeluf@gmx.de> and
* Brion Vibber <brion@pobox.com>
@@ -26,8 +26,13 @@
* @see http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that generates a sitemap for the site.
+ *
+ * @ingroup Maintenance
+ */
class GenerateSitemap extends Maintenance {
const GS_MAIN = -2;
const GS_TALK = -1;
@@ -72,6 +77,13 @@ class GenerateSitemap extends Maintenance {
var $compress;
/**
+ * Whether or not to include redirection pages
+ *
+ * @var bool
+ */
+ var $skipRedirects;
+
+ /**
* The number of entries to save in each sitemap file
*
* @var array
@@ -137,6 +149,7 @@ class GenerateSitemap extends Maintenance {
$this->addOption( 'fspath', 'The file system path to save to, e.g. /tmp/sitemap; defaults to current directory', false, true );
$this->addOption( 'urlpath', 'The URL path corresponding to --fspath, prepended to filenames in the index; defaults to an empty string', false, true );
$this->addOption( 'compress', 'Compress the sitemap files, can take value yes|no, default yes', false, true );
+ $this->addOption( 'skip-redirects', 'Do not include redirecting articles in the sitemap' );
$this->addOption( 'identifier', 'What site identifier to use for the wiki, defaults to $wgDBname', false, true );
}
@@ -154,6 +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->dbr = wfGetDB( DB_SLAVE );
$this->generateNamespaces();
$this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() );
@@ -264,7 +278,7 @@ class GenerateSitemap extends Maintenance {
* @return String
*/
function guessPriority( $namespace ) {
- return MWNamespace::isMain( $namespace ) ? $this->priorities[self::GS_MAIN] : $this->priorities[self::GS_TALK];
+ return MWNamespace::isSubject( $namespace ) ? $this->priorities[self::GS_MAIN] : $this->priorities[self::GS_TALK];
}
/**
@@ -279,6 +293,7 @@ class GenerateSitemap extends Maintenance {
'page_namespace',
'page_title',
'page_touched',
+ 'page_is_redirect'
),
array( 'page_namespace' => $namespace ),
__METHOD__
@@ -302,7 +317,13 @@ class GenerateSitemap extends Maintenance {
$fns = $wgContLang->getFormattedNsText( $namespace );
$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 ) {
+ $skippedRedirects++;
+ continue;
+ }
+
if ( $i++ === 0 || $i === $this->url_limit + 1 || $length + $this->limit[1] + $this->limit[2] > $this->size_limit ) {
if ( $this->file !== false ) {
$this->write( $this->file, $this->closeFile() );
@@ -332,6 +353,11 @@ class GenerateSitemap extends Maintenance {
}
}
}
+
+ if ($this->skipRedirects && $skippedRedirects > 0) {
+ $this->output( " skipped $skippedRedirects redirect(s)\n" );
+ }
+
if ( $this->file ) {
$this->write( $this->file, $this->closeFile() );
$this->close( $this->file );
diff --git a/maintenance/getLagTimes.php b/maintenance/getLagTimes.php
index 0322fa2d..72b1d48a 100644
--- a/maintenance/getLagTimes.php
+++ b/maintenance/getLagTimes.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Display replication lag times.
+ *
* 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
@@ -15,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that displays replication lag times.
+ *
+ * @ingroup Maintenance
+ */
class GetLagTimes extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/getSlaveServer.php b/maintenance/getSlaveServer.php
index 3d13bc4e..ec9ed20a 100644
--- a/maintenance/getSlaveServer.php
+++ b/maintenance/getSlaveServer.php
@@ -1,6 +1,6 @@
<?php
/**
- * This script reports the hostname of a slave server.
+ * Reports the hostname of a slave server.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that reports the hostname of a slave server.
+ *
+ * @ingroup Maintenance
+ */
class GetSlaveServer extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/getText.php b/maintenance/getText.php
index eb044117..3e2f8540 100644
--- a/maintenance/getText.php
+++ b/maintenance/getText.php
@@ -1,6 +1,7 @@
<?php
/**
- * Outputs page text to stdout, useful for command-line editing automation.
+ * Outputs page text to stdout.
+ * Useful for command-line editing automation.
* Example: php getText.php "page title" | sed -e '...' | php edit.php "page title"
*
* This program is free software; you can redistribute it and/or modify
@@ -18,11 +19,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that outputs page text to stdout.
+ *
+ * @ingroup Maintenance
+ */
class GetTextMaint extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/hiphop/make b/maintenance/hiphop/make
index 2bb9951f..2fa70dcb 100644
--- a/maintenance/hiphop/make
+++ b/maintenance/hiphop/make
@@ -2,7 +2,7 @@
<?php
define( 'MW_CONFIG_CALLBACK', 'MakeHipHop::noConfigNeeded' );
-require( dirname( __FILE__ ) . '/../Maintenance.php' );
+require( __DIR__ . '/../Maintenance.php' );
class MakeHipHop extends Maintenance {
function noConfigNeeded() {}
@@ -12,7 +12,7 @@ class MakeHipHop extends Maintenance {
$startTime = time();
- $thisDir = realpath( dirname( __FILE__ ) );
+ $thisDir = realpath( __DIR__ );
$IP = realpath( "$thisDir/../.." );
if ( strval( $wgHipHopBuildDirectory ) !== '' ) {
$buildDir = $wgHipHopBuildDirectory;
@@ -278,7 +278,7 @@ class MakeHipHop extends Maintenance {
}
}
- $extraCoreFiles = array_map( 'trim', file( dirname( __FILE__ ) . '/extra-files' ) );
+ $extraCoreFiles = array_map( 'trim', file( __DIR__ . '/extra-files' ) );
foreach ( $extraCoreFiles as $file ) {
if ( $file === '' ) {
continue;
diff --git a/maintenance/hiphop/run-server b/maintenance/hiphop/run-server
index 0ad43134..1c4b51f4 100644
--- a/maintenance/hiphop/run-server
+++ b/maintenance/hiphop/run-server
@@ -1,7 +1,7 @@
#!/usr/bin/hphpi -f
<?php
-require( dirname( __FILE__ ) . '/../Maintenance.php' );
+require( __DIR__ . '/../Maintenance.php' );
class RunHipHopServer extends Maintenance {
function __construct() {
@@ -19,7 +19,7 @@ class RunHipHopServer extends Maintenance {
function runCompiled() {
global $wgHipHopBuildDirectory;
- $thisDir = realpath( dirname( __FILE__ ) );
+ $thisDir = realpath( __DIR__ );
$IP = realpath( "$thisDir/../.." );
if ( strval( $wgHipHopBuildDirectory ) !== '' ) {
$buildDir = $wgHipHopBuildDirectory;
@@ -51,7 +51,7 @@ class RunHipHopServer extends Maintenance {
}
function runInterpreted() {
- $thisDir = realpath( dirname( __FILE__ ) );
+ $thisDir = realpath( __DIR__ );
$IP = realpath( "$thisDir/../.." );
$sourceBase = realpath( "$IP/.." );
diff --git a/maintenance/ibm_db2/tables.sql b/maintenance/ibm_db2/tables.sql
index 66fc6564..caad9251 100644
--- a/maintenance/ibm_db2/tables.sql
+++ b/maintenance/ibm_db2/tables.sql
@@ -371,7 +371,9 @@ CREATE TABLE ipblocks (
ipb_range_end VARCHAR(1024),
ipb_deleted SMALLINT NOT NULL DEFAULT 0,
ipb_block_email SMALLINT NOT NULL DEFAULT 0,
- ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0
+ ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0,
+ ipb_parent_block_id INTEGER DEFAULT NULL
+ -- REFERENCES ipblocks(ipb_id) ON DELETE SET NULL
);
CREATE INDEX ipb_address
@@ -926,13 +928,3 @@ CREATE TABLE user_former_groups (
);
CREATE UNIQUE INDEX ufg_user_group
ON user_former_groups (ufg_user, ufg_group);
-
-
-
--- Table for holding configuration changes
-CREATE TABLE config (
- cf_name VARCHAR(255) NOT NULL
- PRIMARY KEY,
- cf_value CLOB(64K) INLINE LENGTH 4096 NOT NULL
-);
-
diff --git a/maintenance/importDump.php b/maintenance/importDump.php
index 2ad0872f..f51d7ad7 100644
--- a/maintenance/importDump.php
+++ b/maintenance/importDump.php
@@ -1,6 +1,8 @@
<?php
/**
- * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * Import XML dump files into the current wiki.
+ *
+ * Copyright © 2005 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -22,9 +24,11 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
/**
+ * Maintenance script that imports XML dump files into the current wiki.
+ *
* @ingroup Maintenance
*/
class BackupReader extends Maintenance {
@@ -204,7 +208,7 @@ TEXT;
function showReport() {
if ( !$this->mQuiet ) {
- $delta = wfTime() - $this->startTime;
+ $delta = microtime( true ) - $this->startTime;
if ( $delta ) {
$rate = sprintf( "%.2f", $this->pageCount / $delta );
$revrate = sprintf( "%.2f", $this->revCount / $delta );
@@ -250,7 +254,7 @@ TEXT;
}
function importFromHandle( $handle ) {
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
$source = new ImportStreamSource( $handle );
$importer = new WikiImporter( $source );
diff --git a/maintenance/importImages.inc b/maintenance/importImages.inc
index 5d35e2c0..ac5d1443 100644
--- a/maintenance/importImages.inc
+++ b/maintenance/importImages.inc
@@ -1,6 +1,6 @@
<?php
/**
- * Support functions for the importImages script
+ * Support functions for the importImages.php script
*
* 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
@@ -26,7 +26,7 @@
/**
* Search a directory for files with one of a set of extensions
*
- * @param $dir Path to directory to search
+ * @param $dir string Path to directory to search
* @param $exts Array of extensions to search for
* @return mixed Array of filenames on success, or false on failure
*/
@@ -74,9 +74,9 @@ function splitFilename( $filename ) {
* files for acme.foo.bar and the extension ".txt". With $maxStrip = 2,
* acme.txt would also be acceptable.
*
- * @param $file base path
- * @param $auxExtension the extension to be appended to the base path
- * @param $maxStrip the maximum number of extensions to strip from the base path (default: 1)
+ * @param $file string base path
+ * @param $auxExtension string the extension to be appended to the base path
+ * @param $maxStrip int the maximum number of extensions to strip from the base path (default: 1)
* @return string or false
*/
function findAuxFile( $file, $auxExtension, $maxStrip = 1 ) {
diff --git a/maintenance/importImages.php b/maintenance/importImages.php
index bd077ff9..8d92383d 100644
--- a/maintenance/importImages.php
+++ b/maintenance/importImages.php
@@ -1,8 +1,7 @@
<?php
-
/**
- * Maintenance script to import one or more images from the local file system into
- * the wiki without using the web-based interface.
+ * Import one or more images from the local file system into the wiki without
+ * using the web-based interface.
*
* "Smart import" additions:
* - aim: preserve the essential metadata (user, description) when importing medias from an existing wiki
@@ -33,8 +32,8 @@
*/
$optionsWithArgs = array( 'extensions', 'comment', 'comment-file', 'comment-ext', 'user', 'license', 'sleep', 'limit', 'from', 'source-wiki-url' );
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
-require_once( dirname( __FILE__ ) . '/importImages.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
+require_once( __DIR__ . '/importImages.inc' );
$processed = $added = $ignored = $skipped = $overwritten = $failed = 0;
echo( "Import Images\n\n" );
diff --git a/maintenance/importSiteScripts.php b/maintenance/importSiteScripts.php
index 0dc200ec..e369cb15 100644
--- a/maintenance/importSiteScripts.php
+++ b/maintenance/importSiteScripts.php
@@ -1,13 +1,34 @@
<?php
/**
- * Maintenance script to import all scripts in the MediaWiki namespace from a
- * local site.
+ * Import all scripts in the MediaWiki namespace from a local site.
+ *
+ * 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( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to import all scripts in the MediaWiki namespace from a
+ * local site.
+ *
+ * @ingroup Maintenance
+ */
class ImportSiteScripts extends Maintenance {
public function __construct() {
parent::__construct();
@@ -16,17 +37,17 @@ class ImportSiteScripts extends Maintenance {
$this->addArg( 'index', 'index.php base url' );
$this->addOption( 'username', 'User name of the script importer' );
}
-
+
public function execute() {
global $wgUser;
$user = User::newFromName( $this->getOption( 'username', 'ScriptImporter' ) );
$wgUser = $user;
-
+
$baseUrl = $this->getArg( 1 );
$pageList = $this->fetchScriptList();
$this->output( 'Importing ' . count( $pageList ) . " pages\n" );
-
+
foreach ( $pageList as $page ) {
$title = Title::makeTitleSafe( NS_MEDIAWIKI, $page );
if ( !$title ) {
@@ -35,34 +56,34 @@ class ImportSiteScripts extends Maintenance {
}
$this->output( "Importing $page\n" );
- $url = wfAppendQuery( $baseUrl, array(
- 'action' => 'raw',
+ $url = wfAppendQuery( $baseUrl, array(
+ 'action' => 'raw',
'title' => "MediaWiki:{$page}" ) );
$text = Http::get( $url );
$wikiPage = WikiPage::factory( $title );
$wikiPage->doEdit( $text, "Importing from $url", 0, false, $user );
}
-
+
}
-
+
protected function fetchScriptList() {
- $data = array(
+ $data = array(
'action' => 'query',
'format' => 'php',//'json',
'list' => 'allpages',
'apnamespace' => '8',
- 'aplimit' => '500',
+ 'aplimit' => '500',
);
$baseUrl = $this->getArg( 0 );
$pages = array();
-
+
do {
$url = wfAppendQuery( $baseUrl, $data );
$strResult = Http::get( $url );
//$result = FormatJson::decode( $strResult ); // Still broken
$result = unserialize( $strResult );
-
+
if ( !empty( $result['query']['allpages'] ) ) {
foreach ( $result['query']['allpages'] as $page ) {
if ( substr( $page['title'], -3 ) === '.js' ) {
@@ -76,9 +97,9 @@ class ImportSiteScripts extends Maintenance {
$this->output( "Fetching new batch from {$data['apfrom']}\n" );
}
} while ( isset( $result['query-continue'] ) );
-
+
return $pages;
-
+
}
}
diff --git a/maintenance/importTextFile.php b/maintenance/importTextFile.php
index ec9ff001..adb50635 100644
--- a/maintenance/importTextFile.php
+++ b/maintenance/importTextFile.php
@@ -1,8 +1,6 @@
<?php
-
/**
- * Maintenance script allows creating or editing pages using
- * the contents of a text file
+ * Create or edit pages using the contents of a text file.
*
* 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
@@ -26,7 +24,7 @@
$options = array( 'help', 'nooverwrite', 'norc' );
$optionsWithArgs = array( 'title', 'user', 'comment' );
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
echo( "Import Text File\n\n" );
if ( count( $args ) < 1 || isset( $options['help'] ) ) {
diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php
index 0f136450..3135b4c7 100644
--- a/maintenance/initEditCount.php
+++ b/maintenance/initEditCount.php
@@ -22,7 +22,7 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
class InitEditCount extends Maintenance {
public function __construct() {
diff --git a/maintenance/initStats.php b/maintenance/initStats.php
index eab9c8df..5d8b8866 100644
--- a/maintenance/initStats.php
+++ b/maintenance/initStats.php
@@ -1,6 +1,6 @@
<?php
/**
- * Maintenance script to re-initialise or update the site statistics table
+ * Re-initialise or update the site statistics table.
*
* 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,8 +23,13 @@
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to re-initialise or update the site statistics table
+ *
+ * @ingroup Maintenance
+ */
class InitStats extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/install.php b/maintenance/install.php
index 9a408aa6..762bb94f 100644
--- a/maintenance/install.php
+++ b/maintenance/install.php
@@ -1,6 +1,7 @@
<?php
-
/**
+ * CLI-based MediaWiki installation and configuration.
+ *
* 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
@@ -16,12 +17,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
- * @see wfWaitForSlaves()
*/
-if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.2.3' ) < 0 ) ) {
- echo "You are using PHP version " . phpversion() . " but MediaWiki needs PHP 5.2.3 or higher. ABORTING.\n" .
+if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.3.2' ) < 0 ) ) {
+ echo "You are using PHP version " . phpversion() . " but MediaWiki needs PHP 5.3.2 or higher. ABORTING.\n" .
"Check if you have a newer php executable with a different name, such as php5.\n";
die( 1 );
}
@@ -29,8 +30,13 @@ if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '
define( 'MW_CONFIG_CALLBACK', 'Installer::overrideConfig' );
define( 'MEDIAWIKI_INSTALL', true );
-require_once( dirname( dirname( __FILE__ ) )."/maintenance/Maintenance.php" );
+require_once( dirname( __DIR__ )."/maintenance/Maintenance.php" );
+/**
+ * Maintenance script to install and configure MediaWiki
+ *
+ * @ingroup Maintenance
+ */
class CommandLineInstaller extends Maintenance {
function __construct() {
parent::__construct();
@@ -39,7 +45,7 @@ class CommandLineInstaller extends Maintenance {
$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. You will be prompted for this if it isn\'t provided', false, true );
+ $this->addOption( 'pass', 'The password for the wiki administrator.', true, true );
/* $this->addOption( 'email', 'The email for the wiki administrator', false, true ); */
$this->addOption( 'scriptpath', 'The relative path of the wiki in the web server (/wiki)', false, true );
@@ -81,7 +87,7 @@ class CommandLineInstaller extends Maintenance {
}
$installer =
- new CliInstaller( $siteName, $adminName, $this->mOptions );
+ InstallerOverrides::getCliInstaller( $siteName, $adminName, $this->mOptions );
$status = $installer->doEnvironmentChecks();
if( $status->isGood() ) {
diff --git a/maintenance/interwiki.list b/maintenance/interwiki.list
index d6abd1a7..179fa5c6 100644
--- a/maintenance/interwiki.list
+++ b/maintenance/interwiki.list
@@ -14,8 +14,8 @@ docbook|http://wiki.docbook.org/topic/$1|0
doi|http://dx.doi.org/$1|0
drumcorpswiki|http://www.drumcorpswiki.com/index.php/$1|0
dwjwiki|http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1|0
-emacswiki|http://www.emacswiki.org/cgi-bin/wiki.pl?$1|0
elibre|http://enciclopedia.us.es/index.php/$1|0
+emacswiki|http://www.emacswiki.org/cgi-bin/wiki.pl?$1|0
foldoc|http://foldoc.org/?$1|0
foxwiki|http://fox.wikis.com/wc.dll?Wiki~$1|0
freebsdman|http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1|0
@@ -37,11 +37,11 @@ lqwiki|http://wiki.linuxquestions.org/wiki/$1|0
lugkr|http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1|0
mathsongswiki|http://SeedWiki.com/page.cfm?wikiid=237&doc=$1|0
meatball|http://www.usemod.com/cgi-bin/mb.pl?$1|0
-mediazilla|https://bugzilla.wikimedia.org/$1|1
mediawikiwiki|http://www.mediawiki.org/wiki/$1|0
+mediazilla|https://bugzilla.wikimedia.org/$1|1
memoryalpha|http://www.memory-alpha.org/en/index.php/$1|0
metawiki|http://sunir.org/apps/meta.pl?$1|0
-metawikipedia|http://meta.wikimedia.org/wiki/$1|0
+metawikimedia|http://meta.wikimedia.org/wiki/$1|0
moinmoin|http://purl.net/wiki/moin/$1|0
mozillawiki|http://wiki.mozilla.org/index.php/$1|0
mw|http://www.mediawiki.org/wiki/$1|0
@@ -82,10 +82,11 @@ wikicities|http://www.wikia.com/wiki/$1|0
wikif1|http://www.wikif1.org/$1|0
wikihow|http://www.wikihow.com/$1|0
wikinfo|http://www.wikinfo.org/index.php/$1|0
+# The following wik[it]* interwikis but wikitravel belong to the Wikimedia Family:
wikimedia|http://wikimediafoundation.org/wiki/$1|0
wikinews|http://en.wikinews.org/wiki/$1|1
-wikiquote|http://en.wikiquote.org/wiki/$1|1
wikipedia|http://en.wikipedia.org/wiki/$1|1
+wikiquote|http://en.wikiquote.org/wiki/$1|1
wikisource|http://wikisource.org/wiki/$1|1
wikispecies|http://species.wikimedia.org/wiki/$1|1
wikitravel|http://wikitravel.org/en/$1|0
diff --git a/maintenance/interwiki.sql b/maintenance/interwiki.sql
index 6efc1e0e..370460af 100644
--- a/maintenance/interwiki.sql
+++ b/maintenance/interwiki.sql
@@ -16,8 +16,8 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
('doi','http://dx.doi.org/$1',0),
('drumcorpswiki','http://www.drumcorpswiki.com/index.php/$1',0),
('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0),
-('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0),
('elibre','http://enciclopedia.us.es/index.php/$1',0),
+('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0),
('foldoc','http://foldoc.org/?$1',0),
('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0),
('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0),
@@ -39,11 +39,11 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
('lugkr','http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?$1',0),
('mathsongswiki','http://SeedWiki.com/page.cfm?wikiid=237&doc=$1',0),
('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0),
-('mediazilla','https://bugzilla.wikimedia.org/$1',1),
('mediawikiwiki','http://www.mediawiki.org/wiki/$1',0),
+('mediazilla','https://bugzilla.wikimedia.org/$1',1),
('memoryalpha','http://www.memory-alpha.org/en/index.php/$1',0),
('metawiki','http://sunir.org/apps/meta.pl?$1',0),
-('metawikipedia','http://meta.wikimedia.org/wiki/$1',0),
+('metawikimedia','http://meta.wikimedia.org/wiki/$1',0),
('moinmoin','http://purl.net/wiki/moin/$1',0),
('mozillawiki','http://wiki.mozilla.org/index.php/$1',0),
('mw','http://www.mediawiki.org/wiki/$1',0),
@@ -84,10 +84,11 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local) VALUES
('wikif1','http://www.wikif1.org/$1',0),
('wikihow','http://www.wikihow.com/$1',0),
('wikinfo','http://www.wikinfo.org/index.php/$1',0),
+# The following wik[it]* interwikis but wikitravel belong to the Wikimedia Family:
('wikimedia','http://wikimediafoundation.org/wiki/$1',0),
('wikinews','http://en.wikinews.org/wiki/$1',1),
-('wikiquote','http://en.wikiquote.org/wiki/$1',1),
('wikipedia','http://en.wikipedia.org/wiki/$1',1),
+('wikiquote','http://en.wikiquote.org/wiki/$1',1),
('wikisource','http://wikisource.org/wiki/$1',1),
('wikispecies','http://species.wikimedia.org/wiki/$1',1),
('wikitravel','http://wikitravel.org/en/$1',0),
diff --git a/maintenance/jsparse.php b/maintenance/jsparse.php
index da6798e1..ceafc390 100644
--- a/maintenance/jsparse.php
+++ b/maintenance/jsparse.php
@@ -1,6 +1,6 @@
<?php
/**
- * Maintenance script to do test JavaScript validity parses using jsmin+'s parser
+ * Test JavaScript validity parses using jsmin+'s parser
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to do test JavaScript validity parses using jsmin+'s parser
+ *
+ * @ingroup Maintenance
+ */
class JSParseHelper extends Maintenance {
var $errs = 0;
@@ -35,7 +41,7 @@ class JSParseHelper extends Maintenance {
if ( $this->hasArg() ) {
$files = $this->mArgs;
} else {
- $this->maybeHelp( true ); // @fixme this is a lame API :)
+ $this->maybeHelp( true ); // @todo fixme this is a lame API :)
exit( 1 ); // it should exit from the above first...
}
diff --git a/maintenance/lag.php b/maintenance/lag.php
index dc8bff5f..3ad0864f 100644
--- a/maintenance/lag.php
+++ b/maintenance/lag.php
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to show database lag.
+ *
+ * @ingroup Maintenance
+ */
class DatabaseLag extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/language/StatOutputs.php b/maintenance/language/StatOutputs.php
index befd0d72..d77029e7 100644
--- a/maintenance/language/StatOutputs.php
+++ b/maintenance/language/StatOutputs.php
@@ -46,7 +46,7 @@ class statsOutput {
/** Outputs WikiText */
class wikiStatsOutput extends statsOutput {
function heading() {
- global $wgDummyLanguageCodes, $wgContLang;
+ global $wgDummyLanguageCodes;
$version = SpecialVersion::getVersion( 'nodb' );
echo "'''Statistics are based on:''' <code>" . $version . "</code>\n\n";
echo "'''Note:''' These statistics can be generated by running <code>php maintenance/language/transstat.php</code>.\n\n";
@@ -55,7 +55,7 @@ class wikiStatsOutput extends statsOutput {
if( is_array( $wgDummyLanguageCodes ) ) {
$dummyCodes = array();
foreach( $wgDummyLanguageCodes as $dummyCode => $correctCode ) {
- $dummyCodes[] = $wgContLang->getLanguageName( $dummyCode ) . ' (' . $dummyCode . ')';
+ $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 );
}
diff --git a/maintenance/language/alltrans.php b/maintenance/language/alltrans.php
index f872e6a6..8caf8677 100644
--- a/maintenance/language/alltrans.php
+++ b/maintenance/language/alltrans.php
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+/**
+ * Maintenance script that gets all messages as defined by the
+ * English language file.
+ *
+ * @ingroup MaintenanceLanguage
+ */
class AllTrans extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/language/checkDupeMessages.php b/maintenance/language/checkDupeMessages.php
index ea5b1870..6abf7b44 100644
--- a/maintenance/language/checkDupeMessages.php
+++ b/maintenance/language/checkDupeMessages.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to print out duplicates in message array
+ * Print out duplicates in message array
*
* 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
@@ -21,8 +21,8 @@
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
-$messagesDir = dirname( __FILE__ ) . '/../../languages/messages/';
+require_once( __DIR__ . '/../commandLine.inc' );
+$messagesDir = __DIR__ . '/../../languages/messages/';
$runTest = false;
$run = false;
$runMode = 'text';
diff --git a/maintenance/language/checkExtensions.php b/maintenance/language/checkExtensions.php
index a58a8f5c..ebc62b60 100644
--- a/maintenance/language/checkExtensions.php
+++ b/maintenance/language/checkExtensions.php
@@ -21,7 +21,7 @@
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+require_once( __DIR__ . '/../commandLine.inc' );
require_once( 'languages.inc' );
require_once( 'checkLanguage.inc' );
diff --git a/maintenance/language/checkLanguage.inc b/maintenance/language/checkLanguage.inc
index 8ab6125b..11b00e14 100644
--- a/maintenance/language/checkLanguage.inc
+++ b/maintenance/language/checkLanguage.inc
@@ -41,7 +41,7 @@ class CheckLanguageCLI {
/**
* Constructor.
- * @param $options Options for script.
+ * @param $options array Options for script.
*/
public function __construct( Array $options ) {
if ( isset( $options['help'] ) ) {
@@ -94,7 +94,7 @@ class CheckLanguageCLI {
/**
* Get the default checks.
- * @return A list of the default checks.
+ * @return array A list of the default checks.
*/
protected function defaultChecks() {
return array(
@@ -107,7 +107,7 @@ class CheckLanguageCLI {
/**
* Get the checks which check other things than messages.
- * @return A list of the non-message checks.
+ * @return array A list of the non-message checks.
*/
protected function nonMessageChecks() {
return array(
@@ -129,7 +129,7 @@ class CheckLanguageCLI {
/**
* Get all checks.
- * @return An array of all check names mapped to their function names.
+ * @return array An array of all check names mapped to their function names.
*/
protected function getChecks() {
return array(
@@ -157,7 +157,7 @@ class CheckLanguageCLI {
/**
* Get total count for each check non-messages check.
- * @return An array of all check names mapped to a two-element array:
+ * @return array An array of all check names mapped to a two-element array:
* function name to get the total count and language code or null
* for checked code.
*/
@@ -176,7 +176,7 @@ class CheckLanguageCLI {
/**
* Get all check descriptions.
- * @return An array of all check names mapped to their descriptions.
+ * @return array An array of all check names mapped to their descriptions.
*/
protected function getDescriptions() {
return array(
@@ -204,7 +204,7 @@ class CheckLanguageCLI {
/**
* Get help.
- * @return The help string.
+ * @return string The help string.
*/
protected function help() {
return <<<ENDS
@@ -222,17 +222,17 @@ 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: Don't 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: Don't do the following checks (form: code,code).
+ --blacklist: Do not do the following checks (form: code,code).
--easy: Do only the easy checks, which can be treated by non-speakers of the language.
Check codes (ideally, all of them should result 0; all the checks are executed by default (except language-specific check blacklists in checkLanguage.inc):
* untranslated: Messages which are required to translate, but are not translated.
* duplicate: Messages which translation equal to fallback
* obsolete: Messages which are untranslatable or do not exist, but are translated.
- * variables: Messages without variables which should be used, or with variables which shouldn't be used.
+ * variables: Messages without variables which should be used, or with variables which should not be used.
* empty: Empty messages and messages that contain only -.
* whitespace: Messages which have trailing whitespace.
* xhtml: Messages which are not well-formed XHTML (checks only few common errors).
@@ -295,7 +295,7 @@ ENDS;
/**
* Get the check blacklist.
- * @return The list of checks which should not be executed.
+ * @return array The list of checks which should not be executed.
*/
protected function getCheckBlacklist() {
global $checkBlacklist;
@@ -336,9 +336,9 @@ ENDS;
/**
* Format a message key.
- * @param $key The message key.
- * @param $code The language code.
- * @return The formatted message key.
+ * @param $key string The message key.
+ * @param $code string The language code.
+ * @return string The formatted message key.
*/
protected function formatKey( $key, $code ) {
if ( $this->doLinks ) {
@@ -355,7 +355,6 @@ ENDS;
/**
* Output the checks results as plain text.
- * @return The checks results as plain text.
*/
protected function outputText() {
foreach ( $this->results as $code => $results ) {
@@ -401,10 +400,8 @@ ENDS;
/**
* Output the checks results as wiki text.
- * @return The checks results as wiki text.
*/
function outputWiki() {
- global $wgContLang;
$detailText = '';
$rows[] = '! Language !! Code !! Total !! ' . implode( ' !! ', array_diff( $this->checks, $this->nonMessageChecks() ) );
foreach ( $this->results as $code => $results ) {
@@ -440,7 +437,7 @@ ENDS;
# Don't list languages without problems
continue;
}
- $language = $wgContLang->getLanguageName( $code );
+ $language = Language::fetchLanguageName( $code );
$rows[] = "| $language || $code || $problems || " . implode( ' || ', $numbers );
}
@@ -462,7 +459,7 @@ EOL;
/**
* Check if there are any results for the checks, in any language.
- * @return True if there are any results, false if not.
+ * @return bool True if there are any results, false if not.
*/
protected function isEmpty() {
foreach( $this->results as $results ) {
@@ -484,8 +481,8 @@ class CheckExtensionsCLI extends CheckLanguageCLI {
/**
* Constructor.
- * @param $options Options for script.
- * @param $extension The extension name (or names).
+ * @param $options array Options for script.
+ * @param $extension string The extension name (or names).
*/
public function __construct( Array $options, $extension ) {
if ( isset( $options['help'] ) ) {
@@ -569,7 +566,7 @@ class CheckExtensionsCLI extends CheckLanguageCLI {
/**
* Get the default checks.
- * @return A list of the default checks.
+ * @return array A list of the default checks.
*/
protected function defaultChecks() {
return array(
@@ -580,7 +577,7 @@ class CheckExtensionsCLI extends CheckLanguageCLI {
/**
* Get the checks which check other things than messages.
- * @return A list of the non-message checks.
+ * @return array A list of the non-message checks.
*/
protected function nonMessageChecks() {
return array();
@@ -588,7 +585,7 @@ class CheckExtensionsCLI extends CheckLanguageCLI {
/**
* Get the checks that can easily be treated by non-speakers of the language.
- * @return A list of the easy checks.
+ * @return arrayA list of the easy checks.
*/
protected function easyChecks() {
return array(
@@ -598,7 +595,7 @@ class CheckExtensionsCLI extends CheckLanguageCLI {
/**
* Get help.
- * @return The help string.
+ * @return string The help string.
*/
protected function help() {
return <<<ENDS
diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php
index 69f61084..99ba4e98 100644
--- a/maintenance/language/checkLanguage.php
+++ b/maintenance/language/checkLanguage.php
@@ -21,7 +21,7 @@
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+require_once( __DIR__ . '/../commandLine.inc' );
require_once( 'checkLanguage.inc' );
require_once( 'languages.inc' );
diff --git a/maintenance/language/countMessages.php b/maintenance/language/countMessages.php
index f949ddc2..5058a549 100644
--- a/maintenance/language/countMessages.php
+++ b/maintenance/language/countMessages.php
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+/**
+ * Maintenance script that counts how many messages we have defined
+ * for each language.
+ *
+ * @ingroup MaintenanceLanguage
+ */
class CountMessages extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/language/date-formats.php b/maintenance/language/date-formats.php
index 04f5e8ba..ed12b786 100644
--- a/maintenance/language/date-formats.php
+++ b/maintenance/language/date-formats.php
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+/**
+ * Maintenance script that tests various language time and date functions.
+ *
+ * @ingroup MaintenanceLanguage
+ */
class DateFormats extends Maintenance {
private $ts = '20010115123456';
diff --git a/maintenance/language/digit2html.php b/maintenance/language/digit2html.php
index a80ac014..9d4cbe7e 100644
--- a/maintenance/language/digit2html.php
+++ b/maintenance/language/digit2html.php
@@ -1,5 +1,7 @@
<?php
/**
+ * Check digit transformation
+ *
* 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
@@ -15,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+/**
+ * Maintenance script that check digit transformation.
+ *
+ * @ingroup MaintenanceLanguage
+ */
class Digit2Html extends Maintenance {
# A list of unicode numerals is available at:
diff --git a/maintenance/language/dumpMessages.php b/maintenance/language/dumpMessages.php
index 9bdda09d..0292d314 100644
--- a/maintenance/language/dumpMessages.php
+++ b/maintenance/language/dumpMessages.php
@@ -18,24 +18,30 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup MaintenanceLanguage
- * @todo Make this more useful, right now just dumps $wgContentLang
+ * @todo Make this more useful, right now just dumps $wgContLang
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
+/**
+ * Maintenance script that dumps an entire language, using the keys from English.
+ *
+ * @ingroup MaintenanceLanguage
+ */
class DumpMessages extends Maintenance {
public function __construct() {
parent::__construct();
$this->mDescription = "Dump an entire language, using the keys from English";
}
-
+
public function execute() {
global $wgVersion;
$messages = array();
foreach ( array_keys( Language::getMessagesFor( 'en' ) ) as $key ) {
- $messages[$key] = wfMsg( $key );
+ $messages[$key] = wfMessage( $key )->text();
}
$this->output( "MediaWiki $wgVersion language file\n" );
$this->output( serialize( $messages ) );
diff --git a/maintenance/language/generateCollationData.php b/maintenance/language/generateCollationData.php
index e5ce5c87..e34d9a13 100644
--- a/maintenance/language/generateCollationData.php
+++ b/maintenance/language/generateCollationData.php
@@ -1,13 +1,32 @@
<?php
/**
- * @ingroup Maintenance
+ * Maintenance script to generate first letter data files for Collation.php.
+ *
+ * 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 MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) .'/../Maintenance.php' );
+require_once( __DIR__ .'/../Maintenance.php' );
/**
* Generate first letter data files for Collation.php
+ *
+ * @ingroup MaintenanceLanguage
*/
class GenerateCollationData extends Maintenance {
/** The directory with source data files in it */
@@ -386,4 +405,3 @@ class UcdXmlReader {
$maintClass = 'GenerateCollationData';
require_once( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/maintenance/language/generateNormalizerData.php b/maintenance/language/generateNormalizerData.php
index a958abf1..54dfa39a 100644
--- a/maintenance/language/generateNormalizerData.php
+++ b/maintenance/language/generateNormalizerData.php
@@ -21,13 +21,15 @@
* @ingroup MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/../../includes/normal/UtfNormalUtil.php' );
+require_once( __DIR__ . '/../../includes/normal/UtfNormalUtil.php' );
/**
* Generates normalizer data files for Arabic and Malayalam.
* For NFC see includes/normal.
+ *
+ * @ingroup MaintenanceLanguage
*/
class GenerateNormalizerData extends Maintenance {
var $dataFile;
@@ -155,4 +157,3 @@ class GenerateNormalizerData extends Maintenance {
$maintClass = 'GenerateNormalizerData';
require_once( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/maintenance/language/lang2po.php b/maintenance/language/lang2po.php
deleted file mode 100644
index 7e5dc472..00000000
--- a/maintenance/language/lang2po.php
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-/**
- * Convert Language files to .po files !
- *
- * Todo:
- * - generate .po header
- * - fix escaping of \
- *
- * 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
- *
- * @ingroup MaintenanceLanguage
- */
-
-/** This is a command line script */
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/languages.inc' );
-
-define( 'ALL_LANGUAGES', true );
-define( 'XGETTEXT_BIN', 'xgettext' );
-define( 'MSGMERGE_BIN', 'msgmerge' );
-
-// used to generate the .pot
-define( 'XGETTEXT_OPTIONS', '-n --keyword=wfMsg --keyword=wfMsgForContent --keyword=wfMsgHtml --keyword=wfMsgWikiHtml ' );
-define( 'MSGMERGE_OPTIONS', ' -v ' );
-
-define( 'LOCALE_OUTPUT_DIR', $IP . '/locale' );
-
-class Lang2Po extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->mDescription = "";
- $this->addOption( 'lang', 'a lang code you want to generate a .po for (default: all langs)', false, true );
- }
-
- public function execute() {
- // Generate a template .pot based on source tree
- $this->output( "Getting 'gettext' default messages from sources:" );
- $this->generatePot();
- $this->output( "done.\n" );
-
-
- $langTool = new languages();
- if ( $this->getOption( 'lang', ALL_LANGUAGES ) === ALL_LANGUAGES ) {
- $codes = $langTool->getLanguages();
- } else {
- $codes = array( $this->getOption( 'lang' ) );
- }
-
- // Do all languages
- foreach ( $codes as $langcode ) {
- $this->output( "Loading messages for $langcode:\n" );
- if ( !$this->generatePo( $langcode, $langTool->getMessages( $langcode ) ) ) {
- $this->error( "ERROR: Failed to write file." );
- } else {
- $this->output( "Applying template:" );
- $this->applyPot( $langcode );
- }
- }
- }
-
- /**
- * Return a dummy header for later edition.
- *
- * @return String: a dummy header
- */
- private function poHeader() {
- return '# SOME DESCRIPTIVE TITLE.
-# Copyright (C) 2005 MediaWiki
-# This file is distributed under the same license as the MediaWiki package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: bugzilllaaaaa\n"
-"POT-Creation-Date: 2005-08-16 20:13+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: VARIOUS <nobody>\n"
-"Language-Team: LANGUAGE <nobody>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-';
- }
-
- /**
- * generate and write a file in .po format.
- *
- * @param $langcode String: code of a language it will process.
- * @param $messages Array containing the various messages.
- * @return string Filename where stuff got saved or false.
- */
- private function generatePo( $langcode, $messages ) {
- $data = $this->poHeader();
-
- // Generate .po entries
- foreach ( $messages['all'] as $identifier => $content ) {
- $data .= "msgid \"$identifier\"\n";
-
- // Escape backslashes
- $tmp = str_replace( '\\', '\\\\', $content );
- // Escape doublelquotes
- $tmp = preg_replace( "/(?<!\\\\)\"/", '\"', $tmp );
- // Rewrite multilines to gettext format
- $tmp = str_replace( "\n", "\"\n\"", $tmp );
-
- $data .= 'msgstr "' . $tmp . "\"\n\n";
- }
-
- // Write the content to a file in locale/XX/messages.po
- $dir = LOCALE_OUTPUT_DIR . '/' . $langcode;
- if ( !is_dir( $dir ) ) { mkdir( $dir, 0770 ); }
- $filename = $dir . '/fromlanguagefile.po';
-
- $file = fopen( $filename , 'wb' );
- if ( fwrite( $file, $data ) ) {
- fclose( $file );
- return $filename;
- } else {
- fclose( $file );
- return false;
- }
- }
-
- private function generatePot() {
- global $IP;
- $curdir = getcwd();
- chdir( $IP );
- exec( XGETTEXT_BIN
- . ' ' . XGETTEXT_OPTIONS
- . ' -o ' . LOCALE_OUTPUT_DIR . '/wfMsg.pot'
- . ' includes/*php'
- );
- chdir( $curdir );
- }
-
- private function applyPot( $langcode ) {
- $langdir = LOCALE_OUTPUT_DIR . '/' . $langcode;
-
- $from = $langdir . '/fromlanguagefile.po';
- $pot = LOCALE_OUTPUT_DIR . '/wfMsg.pot';
- $dest = $langdir . '/messages.po';
-
- // Merge template and generate file to get final .po
- exec( MSGMERGE_BIN . MSGMERGE_OPTIONS . " $from $pot -o $dest " );
- // delete no more needed file
- // unlink($from);
- }
-}
-
-$maintClass = "Lang2Po";
-require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/language/langmemusage.php b/maintenance/language/langmemusage.php
index 28fe120e..2323638e 100644
--- a/maintenance/language/langmemusage.php
+++ b/maintenance/language/langmemusage.php
@@ -22,8 +22,8 @@
*/
/** This is a command line script */
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/languages.inc' );
+require_once( __DIR__ . '/../Maintenance.php' );
+require_once( __DIR__ . '/languages.inc' );
class LangMemUsage extends Maintenance {
diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc
index 06102ac1..b76f921d 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 Treat the EXIF messages?
+ * @param $exif bool Treat the EXIF messages?
*/
function __construct( $exif = true ) {
- require( dirname(__FILE__) . '/messageTypes.inc' );
+ require( __DIR__ . '/messageTypes.inc' );
$this->mIgnoredMessages = $wgIgnoredMessages;
if ( $exif ) {
$this->mOptionalMessages = array_merge( $wgOptionalMessages );
@@ -54,7 +54,7 @@ class languages {
$this->mOptionalMessages = array_merge( $wgOptionalMessages, $wgEXIFMessages );
}
- $this->mLanguages = array_keys( Language::getLanguageNames( true ) );
+ $this->mLanguages = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) );
sort( $this->mLanguages );
}
@@ -244,7 +244,7 @@ class languages {
*
* @param $code string The language code.
*
- * @return Namespace names.
+ * @return array Namespace names.
*/
public function getNamespaceNames( $code ) {
$this->loadFile( $code );
@@ -256,7 +256,7 @@ class languages {
*
* @param $code string The language code.
*
- * @return Namespace aliases.
+ * @return array Namespace aliases.
*/
public function getNamespaceAliases( $code ) {
$this->loadFile( $code );
@@ -268,7 +268,7 @@ class languages {
*
* @param $code string The language code.
*
- * @return Magic words.
+ * @return array Magic words.
*/
public function getMagicWords( $code ) {
$this->loadFile( $code );
@@ -280,7 +280,7 @@ class languages {
*
* @param $code string The language code.
*
- * @return Special page aliases.
+ * @return array Special page aliases.
*/
public function getSpecialPageAliases( $code ) {
$this->loadFile( $code );
@@ -734,7 +734,7 @@ class extensionLanguages extends languages {
/**
* Load the messages group.
- * @param $group The messages group.
+ * @param $group MessageGroup The messages group.
*/
function __construct( MessageGroup $group ) {
$this->mMessageGroup = $group;
diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc
index 1c33667a..ce1dbb9b 100644
--- a/maintenance/language/messageTypes.inc
+++ b/maintenance/language/messageTypes.inc
@@ -123,6 +123,7 @@ $wgIgnoredMessages = array(
'pubmedurl',
'randompage-url',
'recentchanges-url',
+ 'recentchangestext',
'revision-info-current',
'revision-nav',
'rfcurl',
@@ -136,6 +137,7 @@ $wgIgnoredMessages = array(
'sitetitle',
'sp-contributions-footer',
'sp-contributions-footer-anon',
+ 'sp-contributions-footer-newbies',
'statistics-summary',
'statistics-footer',
'talkpagetext',
@@ -161,11 +163,13 @@ $wgIgnoredMessages = array(
'wantedcategories-summary',
'wantedfiles-summary',
'wantedpages-summary',
+ 'watchlist-summary',
'mostlinked-summary',
'mostlinkedcategories-summary',
'mostlinkedtemplates-summary',
'mostcategories-summary',
'mostimages-summary',
+ 'mostinterwikis-summary',
'mostrevisions-summary',
'prefixindex-summary',
'shortpages-summary',
@@ -185,12 +189,63 @@ $wgIgnoredMessages = array(
'wantedtemplates-summary',
'activeusers-summary',
'search-summary',
+ 'editpage-head-copy-warn',
'editpage-tos-summary',
'addsection-preload',
'addsection-editintro',
'longpage-hint',
'javascripttest-backlink',
'javascripttest-qunit-name',
+ 'revdelete-logentry',
+ 'logdelete-logentry',
+ 'revdelete-content',
+ 'revdelete-summary',
+ 'revdelete-uname',
+ 'revdelete-hid',
+ 'revdelete-unhid',
+ 'revdelete-log-message',
+ 'logdelete-log-message',
+ 'deletedarticle',
+ 'suppressedarticle',
+ 'undeletedarticle',
+ 'patrol-log-line',
+ 'patrol-log-auto',
+ 'patrol-log-diff',
+ '1movedto2',
+ '1movedto2_redir',
+ 'move-redirect-suppressed',
+ // 'newuserlog-byemail',
+ 'newuserlog-create-entry',
+ 'newuserlog-create2-entry',
+ 'newuserlog-autocreate-entry',
+ 'suppressedarticle',
+ 'deletedarticle',
+ // 'uploadedimage',
+ // 'overwroteimage',
+ 'userlogout-summary',
+ 'changeemail-summary',
+ 'changepassword-summary',
+ 'unusedcategories-summary',
+ 'unusedimages-summary',
+ 'deletedcontributions-summary',
+ 'linksearch-summary',
+ 'emailuser-summary',
+ 'undelete-summary',
+ 'contributions-summary',
+ 'unblock-summary',
+ 'movepage-summary',
+ 'export-summary',
+ 'import-summary',
+ 'editwatchlist-summary',
+ 'version-summary',
+ 'tags-summary',
+ 'comparepages-summary',
+ 'version-entrypoints-index-php',
+ 'version-entrypoints-api-php',
+ 'version-entrypoints-load-php',
+ 'ipb-default-expiry',
+ 'pageinfo-header',
+ 'pageinfo-footer',
);
/** Optional messages, which may be translated only if changed in the target language. */
@@ -201,7 +256,6 @@ $wgOptionalMessages = array(
'feed-rss',
'unit-pixel',
'userrights-irreversible-marker',
- 'tog-nolangconversion',
'tog-noconvertlink',
'variantname-zh-hans',
'variantname-zh-hant',
@@ -402,6 +456,7 @@ $wgOptionalMessages = array(
'ellipsis',
'percent',
'parentheses',
+ 'brackets',
'autocomment-prefix',
'listgrouprights-right-display',
'listgrouprights-right-revoked',
@@ -418,6 +473,12 @@ $wgOptionalMessages = array(
'metadata-langitem',
'metadata-langitem-default',
'nocookiesforlogin',
+ 'version-entrypoints-articlepath',
+ 'version-entrypoints-scriptpath',
+ 'mergehistory-revisionrow',
+ 'categoryviewer-pagedlinks',
+ 'undelete-revisionrow',
+ 'pageinfo-redirects-value',
);
/** EXIF messages, which may be set as optional in several checks, but are generally mandatory */
diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc
index bee5a67c..29269175 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -28,7 +28,6 @@ $wgMessageStructure = array(
),
'toggles' => array(
'tog-underline',
- 'tog-highlightbroken',
'tog-justify',
'tog-hideminor',
'tog-hidepatrolled',
@@ -68,7 +67,6 @@ $wgMessageStructure = array(
'tog-watchlisthideliu',
'tog-watchlisthideanons',
'tog-watchlisthidepatrolled',
- 'tog-nolangconversion',
'tog-ccmeonemails',
'tog-diffonly',
'tog-showhiddencats',
@@ -158,6 +156,7 @@ $wgMessageStructure = array(
'index-category',
'noindex-category',
'broken-file-category',
+ 'categoryviewer-pagedlinks',
),
'mainpage' => array(
'linkprefix',
@@ -306,6 +305,10 @@ $wgMessageStructure = array(
'youhavenewmessages',
'newmessageslink',
'newmessagesdifflink',
+ 'youhavenewmessagesfromusers',
+ 'youhavenewmessagesmanyusers',
+ 'newmessageslinkplural',
+ 'newmessagesdifflinkplural',
'youhavenewmessagesmulti',
'newtalkseparator',
'editsection',
@@ -368,9 +371,9 @@ $wgMessageStructure = array(
'readonly',
'enterlockreason',
'readonlytext',
- 'missing-article',
- 'missingarticle-rev',
- 'missingarticle-diff',
+ 'missing-article', // not used anymore in core, but kept for extensions
+ 'missingarticle-rev', // not used anymore in core, but kept for extensions
+ 'missingarticle-diff', // not used anymore in core, but kept for extensions
'readonly_lag',
'internalerror',
'internalerror_info',
@@ -387,6 +390,7 @@ $wgMessageStructure = array(
'badarticleerror',
'cannotdelete',
'cannotdelete-title',
+ 'delete-hook-aborted',
'badtitle',
'badtitletext',
'perfcached',
@@ -409,6 +413,11 @@ $wgMessageStructure = array(
'customjsprotected',
'ns-specialprotected',
'titleprotected',
+ 'filereadonlyerror',
+ 'invalidtitle-knownnamespace',
+ 'invalidtitle-unknownnamespace',
+ 'exception-nologin',
+ 'exception-nologin-text',
),
'virus' => array(
'virus-badscanner',
@@ -424,6 +433,7 @@ $wgMessageStructure = array(
'remembermypassword',
'securelogin-stick-https',
'yourdomainname',
+ 'password-change-forbidden',
'externaldberror',
'login',
'nav-login-createaccount',
@@ -432,6 +442,7 @@ $wgMessageStructure = array(
'userloginnocreate',
'logout',
'userlogout',
+ 'userlogout-summary',
'notloggedin',
'nologin',
'nologinlink',
@@ -484,6 +495,7 @@ $wgMessageStructure = array(
'emailconfirmlink',
'invalidemailaddress',
'cannotchangeemail',
+ 'emaildisabled',
'accountcreated',
'accountcreatedtext',
'createaccount-title',
@@ -539,6 +551,7 @@ $wgMessageStructure = array(
),
'changeemail' => array(
'changeemail',
+ 'changeemail-summary',
'changeemail-header',
'changeemail-text',
'changeemail-no-info',
@@ -606,6 +619,7 @@ $wgMessageStructure = array(
'noarticletext',
'noarticletext-nopermission',
'noarticletextanon',
+ 'missing-revision',
'userpage-userdoesnotexist',
'userpage-userdoesnotexist-view',
'blocked-notice-logextract',
@@ -620,12 +634,14 @@ $wgMessageStructure = array(
'updated',
'note',
'previewnote',
+ 'continue-editing',
'previewconflict',
'session_fail_preview',
'session_fail_preview_html',
'token_suffix_mismatch',
'edit_form_incomplete',
'editing',
+ 'creating',
'editingsection',
'editingcomment',
'editconflict',
@@ -637,6 +653,7 @@ $wgMessageStructure = array(
'yourdiff',
'copyrightwarning',
'copyrightwarning2',
+ 'editpage-head-copy-warn',
'editpage-tos-summary',
'longpage-hint',
'longpageerror',
@@ -671,6 +688,7 @@ $wgMessageStructure = array(
'edit-already-exists',
'addsection-preload',
'addsection-editintro',
+ 'defaultmessagetext',
),
'parserwarnings' => array(
'expensive-parserfunction-warning',
@@ -682,6 +700,13 @@ $wgMessageStructure = array(
'parser-template-loop-warning',
'parser-template-recursion-depth-warning',
'language-converter-depth-warning',
+ 'node-count-exceeded-category',
+ 'node-count-exceeded-warning',
+ 'expansion-depth-exceeded-category',
+ 'expansion-depth-exceeded-warning',
+ 'parser-unstrip-loop-warning',
+ 'parser-unstrip-recursion-limit',
+ 'converter-manual-rule-error',
),
'undo' => array(
'undo-success',
@@ -818,7 +843,8 @@ $wgMessageStructure = array(
'mergehistory-autocomment',
'mergehistory-comment',
'mergehistory-same-destination',
- 'mergehistory-reason'
+ 'mergehistory-reason',
+ 'mergehistory-revisionrow'
),
'mergelog' => array(
'mergelog',
@@ -828,7 +854,8 @@ $wgMessageStructure = array(
),
'diffs' => array(
'history-title',
- 'difference',
+ 'difference-title',
+ 'difference-title-multipage',
'difference-multipage',
'lineno',
'compareselectedversions',
@@ -836,6 +863,7 @@ $wgMessageStructure = array(
'editundo',
'diff-multi',
'diff-multi-manyusers',
+ 'difference-missing-revision',
),
'search' => array(
'search-summary',
@@ -882,8 +910,6 @@ $wgMessageStructure = array(
'search-interwiki-default',
'search-interwiki-custom',
'search-interwiki-more',
- 'search-mwsuggest-enabled',
- 'search-mwsuggest-disabled',
'search-relatedarticle',
'mwsuggest-disable',
'searcheverything-enable',
@@ -926,12 +952,14 @@ $wgMessageStructure = array(
'prefsnologin',
'prefsnologintext',
'changepassword',
+ 'changepassword-summary',
'prefs-skin',
'skin-preview',
'datedefault',
'prefs-beta',
'prefs-datetime',
'prefs-labs',
+ 'prefs-user-pages',
'prefs-personal',
'prefs-rc',
'prefs-watchlist',
@@ -1112,6 +1140,7 @@ $wgMessageStructure = array(
'right-writeapi',
'right-delete',
'right-bigdelete',
+ 'right-deletelogentry',
'right-deleterevision',
'right-deletedhistory',
'right-deletedtext',
@@ -1197,6 +1226,7 @@ $wgMessageStructure = array(
'recentchanges',
'recentchanges-url',
'recentchanges-legend',
+ 'recentchanges-summary',
'recentchangestext',
'recentchanges-feed-description',
'recentchanges-label-newpage',
@@ -1346,6 +1376,7 @@ $wgMessageStructure = array(
'upload-too-many-redirects',
'upload-unknown-size',
'upload-http-error',
+ 'upload-copy-upload-invalid-domain',
),
'filebackend-errors' => array(
@@ -1365,12 +1396,19 @@ $wgMessageStructure = array(
'backend-fail-closetemp',
'backend-fail-read',
'backend-fail-create',
+ 'backend-fail-maxsize',
'backend-fail-readonly',
'backend-fail-synced',
'backend-fail-connect',
'backend-fail-internal',
'backend-fail-contenttype',
- 'backend-fail-batchsize'
+ 'backend-fail-batchsize',
+ 'backend-fail-usable'
+ ),
+
+ 'filejournal-errors' => array(
+ 'filejournal-fail-dbconnect',
+ 'filejournal-fail-dbquery'
),
'lockmanager-errors' => array(
@@ -1379,9 +1417,11 @@ $wgMessageStructure = array(
'lockmanager-fail-deletelock',
'lockmanager-fail-acquirelock',
'lockmanager-fail-openlock',
+ 'lockmanager-fail-acquirelock',
'lockmanager-fail-releaselock',
'lockmanager-fail-db-bucket',
'lockmanager-fail-db-release',
+ 'lockmanager-fail-svr-acquire',
'lockmanager-fail-svr-release'
),
@@ -1484,6 +1524,8 @@ $wgMessageStructure = array(
'sharedupload',
'sharedupload-desc-there',
'sharedupload-desc-here',
+ 'sharedupload-desc-edit',
+ 'sharedupload-desc-create',
'shareddescriptionfollows',
'filepage-nofile',
'filepage-nofile-link',
@@ -1492,6 +1534,7 @@ $wgMessageStructure = array(
'shared-repo',
'shared-repo-name-wikimediacommons',
'filepage.css',
+ 'upload-disallowed-here',
),
'filerevert' => array(
'filerevert',
@@ -1607,6 +1650,7 @@ $wgMessageStructure = array(
'specialpages' => array(
'nbytes',
'ncategories',
+ 'ninterwikis',
'nlinks',
'nmembers',
'nrevisions',
@@ -1627,7 +1671,9 @@ $wgMessageStructure = array(
'uncategorizedtemplates',
'uncategorizedtemplates-summary',
'unusedcategories',
+ 'unusedcategories-summary',
'unusedimages',
+ 'unusedimages-summary',
'popularpages',
'popularpages-summary',
'wantedcategories',
@@ -1651,6 +1697,8 @@ $wgMessageStructure = array(
'mostcategories-summary',
'mostimages',
'mostimages-summary',
+ 'mostinterwikis',
+ 'mostinterwikis-summary',
'mostrevisions',
'mostrevisions-summary',
'prefixindex',
@@ -1718,6 +1766,7 @@ $wgMessageStructure = array(
'alllogstext',
'logempty',
'log-title-wildcard',
+ 'showhideselectedlogentries',
),
'allpages' => array(
'allpages',
@@ -1736,6 +1785,12 @@ $wgMessageStructure = array(
'allpagesprefix',
'allpagesbadtitle',
'allpages-bad-ns',
+ 'allpages-hide-redirects',
+ ),
+ 'cachedspecial' => array(
+ 'cachedspecial-viewing-cached-ttl',
+ 'cachedspecial-viewing-cached-ts',
+ 'cachedspecial-refresh-now',
),
'categories' => array(
'categories',
@@ -1747,11 +1802,13 @@ $wgMessageStructure = array(
),
'deletedcontribs' => array(
'deletedcontributions',
+ 'deletedcontributions-summary',
'deletedcontributions-title',
'sp-deletedcontributions-contribs',
),
'linksearch' => array(
'linksearch',
+ 'linksearch-summary',
'linksearch-pat',
'linksearch-ns',
'linksearch-ok',
@@ -1804,6 +1861,9 @@ $wgMessageStructure = array(
'mailnologin',
'mailnologintext',
'emailuser',
+ 'emailuser-title-target',
+ 'emailuser-title-notarget',
+ 'emailuser-summary',
'emailpage',
'emailpagetext',
'usermailererror',
@@ -1837,6 +1897,7 @@ $wgMessageStructure = array(
),
'watchlist' => array(
'watchlist',
+ 'watchlist-summary',
'mywatchlist',
'watchlistfor2',
'nowatchlist',
@@ -1913,6 +1974,8 @@ $wgMessageStructure = array(
'rollback',
'rollback_short',
'rollbacklink',
+ 'rollbacklinkcount',
+ 'rollbacklinkcount-morethan',
'rollbackfailed',
'cantrollback',
'alreadyrolled',
@@ -1985,6 +2048,7 @@ $wgMessageStructure = array(
),
'undelete' => array(
'undelete',
+ 'undelete-summary',
'undeletepage',
'undeletepagetitle',
'viewdeletedpage',
@@ -2024,6 +2088,7 @@ $wgMessageStructure = array(
'undelete-error-long',
'undelete-show-file-confirm',
'undelete-show-file-submit',
+ 'undelete-revisionrow',
),
'nsform' => array(
'namespace',
@@ -2035,6 +2100,7 @@ $wgMessageStructure = array(
),
'contributions' => array(
'contributions',
+ 'contributions-summary',
'contributions-title',
'mycontris',
'contribsub2',
@@ -2062,6 +2128,7 @@ $wgMessageStructure = array(
'sp-contributions-explain',
'sp-contributions-footer',
'sp-contributions-footer-anon',
+ 'sp-contributions-footer-newbies',
),
'whatlinkshere' => array(
'whatlinkshere',
@@ -2087,6 +2154,7 @@ $wgMessageStructure = array(
'autoblockid',
'block',
'unblock',
+ 'unblock-summary',
'blockip',
'blockip-title',
'blockip-legend',
@@ -2197,6 +2265,7 @@ $wgMessageStructure = array(
'cant-see-hidden-user',
'ipbblocked',
'ipbnounblockself',
+ 'ipb-default-expiry',
),
'developertools' => array(
'lockdb',
@@ -2218,6 +2287,7 @@ $wgMessageStructure = array(
),
'movepage' => array(
'move-page',
+ 'movepage-summary',
'move-page-legend',
'movepagetext',
'movepagetext-noredirectfixer',
@@ -2279,6 +2349,7 @@ $wgMessageStructure = array(
),
'export' => array(
'export',
+ 'export-summary',
'exporttext',
'exportall',
'exportcuronly',
@@ -2325,6 +2396,7 @@ $wgMessageStructure = array(
),
'import' => array(
'import',
+ 'import-summary',
'importinterwiki',
'import-interwiki-text',
'import-interwiki-source',
@@ -2332,6 +2404,7 @@ $wgMessageStructure = array(
'import-interwiki-templates',
'import-interwiki-submit',
'import-interwiki-namespace',
+ 'import-interwiki-rootpage',
'import-upload-filename',
'import-comment',
'importtext',
@@ -2363,6 +2436,9 @@ $wgMessageStructure = array(
'import-error-interwiki',
'import-error-special',
'import-error-invalid',
+ 'import-options-wrong',
+ 'import-rootpage-invalid',
+ 'import-rootpage-nosubpage',
),
'importlog' => array(
'importlogpage',
@@ -2583,19 +2659,41 @@ $wgMessageStructure = array(
'spambot_username',
'spam_reverting',
'spam_blanking',
+ 'spam_deleting',
),
'info' => array(
+ 'pageinfo-header',
'pageinfo-title',
+ 'pageinfo-not-current',
+ 'pageinfo-header-basic',
'pageinfo-header-edits',
- 'pageinfo-header-watchlist',
- 'pageinfo-header-views',
- 'pageinfo-subjectpage',
- 'pageinfo-talkpage',
+ 'pageinfo-header-restrictions',
+ 'pageinfo-header-properties',
+ 'pageinfo-display-title',
+ 'pageinfo-default-sort',
+ 'pageinfo-length',
+ 'pageinfo-article-id',
+ 'pageinfo-robot-policy',
+ 'pageinfo-robot-index',
+ 'pageinfo-robot-noindex',
+ 'pageinfo-views',
'pageinfo-watchers',
+ 'pageinfo-redirects-name',
+ 'pageinfo-redirects-value',
+ 'pageinfo-subpages-name',
+ 'pageinfo-subpages-value',
+ 'pageinfo-firstuser',
+ 'pageinfo-firsttime',
+ 'pageinfo-lastuser',
+ 'pageinfo-lasttime',
'pageinfo-edits',
'pageinfo-authors',
- 'pageinfo-views',
- 'pageinfo-viewsperedit',
+ 'pageinfo-recent-edits',
+ 'pageinfo-recent-authors',
+ 'pageinfo-magic-words',
+ 'pageinfo-hidden-categories',
+ 'pageinfo-templates',
+ 'pageinfo-footer',
),
'skin' => array(
'skinname-standard',
@@ -2649,6 +2747,7 @@ $wgMessageStructure = array(
'file-info-size-pages',
'file-nohires',
'svg-long-desc',
+ 'svg-long-desc-animated',
'show-big-image',
'show-big-image-preview',
'show-big-image-other',
@@ -2658,6 +2757,8 @@ $wgMessageStructure = array(
'file-info-png-looped',
'file-info-png-repeat',
'file-info-png-frames',
+ 'file-no-thumb-animation',
+ 'file-no-thumb-animation-gif',
),
'newfiles' => array(
'newimages',
@@ -3274,6 +3375,7 @@ $wgMessageStructure = array(
'ellipsis',
'percent',
'parentheses',
+ 'brackets',
),
'imgmulti' => array(
'imgmultipageprev',
@@ -3338,6 +3440,7 @@ $wgMessageStructure = array(
'confirm-watch-button',
),
'watchlisteditor' => array(
+ 'editwatchlist-summary',
'watchlistedit-numitems',
'watchlistedit-noitems',
'watchlistedit-normal-title',
@@ -3428,6 +3531,7 @@ $wgMessageStructure = array(
),
'version' => array(
'version',
+ 'version-summary',
'version-extensions',
'version-specialpages',
'version-parserhooks',
@@ -3452,6 +3556,14 @@ $wgMessageStructure = array(
'version-software',
'version-software-product',
'version-software-version',
+ 'version-entrypoints',
+ 'version-entrypoints-header-entrypoint',
+ 'version-entrypoints-header-url',
+ 'version-entrypoints-articlepath',
+ 'version-entrypoints-scriptpath',
+ 'version-entrypoints-index-php',
+ 'version-entrypoints-api-php',
+ 'version-entrypoints-load-php',
),
'filepath' => array(
'filepath',
@@ -3496,6 +3608,7 @@ $wgMessageStructure = array(
),
'special-tags' => array(
'tags',
+ 'tags-summary',
'tag-filter',
'tag-filter-submit',
'tags-title',
@@ -3509,6 +3622,7 @@ $wgMessageStructure = array(
),
'comparepages' => array(
'comparepages',
+ 'comparepages-summary',
'compare-selector',
'compare-page1',
'compare-page2',
@@ -3579,6 +3693,34 @@ $wgMessageStructure = array(
'logentry-newusers-autocreate',
'newuserlog-byemail',
),
+ 'logging-irc' => array(
+ 'revdelete-logentry',
+ 'logdelete-logentry',
+ 'revdelete-content',
+ 'revdelete-summary',
+ 'revdelete-uname',
+ 'revdelete-hid',
+ 'revdelete-unhid',
+ 'revdelete-log-message',
+ 'logdelete-log-message',
+ 'deletedarticle',
+ 'suppressedarticle',
+ 'undeletedarticle',
+ 'patrol-log-line',
+ 'patrol-log-auto',
+ 'patrol-log-diff',
+ '1movedto2',
+ '1movedto2_redir',
+ 'move-redirect-suppressed',
+ // 'newuserlog-byemail',
+ 'newuserlog-create-entry',
+ 'newuserlog-create2-entry',
+ 'newuserlog-autocreate-entry',
+ 'suppressedarticle',
+ 'deletedarticle',
+ // 'uploadedimage',
+ // 'overwroteimage',
+ ),
'feedback' => array(
'feedback-bugornote',
'feedback-subject',
@@ -3594,6 +3736,10 @@ $wgMessageStructure = array(
'feedback-bugcheck',
'feedback-bugnew',
),
+ 'searchsuggestions' => array(
+ 'searchsuggest-search',
+ 'searchsuggest-containing',
+ ),
'apierrors' => array(
'api-error-badaccess-groups',
'api-error-badtoken',
@@ -3605,9 +3751,12 @@ $wgMessageStructure = array(
'api-error-empty-file',
'api-error-emptypage',
'api-error-fetchfileerror',
+ 'api-error-fileexists-forbidden',
+ 'api-error-fileexists-shared-forbidden',
'api-error-file-too-large',
'api-error-filename-tooshort',
'api-error-filetype-banned',
+ 'api-error-filetype-banned-type',
'api-error-filetype-missing',
'api-error-hookaborted',
'api-error-http',
@@ -3632,6 +3781,17 @@ $wgMessageStructure = array(
'api-error-uploaddisabled',
'api-error-verification-error',
),
+ 'duration' => array(
+ 'duration-seconds',
+ 'duration-minutes',
+ 'duration-hours',
+ 'duration-days',
+ 'duration-weeks',
+ 'duration-years',
+ 'duration-decades',
+ 'duration-centuries',
+ 'duration-millennia'
+ ),
);
/** Comments for each block */
@@ -3696,6 +3856,7 @@ XHTML id names.",
'zip' => 'ZipDirectoryReader',
'upload-errors' => '',
'filebackend-errors' => 'File backend',
+ 'filejournal-errors' => 'File journal errors',
'lockmanager-errors' => 'Lock manager',
'uploadstash' => 'Special:UploadStash',
'img-auth' => 'img_auth script messages',
@@ -3866,6 +4027,10 @@ Variants for Chinese language",
'html-forms' => 'HTML forms',
'sqlite' => 'SQLite database support',
'logging' => 'New logging system',
+ 'logging-irc' => 'For IRC, see bug 34508. Do not change',
'feedback' => 'Feedback',
+ 'searchsuggestions' => 'Search suggestions',
'apierrors' => 'API errors',
+ 'duration' => 'Durations',
+ 'cachedspecial' => 'SpecialCachedPage',
);
diff --git a/maintenance/language/rebuildLanguage.php b/maintenance/language/rebuildLanguage.php
index 9b3a4b9d..ad839054 100644
--- a/maintenance/language/rebuildLanguage.php
+++ b/maintenance/language/rebuildLanguage.php
@@ -22,7 +22,7 @@
* @defgroup MaintenanceLanguage MaintenanceLanguage
*/
-require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+require_once( __DIR__ . '/../commandLine.inc' );
require_once( 'languages.inc' );
require_once( 'writeMessagesArray.inc' );
@@ -30,27 +30,28 @@ require_once( 'writeMessagesArray.inc' );
* Rewrite a messages array.
*
* @param $languages
- * @param $code The language code.
+ * @param $code string The language code.
* @param bool $write Write to the messages file?
* @param bool $listUnknown List the unknown messages?
* @param bool $removeUnknown Remove the unknown messages?
* @param bool $removeDupes Remove the duplicated messages?
- * @param $dupeMsgSource The source file intended to remove from the array.
+ * @param $dupeMsgSource string The source file intended to remove from the array.
+ * @param $messagesFolder String: path to a folder to store the MediaWiki messages.
*/
-function rebuildLanguage( $languages, $code, $write, $listUnknown, $removeUnknown, $removeDupes, $dupeMsgSource ) {
+function rebuildLanguage( $languages, $code, $write, $listUnknown, $removeUnknown, $removeDupes, $dupeMsgSource, $messagesFolder ) {
$messages = $languages->getMessages( $code );
$messages = $messages['all'];
if ( $removeDupes ) {
$messages = removeDupes( $messages, $dupeMsgSource );
}
- MessageWriter::writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown );
+ MessageWriter::writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown, $messagesFolder );
}
/**
* Remove duplicates from a message array.
*
- * @param $oldMsgArray The input message array.
- * @param $dupeMsgSource The source file path for duplicates.
+ * @param $oldMsgArray array The input message array.
+ * @param $dupeMsgSource string The source file path for duplicates.
* @return Array $newMsgArray The output message array, with duplicates removed.
*/
function removeDupes( $oldMsgArray, $dupeMsgSource ) {
@@ -85,6 +86,7 @@ Options:
* no-unknown: Do not list the unknown messages.
* remove-unknown: Remove unknown messages.
* remove-duplicates: Remove duplicated messages based on a PHP source file.
+ * messages-folder: An alternative folder with MediaWiki messages.
TEXT;
exit( 1 );
@@ -109,6 +111,7 @@ $wgWriteToFile = !isset( $options['dry-run'] );
$wgListUnknownMessages = !isset( $options['no-unknown'] );
$wgRemoveUnknownMessages = isset( $options['remove-unknown'] );
$wgRemoveDuplicateMessages = isset( $options['remove-duplicates'] );
+$messagesFolder = isset( $options['messages-folder'] ) ? $options['messages-folder'] : false;
# Get language objects
$languages = new languages();
@@ -116,8 +119,8 @@ $languages = new languages();
# Write all the language
if ( $wgCode == 'all' ) {
foreach ( $languages->getLanguages() as $languageCode ) {
- rebuildLanguage( $languages, $languageCode, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages, $wgRemoveDuplicateMessages, $wgDupeMessageSource );
+ rebuildLanguage( $languages, $languageCode, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages, $wgRemoveDuplicateMessages, $wgDupeMessageSource, $messagesFolder );
}
} else {
- rebuildLanguage( $languages, $wgCode, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages, $wgRemoveDuplicateMessages, $wgDupeMessageSource );
+ rebuildLanguage( $languages, $wgCode, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages, $wgRemoveDuplicateMessages, $wgDupeMessageSource, $messagesFolder );
}
diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php
index fb08b7d0..ba503224 100644
--- a/maintenance/language/transstat.php
+++ b/maintenance/language/transstat.php
@@ -28,9 +28,9 @@
*/
$optionsWithArgs = array( 'output' );
-require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+require_once( __DIR__ . '/../commandLine.inc' );
require_once( 'languages.inc' );
-require_once( dirname( __FILE__ ) . '/StatOutputs.php' );
+require_once( __DIR__ . '/StatOutputs.php' );
if ( isset( $options['help'] ) ) {
@@ -102,7 +102,7 @@ foreach ( $wgLanguages->getLanguages() as $code ) {
}
# Calculate the numbers
- $language = $wgContLang->getLanguageName( $code );
+ $language = Language::fetchLanguageName( $code );
$fallback = $wgLanguages->getFallback( $code );
$messages = $wgLanguages->getMessages( $code );
$messagesNumber = count( $messages['translated'] );
@@ -134,5 +134,3 @@ foreach ( $wgLanguages->getLanguages() as $code ) {
# Footer
$output->footer();
-
-
diff --git a/maintenance/language/validate.php b/maintenance/language/validate.php
index 57517644..751e744d 100644
--- a/maintenance/language/validate.php
+++ b/maintenance/language/validate.php
@@ -30,7 +30,7 @@ array_shift( $argv );
define( 'MEDIAWIKI', 1 );
define( 'NOT_REALLY_MEDIAWIKI', 1 );
-$IP = dirname( __FILE__ ) . '/../..';
+$IP = __DIR__ . '/../..';
require_once( "$IP/includes/Defines.php" );
require_once( "$IP/languages/Language.php" );
@@ -58,4 +58,3 @@ function getVars( $filename ) {
unset( $vars['filename'] );
return $vars;
}
-
diff --git a/maintenance/language/writeMessagesArray.inc b/maintenance/language/writeMessagesArray.inc
index 524c2ba6..b2e04c7f 100644
--- a/maintenance/language/writeMessagesArray.inc
+++ b/maintenance/language/writeMessagesArray.inc
@@ -41,16 +41,28 @@ class MessageWriter {
* @param $write Boolean: write to the messages file?
* @param $listUnknown Boolean: list the unknown messages?
* @param $removeUnknown Boolean: whether to remove unkown messages
+ * @param $messagesFolder String: path to a folder to store the MediaWiki messages. Defaults to the current install.
*/
- public static function writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown ) {
+ public static function writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown, $messagesFolder = false ) {
# Rewrite the messages array
$messages = self::writeMessagesArray( $messages, $code == 'en', false, $removeUnknown );
$messagesText = $messages[0];
$sortedMessages = $messages[1];
# Write to the file
- $filename = Language::getMessagesFileName( $code );
- $contents = file_get_contents( $filename );
+ if ( $messagesFolder )
+ $filename = Language::getFileName( "$messagesFolder/Messages", $code );
+ else
+ $filename = Language::getMessagesFileName( $code );
+
+ if ( file_exists( $filename ) )
+ $contents = file_get_contents( $filename );
+ else
+ $contents = '<?php
+$messages = array(
+);
+';
+
if( strpos( $contents, '$messages' ) !== false ) {
$contents = explode( '$messages', $contents );
if( $messagesText == '$messages' . $contents[1] ) {
@@ -93,7 +105,7 @@ class MessageWriter {
*/
public static function writeMessagesArray( $messages, $ignoredComments = false, $prefix = false, $removeUnknown = false ) {
# Load messages
- $dir = $prefix ? $prefix : dirname( __FILE__ );
+ $dir = $prefix ? $prefix : __DIR__;
require( $dir . '/messages.inc' );
self::$messageStructure = $wgMessageStructure;
@@ -156,6 +168,7 @@ class MessageWriter {
* @param $messages Array: key of messages.
* @param $ignored Array: list of ingored message keys.
* @param $optional Array: list of optional message keys.
+ * @return array
*/
public static function makeComments( $messages, $ignored, $optional ) {
# Comment collector
@@ -181,7 +194,7 @@ class MessageWriter {
* @param $messageComments Array: optional comments for messages in this block.
* @param $prefix String: prefix for every line, for indenting purposes.
*
- * @return The block, formatted in PHP.
+ * @return string The block, formatted in PHP.
*/
public static function writeMessagesBlock( $blockComment, $messages,
$messageComments = array(), $prefix = '' ) {
diff --git a/maintenance/locking/LockServerDaemon.php b/maintenance/locking/LockServerDaemon.php
index 1a4a928e..689c9309 100644
--- a/maintenance/locking/LockServerDaemon.php
+++ b/maintenance/locking/LockServerDaemon.php
@@ -1,12 +1,28 @@
<?php
/**
+ * Simple lock server daemon that accepts lock/unlock requests.
+ *
+ * This code should not require MediaWiki setup or PHP files.
+ *
+ * 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 LockManager Maintenance
*/
-/**
- * This code should not require MediaWiki setup or PHP files.
- */
if ( php_sapi_name() !== 'cli' ) {
die( "This is not a valid entry point.\n" );
}
@@ -223,7 +239,7 @@ class LockServerDaemon {
list( $session, $key, $command, $type, $values ) = $m;
if ( sha1( $session . $command . $type . $values . $this->authKey ) !== $key ) {
return 'BAD_KEY';
- } elseif ( strlen( $session ) !== 31 ) {
+ } elseif ( strlen( $session ) !== 32 ) {
return 'BAD_SESSION';
}
$values = explode( '|', $values );
@@ -256,9 +272,9 @@ class LockServerDaemon {
/**
* Remove a socket's corresponding session from tracking and
* store it in the dead session tracking if it still has locks.
- *
+ *
* @param $socket resource
- * @return book
+ * @return bool
*/
protected function recordDeadSocket( $socket ) {
$session = array_search( $socket, $this->sessions );
@@ -293,7 +309,7 @@ class LockServerDaemon {
/**
* Get the current timestamp and memory usage
- *
+ *
* @return string
*/
protected function stat() {
@@ -382,7 +398,7 @@ class SocketArray {
/**
* @param $sock resource
- * @return string|false
+ * @return string|bool
*/
public function readRcvBuffer( $sock ) {
$key = array_search( $sock, $this->clients );
@@ -463,10 +479,10 @@ class LockHolder {
/**
* @param $session string
- * @return bool
+ * @return bool
*/
public function sessionHasLocks( $session ) {
- return isset( $this->sessionIndexSh[$session] )
+ return isset( $this->sessionIndexSh[$session] )
|| isset( $this->sessionIndexEx[$session] );
}
diff --git a/maintenance/mcc.php b/maintenance/mcc.php
index 02445278..e07e62db 100644
--- a/maintenance/mcc.php
+++ b/maintenance/mcc.php
@@ -23,7 +23,7 @@
*/
/** */
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
$mcc = new MWMemcached( array( 'persistent' => true/*, 'debug' => true*/ ) );
$mcc->set_servers( $wgMemCachedServers );
diff --git a/maintenance/mctest.php b/maintenance/mctest.php
index 359cd248..691b832b 100644
--- a/maintenance/mctest.php
+++ b/maintenance/mctest.php
@@ -1,7 +1,7 @@
<?php
/**
- * This script makes several 'set', 'incr' and 'get' requests on every
- * memcached server and shows a report.
+ * Makes several 'set', 'incr' and 'get' requests on every memcached
+ * server and shows a report.
*
* 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
@@ -18,11 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that makes several 'set', 'incr' and 'get' requests
+ * on every memcached server and shows a report.
+ *
+ * @ingroup Maintenance
+ */
class mcTest extends Maintenance {
public function __construct() {
parent::__construct();
@@ -33,7 +40,7 @@ class mcTest extends Maintenance {
}
public function execute() {
- global $wgMemCachedServers;
+ global $wgMemCachedServers, $wgMemCachedTimeout;
$iterations = $this->getOption( 'i', 100 );
if ( $this->hasArg() ) {
@@ -42,7 +49,10 @@ class mcTest extends Maintenance {
foreach ( $wgMemCachedServers as $server ) {
$this->output( $server . " ", $server );
- $mcc = new MemCachedClientforWiki( array( 'persistant' => true ) );
+ $mcc = new MemCachedClientforWiki( array(
+ 'persistant' => true,
+ 'timeout' => $wgMemCachedTimeout
+ ) );
$mcc->set_servers( array( $server ) );
$set = 0;
$incr = 0;
diff --git a/maintenance/mergeMessageFileList.php b/maintenance/mergeMessageFileList.php
index b5a911aa..cea64333 100644
--- a/maintenance/mergeMessageFileList.php
+++ b/maintenance/mergeMessageFileList.php
@@ -25,64 +25,99 @@
# Start from scratch
define( 'MW_NO_EXTENSION_MESSAGES', 1 );
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+$maintClass = 'MergeMessageFileList';
+$mmfl = false;
+/**
+ * Maintenance script that merges $wgExtensionMessagesFiles from various
+ * extensions to produce a single array containing all message files.
+ *
+ * @ingroup Maintenance
+ */
class MergeMessageFileList extends Maintenance {
function __construct() {
parent::__construct();
$this->addOption( 'list-file', 'A file containing a list of extension setup files, one per line.', true, 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 ' .
'single array containing all message files.';
}
public function execute() {
+ global $mmfl;
+
+ # 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.' );
}
$mmfl = array( 'setupFiles' => array_map( 'trim', $lines ) );
- if ( $this->hasOption( 'output' ) ) {
- $mmfl['output'] = $this->getOption( 'output' );
- }
- global $IP, $wgExtensionMessagesFiles;
- foreach ( $mmfl['setupFiles'] as $fileName ) {
- if ( strval( $fileName ) === '' ) {
- continue;
+ # 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 ) {
+ if ( $extname == '.' || $extname == '..' || !is_dir( "$extdir/$extname" ) ) {
+ continue;
+ }
+ $extfile = "{$extdir}/{$extname}/{$extname}.php";
+ if ( file_exists( $extfile ) ) {
+ $mmfl['setupFiles'][] = $extfile;
+ } else {
+ $hasError = true;
+ $this->error( "Extension {$extname} in {$extdir} lacks expected {$extname}.php" );
+ }
}
- $fileName = str_replace( '$IP', $IP, $fileName );
- fwrite( STDERR, "Loading data from $fileName\n" );
- include_once( $fileName );
}
- fwrite( STDERR, "\n" );
- $s =
- "<" . "?php\n" .
- "## This file is generated by mergeMessageFileList.php. Do not edit it directly.\n\n" .
- "if ( defined( 'MW_NO_EXTENSION_MESSAGES' ) ) return;\n\n" .
- '$wgExtensionMessagesFiles = ' . var_export( $wgExtensionMessagesFiles, true ) . ";\n";
- $dirs = array(
- $IP,
- dirname( dirname( __FILE__ ) ),
- realpath( $IP )
- );
-
- foreach ( $dirs as $dir ) {
- $s = preg_replace(
- "/'" . preg_quote( $dir, '/' ) . "([^']*)'/",
- '"$IP\1"',
- $s );
+ if ( $hasError ) {
+ $this->error( "Some files are missing (see above). Giving up.", 1 );
}
- if ( isset( $mmfl['output'] ) ) {
- file_put_contents( $mmfl['output'], $s );
- } else {
- echo $s;
+ if ( $this->hasOption( 'output' ) ) {
+ $mmfl['output'] = $this->getOption( 'output' );
}
}
}
-$maintClass = 'MergeMessageFileList';
require_once( RUN_MAINTENANCE_IF_MAIN );
+
+foreach ( $mmfl['setupFiles'] as $fileName ) {
+ if ( strval( $fileName ) === '' ) {
+ continue;
+ }
+ $fileName = str_replace( '$IP', $IP, $fileName );
+ fwrite( STDERR, "Loading data from $fileName\n" );
+ include_once( $fileName );
+}
+fwrite( STDERR, "\n" );
+$s =
+ "<" . "?php\n" .
+ "## This file is generated by mergeMessageFileList.php. Do not edit it directly.\n\n" .
+ "if ( defined( 'MW_NO_EXTENSION_MESSAGES' ) ) return;\n\n" .
+ '$wgExtensionMessagesFiles = ' . var_export( $wgExtensionMessagesFiles, true ) . ";\n\n";
+
+$dirs = array(
+ $IP,
+ dirname( __DIR__ ),
+ realpath( $IP )
+);
+
+foreach ( $dirs as $dir ) {
+ $s = preg_replace(
+ "/'" . preg_quote( $dir, '/' ) . "([^']*)'/",
+ '"$IP\1"',
+ $s );
+}
+
+if ( isset( $mmfl['output'] ) ) {
+ file_put_contents( $mmfl['output'], $s );
+} else {
+ echo $s;
+}
+
diff --git a/maintenance/migrateUserGroup.php b/maintenance/migrateUserGroup.php
index 771ed947..496af723 100644
--- a/maintenance/migrateUserGroup.php
+++ b/maintenance/migrateUserGroup.php
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that re-assigns users from an old group to a new one.
+ *
+ * @ingroup Maintenance
+ */
class MigrateUserGroup extends Maintenance {
public function __construct() {
parent::__construct();
@@ -50,14 +56,22 @@ class MigrateUserGroup extends Maintenance {
// Migrate users over in batches...
while ( $blockEnd <= $end ) {
$this->output( "Doing users $blockStart to $blockEnd\n" );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$dbw->update( 'user_groups',
array( 'ug_group' => $newGroup ),
array( 'ug_group' => $oldGroup,
- "ug_user BETWEEN $blockStart AND $blockEnd" )
+ "ug_user BETWEEN $blockStart AND $blockEnd" ),
+ __METHOD__,
+ array( 'IGNORE' )
+ );
+ $count += $dbw->affectedRows();
+ $dbw->delete( 'user_groups',
+ array( 'ug_group' => $oldGroup,
+ "ug_user BETWEEN $blockStart AND $blockEnd" ),
+ __METHOD__
);
$count += $dbw->affectedRows();
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$blockStart += $this->mBatchSize;
$blockEnd += $this->mBatchSize;
wfWaitForSlaves();
diff --git a/maintenance/minify.php b/maintenance/minify.php
index e1fd862d..9f5a909d 100644
--- a/maintenance/minify.php
+++ b/maintenance/minify.php
@@ -21,8 +21,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that minifies a file or set of files.
+ *
+ * @ingroup Maintenance
+ */
class MinifyScript extends Maintenance {
var $outDir;
diff --git a/maintenance/moveBatch.php b/maintenance/moveBatch.php
index 6ecc775e..7d15959c 100644
--- a/maintenance/moveBatch.php
+++ b/maintenance/moveBatch.php
@@ -1,6 +1,6 @@
<?php
/**
- * Maintenance script to move a batch of pages
+ * Move a batch of pages.
*
* 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
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Tim Starling
*
@@ -33,8 +34,13 @@
* e.g. immobile_namespace for namespaces which can't be moved
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to move a batch of pages.
+ *
+ * @ingroup Maintenance
+ */
class MoveBatch extends Maintenance {
public function __construct() {
parent::__construct();
@@ -92,13 +98,13 @@ class MoveBatch extends Maintenance {
$this->output( $source->getPrefixedText() . ' --> ' . $dest->getPrefixedText() );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$err = $source->moveTo( $dest, false, $reason );
if ( $err !== true ) {
$msg = array_shift( $err[0] );
- $this->output( "\nFAILED: " . wfMsg( $msg, $err[0] ) );
+ $this->output( "\nFAILED: " . wfMessage( $msg, $err[0] )->text() );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$this->output( "\n" );
if ( $interval ) {
diff --git a/maintenance/mssql/tables.sql b/maintenance/mssql/tables.sql
index 8c4d5008..a0c3d17b 100644
--- a/maintenance/mssql/tables.sql
+++ b/maintenance/mssql/tables.sql
@@ -396,6 +396,7 @@ CREATE TABLE /*$wgDBprefix*/ipblocks (
ipb_deleted BIT NOT NULL DEFAULT 0,
ipb_block_email BIT NOT NULL DEFAULT 0,
ipb_allow_usertalk BIT NOT NULL DEFAULT 0,
+ ipb_parent_block_id INT DEFAULT NULL,
);
-- Unique index to support "user already blocked" messages
-- Any new options which prevent collisions should be included
diff --git a/maintenance/mwdoc-filter.php b/maintenance/mwdoc-filter.php
new file mode 100644
index 00000000..ab05a3e2
--- /dev/null
+++ b/maintenance/mwdoc-filter.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Doxygen filter to show correct member variable types in documentation.
+ *
+ * Should be filled in doxygen INPUT_FILTER as "php mwdoc-filter.php"
+ *
+ * Original source code by Goran Rakic
+ * http://blog.goranrakic.com/
+ * http://stackoverflow.com/questions/4325224
+ *
+ * @file
+ */
+
+$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);
+
+echo $source;
diff --git a/maintenance/mwdocgen.php b/maintenance/mwdocgen.php
index 0c3b262e..583249a5 100644
--- a/maintenance/mwdocgen.php
+++ b/maintenance/mwdocgen.php
@@ -49,7 +49,7 @@ if ( php_sapi_name() != 'cli' ) {
}
/** Figure out the base directory for MediaWiki location */
-$mwPath = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
+$mwPath = dirname( __DIR__ ) . DIRECTORY_SEPARATOR;
/** doxygen binary script */
$doxygenBin = 'doxygen';
@@ -57,6 +57,9 @@ $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";
+
/** svnstat command, used to get the version of each file */
$svnstat = $mwPath . 'bin/svnstat';
@@ -77,7 +80,9 @@ $mwExcludePaths = array(
/** Variable to get user input */
$input = '';
-$exclude_patterns = '';
+$excludePatterns = '';
+/** Whether to generates man pages: */
+$doxyGenerateMan = false;
#
# Functions
@@ -114,31 +119,7 @@ function getSvnRevision( $dir ) {
$content = file( $entries );
- // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
- if ( preg_match( '/^<\?xml/', $content[0] ) ) {
- // subversion is release <= 1.3
- if ( !function_exists( 'simplexml_load_file' ) ) {
- // We could fall back to expat... YUCK
- return false;
- }
-
- $xml = simplexml_load_file( $entries );
-
- if ( $xml ) {
- foreach ( $xml->entry as $entry ) {
- if ( $xml->entry[0]['name'] == '' ) {
- // The directory entry should always have a revision marker.
- if ( $entry['revision'] ) {
- return intval( $entry['revision'] );
- }
- }
- }
- }
- return false;
- } else {
- // subversion is release 1.4
- return intval( $content[3] );
- }
+ return intval( $content[3] );
}
/**
@@ -150,16 +131,15 @@ function getSvnRevision( $dir ) {
* @param $svnstat String: path to the svnstat file
* @param $input String: Path to analyze.
* @param $exclude String: Additionals path regex to exclude
- * @param $exclude_patterns 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
*/
-function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath, $currentVersion, $svnstat, $input, $exclude, $exclude_patterns ) {
-
- global $wgDoxyGenerateMan;
+function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath, $currentVersion, $svnstat, $input, $exclude, $excludePatterns, $doxyGenerateMan ) {
+ global $doxygenInputFilter;
$template = file_get_contents( $doxygenTemplate );
-
// Replace template placeholders by correct values.
$replacements = array(
'{{OUTPUT_DIRECTORY}}' => $outputDirectory,
@@ -168,9 +148,10 @@ function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath,
'{{SVNSTAT}}' => $svnstat,
'{{INPUT}}' => $input,
'{{EXCLUDE}}' => $exclude,
- '{{EXCLUDE_PATTERNS}}' => $exclude_patterns,
+ '{{EXCLUDE_PATTERNS}}' => $excludePatterns,
'{{HAVE_DOT}}' => `which dot` ? 'YES' : 'NO',
- '{{GENERATE_MAN}}' => $wgDoxyGenerateMan ? 'YES' : 'NO',
+ '{{GENERATE_MAN}}' => $doxyGenerateMan ? 'YES' : 'NO',
+ '{{INPUT_FILTER}}' => $doxygenInputFilter,
);
$tmpCfg = str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
$tmpFileName = tempnam( wfTempDir(), 'mwdocgen-' );
@@ -208,7 +189,7 @@ if ( is_array( $argv ) ) {
}
break;
case '--generate-man':
- $wgDoxyGenerateMan = true;
+ $doxyGenerateMan = true;
break;
case '--help':
print <<<END
@@ -271,9 +252,10 @@ case 5:
$file = readaline( "Enter file name $mwPath" );
}
$input = $mwPath . $file;
+ break;
case 6:
$input = $mwPath;
- $exclude_patterns = 'extensions';
+ $excludePatterns = 'extensions';
}
$versionNumber = getSvnRevision( $input );
@@ -289,7 +271,7 @@ if ( $versionNumber === false ) { # Not using subversion ?
$excludedPaths = $mwPath . join( " $mwPath", $mwExcludePaths );
print "EXCLUDE: $excludedPaths\n\n";
-$generatedConf = generateConfigFile( $doxygenTemplate, $doxyOutput, $mwPath, $version, $svnstat, $input, $excludedPaths, $exclude_patterns );
+$generatedConf = generateConfigFile( $doxygenTemplate, $doxyOutput, $mwPath, $version, $svnstat, $input, $excludedPaths, $excludePatterns, $doxyGenerateMan );
$command = $doxygenBin . ' ' . $generatedConf;
echo <<<TEXT
diff --git a/maintenance/namespaceDupes.php b/maintenance/namespaceDupes.php
index 0a5fec33..4197a355 100644
--- a/maintenance/namespaceDupes.php
+++ b/maintenance/namespaceDupes.php
@@ -2,7 +2,7 @@
/**
* Check for articles to fix after adding/deleting namespaces
*
- * Copyright (C) 2005-2007 Brion Vibber <brion@pobox.com>
+ * Copyright © 2005-2007 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -20,11 +20,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that checks for articles to fix after
+ * adding/deleting namespaces.
+ *
+ * @ingroup Maintenance
+ */
class NamespaceConflictChecker extends Maintenance {
/**
@@ -257,7 +264,7 @@ class NamespaceConflictChecker extends Maintenance {
$newTitle->getDBkey(),
$newTitle->getPrefixedText() ) );
- $id = $newTitle->getArticleId();
+ $id = $newTitle->getArticleID();
if ( $id ) {
$this->output( "... *** cannot resolve automatically; page exists with ID $id ***\n" );
return false;
@@ -285,7 +292,7 @@ class NamespaceConflictChecker extends Maintenance {
$this->output( "... !!! invalid title\n" );
return false;
}
- $id = $title->getArticleId();
+ $id = $title->getArticleID();
if ( $id ) {
$this->output( "... *** page exists with ID $id ***\n" );
} else {
diff --git a/maintenance/nextJobDB.php b/maintenance/nextJobDB.php
index 67aa3088..e66e981b 100644
--- a/maintenance/nextJobDB.php
+++ b/maintenance/nextJobDB.php
@@ -17,12 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @todo Make this work on PostgreSQL and maybe other database servers
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that picks a database that has pending jobs.
+ *
+ * @ingroup Maintenance
+ */
class nextJobDB extends Maintenance {
public function __construct() {
parent::__construct();
@@ -94,11 +100,12 @@ class nextJobDB extends Maintenance {
$lb = wfGetLB( $dbName );
$db = $lb->getConnection( DB_MASTER, array(), $dbName );
if ( $type === false ) {
- $conds = array();
+ $conds = Job::defaultQueueConditions( );
} else {
$conds = array( 'job_cmd' => $type );
}
+
$exists = (bool) $db->selectField( 'job', '1', $conds, __METHOD__ );
$lb->reuseConnection( $db );
return $exists;
diff --git a/maintenance/nukeNS.php b/maintenance/nukeNS.php
index 57417508..c471a441 100644
--- a/maintenance/nukeNS.php
+++ b/maintenance/nukeNS.php
@@ -1,5 +1,4 @@
<?php
-
/**
* Remove pages with only 1 revision from the MediaWiki namespace, without
* flooding recent changes, delete logs, etc.
@@ -28,13 +27,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Steve Sanbeg
* based on nukePage by Rob Church
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that removes pages with only one revision from the
+ * MediaWiki namespace.
+ *
+ * @ingroup Maintenance
+ */
class NukeNS extends Maintenance {
public function __construct() {
parent::__construct();
@@ -49,7 +55,7 @@ class NukeNS extends Maintenance {
$delete = $this->getOption( 'delete', false );
$all = $this->getOption( 'all', false );
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_pag = $dbw->tableName( 'page' );
$tbl_rev = $dbw->tableName( 'revision' );
@@ -80,7 +86,7 @@ class NukeNS extends Maintenance {
// I already have the id & revs
if ( $delete ) {
$dbw->query( "DELETE FROM $tbl_pag WHERE page_id = $id" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
// Delete revisions as appropriate
$child = $this->runChild( 'NukePage', 'nukePage.php' );
$child->deleteRevisions( $revs );
@@ -91,7 +97,7 @@ class NukeNS extends Maintenance {
$this->output( "skip: " . $title->getPrefixedText() . "\n" );
}
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
if ( $n_deleted > 0 ) {
# update statistics - better to decrement existing count, or just count
diff --git a/maintenance/nukePage.php b/maintenance/nukePage.php
index c818e73a..89dffe0c 100644
--- a/maintenance/nukePage.php
+++ b/maintenance/nukePage.php
@@ -18,12 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that erases a page record from the database.
+ *
+ * @ingroup Maintenance
+ */
class NukePage extends Maintenance {
public function __construct() {
parent::__construct();
@@ -38,7 +44,7 @@ class NukePage extends Maintenance {
$delete = $this->getOption( 'delete', false );
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_pag = $dbw->tableName( 'page' );
$tbl_rec = $dbw->tableName( 'recentchanges' );
@@ -73,7 +79,7 @@ class NukePage extends Maintenance {
$this->output( "done.\n" );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
# Delete revisions as appropriate
if ( $delete && $count ) {
@@ -93,20 +99,20 @@ class NukePage extends Maintenance {
}
} else {
$this->output( "not found in database.\n" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
}
public function deleteRevisions( $ids ) {
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_rev = $dbw->tableName( 'revision' );
$set = implode( ', ', $ids );
$dbw->query( "DELETE FROM $tbl_rev WHERE rev_id IN ( $set )" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
}
diff --git a/maintenance/oracle/alterSharedConstraints.php b/maintenance/oracle/alterSharedConstraints.php
index aa207821..e222314d 100644
--- a/maintenance/oracle/alterSharedConstraints.php
+++ b/maintenance/oracle/alterSharedConstraints.php
@@ -26,7 +26,7 @@
* i.e.: GRANT REFERENCES (user_id) ON mwuser TO hubclient;
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class AlterSharedConstraints extends Maintenance {
public function __construct() {
diff --git a/maintenance/oracle/archives/patch-ipblocks_i05_index.sql b/maintenance/oracle/archives/patch-ipblocks_i05_index.sql
new file mode 100644
index 00000000..14275383
--- /dev/null
+++ b/maintenance/oracle/archives/patch-ipblocks_i05_index.sql
@@ -0,0 +1,4 @@
+define mw_prefix='{$wgDBprefix}';
+
+CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id);
+
diff --git a/maintenance/oracle/archives/patch-revision_i05_index.sql b/maintenance/oracle/archives/patch-revision_i05_index.sql
new file mode 100644
index 00000000..929c7b31
--- /dev/null
+++ b/maintenance/oracle/archives/patch-revision_i05_index.sql
@@ -0,0 +1,4 @@
+define mw_prefix='{$wgDBprefix}';
+
+CREATE INDEX &mw_prefix.revision_i05 ON &mw_prefix.revision (rev_page,rev_user,rev_timestamp);
+
diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql
index 8c0ca30e..26600eba 100644
--- a/maintenance/oracle/tables.sql
+++ b/maintenance/oracle/tables.sql
@@ -39,7 +39,7 @@ CREATE INDEX &mw_prefix.user_groups_i01 ON &mw_prefix.user_groups (ug_group);
CREATE TABLE &mw_prefix.user_former_groups (
ufg_user NUMBER DEFAULT 0 NOT NULL,
- ufg_group VARCHAR2(32) NOT NULL
+ ufg_group VARCHAR2(16) NOT NULL
);
ALTER TABLE &mw_prefix.user_former_groups ADD CONSTRAINT &mw_prefix.user_former_groups_fk1 FOREIGN KEY (ufg_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
CREATE UNIQUE INDEX &mw_prefix.user_former_groups_u01 ON &mw_prefix.user_former_groups (ufg_user,ufg_group);
@@ -116,6 +116,7 @@ CREATE INDEX &mw_prefix.revision_i01 ON &mw_prefix.revision (rev_timestamp);
CREATE INDEX &mw_prefix.revision_i02 ON &mw_prefix.revision (rev_page,rev_timestamp);
CREATE INDEX &mw_prefix.revision_i03 ON &mw_prefix.revision (rev_user,rev_timestamp);
CREATE INDEX &mw_prefix.revision_i04 ON &mw_prefix.revision (rev_user_text,rev_timestamp);
+CREATE INDEX &mw_prefix.revision_i05 ON &mw_prefix.revision (rev_page,rev_user,rev_timestamp);
CREATE SEQUENCE text_old_id_seq;
CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text'
@@ -272,7 +273,8 @@ CREATE TABLE &mw_prefix.ipblocks (
ipb_range_end VARCHAR2(255),
ipb_deleted CHAR(1) DEFAULT '0' NOT NULL,
ipb_block_email CHAR(1) DEFAULT '0' NOT NULL,
- ipb_allow_usertalk CHAR(1) DEFAULT '0' NOT NULL
+ ipb_allow_usertalk CHAR(1) DEFAULT '0' NOT NULL,
+ ipb_parent_block_id NUMBER DEFAULT NULL
);
ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_pk PRIMARY KEY (ipb_id);
ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk1 FOREIGN KEY (ipb_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
@@ -282,6 +284,7 @@ CREATE INDEX &mw_prefix.ipblocks_i01 ON &mw_prefix.ipblocks (ipb_user);
CREATE INDEX &mw_prefix.ipblocks_i02 ON &mw_prefix.ipblocks (ipb_range_start, ipb_range_end);
CREATE INDEX &mw_prefix.ipblocks_i03 ON &mw_prefix.ipblocks (ipb_timestamp);
CREATE INDEX &mw_prefix.ipblocks_i04 ON &mw_prefix.ipblocks (ipb_expiry);
+CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id);
CREATE TABLE &mw_prefix.image (
img_name VARCHAR2(255) NOT NULL,
@@ -664,13 +667,6 @@ CREATE TABLE &mw_prefix.module_deps (
);
CREATE UNIQUE INDEX &mw_prefix.module_deps_u01 ON &mw_prefix.module_deps (md_module, md_skin);
-CREATE TABLE &mw_prefix.config (
- cf_name VARCHAR2(255) NOT NULL,
- cf_value blob NOT NULL
-);
-ALTER TABLE &mw_prefix.config ADD CONSTRAINT &mw_prefix.config_pk PRIMARY KEY (cf_name);
--- leaving index out for now ...
-
-- do not prefix this table as it breaks parserTests
CREATE TABLE wiki_field_info_full (
table_name VARCHAR2(35) NOT NULL,
diff --git a/maintenance/orphans.php b/maintenance/orphans.php
index faaadd37..78f98f5a 100644
--- a/maintenance/orphans.php
+++ b/maintenance/orphans.php
@@ -1,11 +1,11 @@
<?php
/**
- * Look for 'orphan' revisions hooked to pages which don't exist
- * And 'childless' pages with no revisions.
+ * Look for 'orphan' revisions hooked to pages which don't exist and
+ * 'childless' pages with no revisions.
* Then, kill the poor widows and orphans.
* Man this is depressing.
*
- * Copyright (C) 2005 Brion Vibber <brion@pobox.com>
+ * Copyright © 2005 Brion Vibber <brion@pobox.com>
* http://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
@@ -23,17 +23,24 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @author <brion@pobox.com>
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that looks for 'orphan' revisions hooked to pages which
+ * don't exist and 'childless' pages with no revisions.
+ *
+ * @ingroup Maintenance
+ */
class Orphans extends Maintenance {
public function __construct() {
parent::__construct();
$this->mDescription = "Look for 'orphan' revisions hooked to pages which don't exist\n" .
- "And 'childless' pages with no revisions\n" .
+ "and 'childless' pages with no revisions\n" .
"Then, kill the poor widows and orphans\n" .
"Man this is depressing";
$this->addOption( 'fix', 'Actually fix broken entries' );
diff --git a/maintenance/parse.php b/maintenance/parse.php
index 876f28e9..b0ab6244 100644
--- a/maintenance/parse.php
+++ b/maintenance/parse.php
@@ -1,6 +1,7 @@
<?php
/**
- * CLI script to easily parse some wikitext.
+ * Parse some wikitext.
+ *
* Wikitext can be given by stdin or using a file. The wikitext will be parsed
* using 'CLIParser' as a title. This can be overriden with --title option.
*
@@ -27,12 +28,34 @@
* </p>$
* @endcode
*
+ * 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 Antoine Musso <hashar at free dot fr>
* @license GNU General Public License 2.0 or later
*/
-require_once( dirname(__FILE__) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Maintenance script to parse some wikitext.
+ *
+ * @ingroup Maintenance
+ */
class CLIParser extends Maintenance {
protected $parser;
@@ -66,7 +89,8 @@ class CLIParser extends Maintenance {
$input_file = $this->getArg( 0, $php_stdin );
if( $input_file === $php_stdin ) {
- $this->error( basename(__FILE__) .": warning: reading wikitext from STDIN\n" );
+ $ctrl = wfIsWindows() ? 'CTRL+Z' : 'CTRL+D';
+ $this->error( basename(__FILE__) .": warning: reading wikitext from STDIN. Press $ctrl to parse.\n" );
}
return file_get_contents( $input_file );
diff --git a/maintenance/patchSql.php b/maintenance/patchSql.php
index 1f96d62c..1f393556 100644
--- a/maintenance/patchSql.php
+++ b/maintenance/patchSql.php
@@ -18,11 +18,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that manually runs an SQL patch outside of the general updaters.
+ *
+ * @ingroup Maintenance
+ */
class PatchSql extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/populateCategory.php b/maintenance/populateCategory.php
index 0b45493e..ae54d698 100644
--- a/maintenance/populateCategory.php
+++ b/maintenance/populateCategory.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to populate category table.
+ * Populate the category table.
*
* 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
@@ -22,9 +22,13 @@
* @author Simetrical
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Mainteance script to populate the category table.
+ *
+ * @ingroup Maintenance
+ */
class PopulateCategory extends Maintenance {
const REPORTING_INTERVAL = 1000;
diff --git a/maintenance/populateImageSha1.php b/maintenance/populateImageSha1.php
index 4cd2747c..37429a34 100644
--- a/maintenance/populateImageSha1.php
+++ b/maintenance/populateImageSha1.php
@@ -17,15 +17,22 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to populate the img_sha1 field.
+ *
+ * @ingroup Maintenance
+ */
class PopulateImageSha1 extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
$this->mDescription = "Populate the img_sha1 field";
+ $this->addOption( 'force', "Recalculate sha1 for rows that already have a value" );
$this->addOption( 'method', "Use 'pipe' to pipe to mysql command line,\n" .
"\t\tdefault uses Database class", false, true );
$this->addOption( 'file', 'Fix for a specific file, without File: namespace prefixed', false, true );
@@ -49,11 +56,13 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
public function doDBUpdates() {
$method = $this->getOption( 'method', 'normal' );
- $file = $this->getOption( 'file' );
+ $file = $this->getOption( 'file', '' );
+ $force = $this->getOption( 'force' );
+ $isRegen = ( $force || $file != '' ); // forced recalculation?
$t = -microtime( true );
$dbw = wfGetDB( DB_MASTER );
- if ( $file ) {
+ if ( $file != '' ) {
$res = $dbw->select(
'image',
array( 'img_name' ),
@@ -66,15 +75,24 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
}
$this->output( "Populating img_sha1 field for specified files\n" );
} else {
- $res = $dbw->select( 'image',
- array( 'img_name' ), array( 'img_sha1' => '' ), __METHOD__ );
- $this->output( "Populating img_sha1 field\n" );
+ if ( $force ) {
+ $conds = array();
+ $this->output( "Populating and recalculating img_sha1 field\n" );
+ } else {
+ $conds = array( 'img_sha1' => '' );
+ $this->output( "Populating img_sha1 field\n" );
+ }
+ $res = $dbw->select( 'image', array( 'img_name' ), $conds, __METHOD__ );
}
$imageTable = $dbw->tableName( 'image' );
+ $oldImageTable = $dbw->tableName( 'oldimage' );
if ( $method == 'pipe' ) {
- // @todo FIXME: Kill this and replace with a second unbuffered DB connection.
+ // Opening a pipe allows the SHA-1 operation to be done in parallel
+ // with the database write operation, because the writes are queued
+ // in the pipe buffer. This can improve performance by up to a
+ // factor of 2.
global $wgDBuser, $wgDBserver, $wgDBpassword, $wgDBname;
$cmd = 'mysql -u' . wfEscapeShellArg( $wgDBuser ) .
' -h' . wfEscapeShellArg( $wgDBserver ) .
@@ -87,21 +105,49 @@ class PopulateImageSha1 extends LoggedUpdateMaintenance {
$i = 0;
foreach ( $res as $row ) {
if ( $i % $this->mBatchSize == 0 ) {
- $this->output( sprintf( "Done %d of %d, %5.3f%% \r", $i, $numRows, $i / $numRows * 100 ) );
+ $this->output( sprintf(
+ "Done %d of %d, %5.3f%% \r", $i, $numRows, $i / $numRows * 100 ) );
wfWaitForSlaves();
}
$file = wfLocalFile( $row->img_name );
if ( !$file ) {
continue;
}
+ // Upgrade the current file version...
$sha1 = $file->getRepo()->getFileSha1( $file->getPath() );
- if ( strval( $sha1 ) !== '' ) {
- $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) .
- " WHERE img_name=" . $dbw->addQuotes( $row->img_name );
- if ( $method == 'pipe' ) {
- fwrite( $pipe, "$sql;\n" );
+ if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
+ if ( $isRegen && $file->getSha1() !== $sha1 ) {
+ // The population was probably done already. If the old SHA1
+ // does not match, then both fix the SHA1 and the metadata.
+ $file->upgradeRow();
} else {
- $dbw->query( $sql, __METHOD__ );
+ $sql = "UPDATE $imageTable SET img_sha1=" . $dbw->addQuotes( $sha1 ) .
+ " WHERE img_name=" . $dbw->addQuotes( $file->getName() );
+ if ( $method == 'pipe' ) {
+ fwrite( $pipe, "$sql;\n" );
+ } else {
+ $dbw->query( $sql, __METHOD__ );
+ }
+ }
+ }
+ // Upgrade the old file versions...
+ foreach ( $file->getHistory() as $oldFile ) {
+ $sha1 = $oldFile->getRepo()->getFileSha1( $oldFile->getPath() );
+ if ( strval( $sha1 ) !== '' ) { // file on disk and hashed properly
+ if ( $isRegen && $oldFile->getSha1() !== $sha1 ) {
+ // The population was probably done already. If the old SHA1
+ // does not match, then both fix the SHA1 and the metadata.
+ $oldFile->upgradeRow();
+ } else {
+ $sql = "UPDATE $oldImageTable SET oi_sha1=" . $dbw->addQuotes( $sha1 ) .
+ " WHERE (oi_name=" . $dbw->addQuotes( $oldFile->getName() ) . " AND" .
+ " oi_archive_name=" . $dbw->addQuotes( $oldFile->getArchiveName() ) . ")";
+ if ( $method == 'pipe' ) {
+ fwrite( $pipe, "$sql;\n" );
+ } else {
+ $dbw->query( $sql, __METHOD__ );
+ }
+ }
}
}
$i++;
diff --git a/maintenance/populateLogSearch.php b/maintenance/populateLogSearch.php
index e3f6067f..99d81557 100644
--- a/maintenance/populateLogSearch.php
+++ b/maintenance/populateLogSearch.php
@@ -18,11 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that makes the required database updates for populating the
+ * log_search table retroactively
+ *
+ * @ingroup Maintenance
+ */
class PopulateLogSearch extends LoggedUpdateMaintenance {
static $tableMap = array( 'rev' => 'revision', 'fa' => 'filearchive', 'oi' => 'oldimage', 'ar' => 'archive' );
diff --git a/maintenance/populateLogUsertext.php b/maintenance/populateLogUsertext.php
index 2b0e2d64..059b6fe2 100644
--- a/maintenance/populateLogUsertext.php
+++ b/maintenance/populateLogUsertext.php
@@ -20,11 +20,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that makes the required database updates for
+ * Special:ProtectedPages to show all protected pages.
+ *
+ * @ingroup Maintenance
+ */
class PopulateLogUsertext extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
@@ -59,12 +66,12 @@ class PopulateLogUsertext extends LoggedUpdateMaintenance {
$res = $db->select( array( 'logging', 'user' ),
array( 'log_id', 'user_name' ), $cond, __METHOD__ );
- $db->begin();
+ $db->begin( __METHOD__ );
foreach ( $res as $row ) {
$db->update( 'logging', array( 'log_user_text' => $row->user_name ),
array( 'log_id' => $row->log_id ), __METHOD__ );
}
- $db->commit();
+ $db->commit( __METHOD__ );
$blockStart += $this->mBatchSize;
$blockEnd += $this->mBatchSize;
wfWaitForSlaves();
diff --git a/maintenance/populateParentId.php b/maintenance/populateParentId.php
index 14f158c9..e81d4ffb 100644
--- a/maintenance/populateParentId.php
+++ b/maintenance/populateParentId.php
@@ -19,11 +19,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that makes the required database updates for rev_parent_id
+ * to be of any use.
+ *
+ * @ingroup Maintenance
+ */
class PopulateParentId extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
@@ -61,7 +68,7 @@ class PopulateParentId extends LoggedUpdateMaintenance {
$cond = "rev_id BETWEEN $blockStart AND $blockEnd";
$res = $db->select( 'revision',
array( 'rev_id', 'rev_page', 'rev_timestamp', 'rev_parent_id' ),
- $cond, __METHOD__ );
+ array( $cond, 'rev_parent_id' => null ), __METHOD__ );
# Go through and update rev_parent_id from these rows.
# Assume that the previous revision of the title was
# the original previous revision of the title when the
diff --git a/maintenance/populateRevisionLength.php b/maintenance/populateRevisionLength.php
index 6626cbc1..6c835f4e 100644
--- a/maintenance/populateRevisionLength.php
+++ b/maintenance/populateRevisionLength.php
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that populates the rev_len field for old revisions
+ * created before MW 1.10.
+ *
+ * @ingroup Maintenance
+ */
class PopulateRevisionLength extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/populateRevisionSha1.php b/maintenance/populateRevisionSha1.php
index 55e2a93d..2e14d31e 100644
--- a/maintenance/populateRevisionSha1.php
+++ b/maintenance/populateRevisionSha1.php
@@ -18,11 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that fills the rev_sha1 and ar_sha1 columns of revision
+ * and archive tables for revisions created before MW 1.19.
+ *
+ * @ingroup Maintenance
+ */
class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
public function __construct() {
parent::__construct();
@@ -81,13 +88,13 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
AND $idCol IS NOT NULL AND {$prefix}_sha1 = ''";
$res = $db->select( $table, '*', $cond, __METHOD__ );
- $db->begin();
+ $db->begin( __METHOD__ );
foreach ( $res as $row ) {
if ( $this->upgradeRow( $row, $table, $idCol, $prefix ) ) {
$count++;
}
}
- $db->commit();
+ $db->commit( __METHOD__ );
$blockStart += $this->mBatchSize;
$blockEnd += $this->mBatchSize;
@@ -102,23 +109,24 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
protected function doSha1LegacyUpdates() {
$count = 0;
$db = $this->getDB( DB_MASTER );
- $res = $db->select( 'archive', '*', array( 'ar_rev_id IS NULL' ), __METHOD__ );
+ $res = $db->select( 'archive', '*',
+ array( 'ar_rev_id IS NULL', 'ar_sha1' => '' ), __METHOD__ );
$updateSize = 0;
- $db->begin();
+ $db->begin( __METHOD__ );
foreach ( $res as $row ) {
if ( $this->upgradeLegacyArchiveRow( $row ) ) {
++$count;
}
if ( ++$updateSize >= 100 ) {
$updateSize = 0;
- $db->commit();
+ $db->commit( __METHOD__ );
$this->output( "Commited row with ar_timestamp={$row->ar_timestamp}\n" );
wfWaitForSlaves();
- $db->begin();
+ $db->begin( __METHOD__ );
}
}
- $db->commit();
+ $db->commit( __METHOD__ );
return $count;
}
@@ -131,12 +139,15 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
*/
protected function upgradeRow( $row, $table, $idCol, $prefix ) {
$db = $this->getDB( DB_MASTER );
- if ( $table === 'archive' ) {
- $rev = Revision::newFromArchiveRow( $row );
- } else {
- $rev = new Revision( $row );
+ try {
+ $rev = ( $table === 'archive' )
+ ? Revision::newFromArchiveRow( $row )
+ : new Revision( $row );
+ $text = $rev->getRawText();
+ } catch ( MWException $e ) {
+ $this->output( "Text of revision with {$idCol}={$row->$idCol} unavailable!\n" );
+ return false; // bug 22624?
}
- $text = $rev->getRawText();
if ( !is_string( $text ) ) {
# This should not happen, but sometimes does (bug 20757)
$this->output( "Text of revision with {$idCol}={$row->$idCol} unavailable!\n" );
@@ -145,7 +156,7 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
$db->update( $table,
array( "{$prefix}_sha1" => Revision::base36Sha1( $text ) ),
array( $idCol => $row->$idCol ),
- __METHOD__
+ __METHOD__
);
return true;
}
@@ -157,7 +168,12 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
*/
protected function upgradeLegacyArchiveRow( $row ) {
$db = $this->getDB( DB_MASTER );
- $rev = Revision::newFromArchiveRow( $row );
+ try {
+ $rev = Revision::newFromArchiveRow( $row );
+ } catch ( MWException $e ) {
+ $this->output( "Text of revision with timestamp {$row->ar_timestamp} unavailable!\n" );
+ return false; // bug 22624?
+ }
$text = $rev->getRawText();
if ( !is_string( $text ) ) {
# This should not happen, but sometimes does (bug 20757)
@@ -174,7 +190,7 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
'ar_timestamp' => $row->ar_timestamp,
'ar_len' => $row->ar_len // extra sanity
),
- __METHOD__
+ __METHOD__
);
return true;
}
diff --git a/maintenance/postgres/archives/patch-add_interwiki.sql b/maintenance/postgres/archives/patch-add_interwiki.sql
new file mode 100644
index 00000000..6c08af7a
--- /dev/null
+++ b/maintenance/postgres/archives/patch-add_interwiki.sql
@@ -0,0 +1,14 @@
+DROP FUNCTION IF EXISTS add_interwiki(TEXT,INT,CHARACTER) CASCADE;
+CREATE OR REPLACE FUNCTION "add_interwiki" (TEXT,INT,SMALLINT) RETURNS INT LANGUAGE SQL AS
+$mw$
+ INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3);
+ SELECT 1;
+$mw$;
+
+DROP FUNCTION IF EXISTS add_interwiki(TEXT,INT,CHARACTER) CASCADE;
+CREATE OR REPLACE FUNCTION "add_interwiki" (TEXT,INT,SMALLINT) RETURNS INT LANGUAGE SQL AS
+$mw$
+ INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3);
+ SELECT 1;
+$mw$;
+
diff --git a/maintenance/postgres/archives/patch-category.sql b/maintenance/postgres/archives/patch-category.sql
index 5e0d620f..266b1d00 100644
--- a/maintenance/postgres/archives/patch-category.sql
+++ b/maintenance/postgres/archives/patch-category.sql
@@ -1,8 +1,8 @@
-CREATE SEQUENCE category_id_seq;
+CREATE SEQUENCE category_cat_id_seq;
CREATE TABLE category (
- cat_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('category_id_seq'),
+ cat_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('category_cat_id_seq'),
cat_title TEXT NOT NULL,
cat_pages INTEGER NOT NULL DEFAULT 0,
cat_subcats INTEGER NOT NULL DEFAULT 0,
diff --git a/maintenance/postgres/archives/patch-external_user.sql b/maintenance/postgres/archives/patch-external_user.sql
new file mode 100644
index 00000000..6058a706
--- /dev/null
+++ b/maintenance/postgres/archives/patch-external_user.sql
@@ -0,0 +1,6 @@
+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-ipb_address_unique.sql b/maintenance/postgres/archives/patch-ipb_address_unique.sql
index e618f99c..e69de29b 100644
--- a/maintenance/postgres/archives/patch-ipb_address_unique.sql
+++ b/maintenance/postgres/archives/patch-ipb_address_unique.sql
@@ -1 +0,0 @@
-CREATE UNIQUE INDEX ipb_address_unique ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only);
diff --git a/maintenance/postgres/archives/patch-log_search.sql b/maintenance/postgres/archives/patch-log_search.sql
index 20a61fd7..4c0b3c61 100644
--- a/maintenance/postgres/archives/patch-log_search.sql
+++ b/maintenance/postgres/archives/patch-log_search.sql
@@ -5,5 +5,5 @@ CREATE TABLE log_search (
ls_log_id INTEGER NOT NULL DEFAULT 0
);
-ALTER TABLE log_search ADD CONSTRAINT log_search_pk PRIMARY KEY(ls_field, ls_value, ls_log_id);
+ALTER TABLE log_search ADD CONSTRAINT log_search_pkey PRIMARY KEY(ls_field, ls_value, ls_log_id);
CREATE INDEX ls_log_id ON log_search (ls_log_id);
diff --git a/maintenance/postgres/archives/patch-module_deps.sql b/maintenance/postgres/archives/patch-module_deps.sql
index 703dcdaf..bd7bb1f0 100644
--- a/maintenance/postgres/archives/patch-module_deps.sql
+++ b/maintenance/postgres/archives/patch-module_deps.sql
@@ -4,4 +4,4 @@ CREATE TABLE module_deps (
md_deps TEXT NOT NULL
);
-CREATE UNIQUE INDEX md_module_skin_idx ON module_deps (md_module, md_skin);
+CREATE UNIQUE INDEX md_module_skin ON module_deps (md_module, md_skin);
diff --git a/maintenance/postgres/archives/patch-msg_resource.sql b/maintenance/postgres/archives/patch-msg_resource.sql
index 00d82073..68756d1a 100644
--- a/maintenance/postgres/archives/patch-msg_resource.sql
+++ b/maintenance/postgres/archives/patch-msg_resource.sql
@@ -5,4 +5,4 @@ CREATE TABLE msg_resource (
mr_timestamp TIMESTAMPTZ NOT NULL
);
-CREATE UNIQUE INDEX mr_resource_lang_idx ON msg_resource (mr_resource, mr_lang);
+CREATE UNIQUE INDEX mr_resource_lang ON msg_resource (mr_resource, mr_lang);
diff --git a/maintenance/postgres/archives/patch-msg_resource_links.sql b/maintenance/postgres/archives/patch-msg_resource_links.sql
index e7b80219..88109da3 100644
--- a/maintenance/postgres/archives/patch-msg_resource_links.sql
+++ b/maintenance/postgres/archives/patch-msg_resource_links.sql
@@ -3,4 +3,4 @@ CREATE TABLE msg_resource_links (
mrl_message TEXT NOT NULL
);
-CREATE UNIQUE INDEX mrl_message_resource_idx ON msg_resource_links (mrl_message, mrl_resource);
+CREATE UNIQUE INDEX mrl_message_resource ON msg_resource_links (mrl_message, mrl_resource);
diff --git a/maintenance/postgres/compare_schemas.pl b/maintenance/postgres/compare_schemas.pl
index 18210fcf..53aeb147 100644
--- a/maintenance/postgres/compare_schemas.pl
+++ b/maintenance/postgres/compare_schemas.pl
@@ -38,7 +38,7 @@ while (<DATA>) {
my $datatype = join '|' => qw(
bool
-tinyint int bigint real float
+tinyint smallint int bigint real float
tinytext mediumtext text char varchar varbinary binary
timestamp datetime
tinyblob mediumblob blob
@@ -94,7 +94,7 @@ sub parse_sql {
next if /^\s*\-\-/ or /^\s+$/;
s/\s*\-\- [\w ]+$//;
chomp;
-
+
if (/CREATE\s*TABLE/i) {
if (m{^CREATE TABLE /\*_\*/(\w+) \($}) {
$table = $1;
@@ -158,16 +158,17 @@ for my $table (sort keys %{$old{$oldfile}}) {
}
}
-my $dtype = join '|' => qw(
+my $dtypelist = join '|' => qw(
SMALLINT INTEGER BIGINT NUMERIC SERIAL
TEXT CHAR VARCHAR
BYTEA
TIMESTAMPTZ
CIDR
);
-$dtype = qr{($dtype)};
+my $dtype = qr{($dtypelist)};
my %new;
my ($infunction,$inview,$inrule,$lastcomma) = (0,0,0,0);
+my %custom_type;
seek $newfh, 0, 0;
while (<$newfh>) {
next if /^\s*\-\-/ or /^\s*$/;
@@ -182,6 +183,11 @@ while (<$newfh>) {
next if /^DROP SEQUENCE/;
next if /^DROP FUNCTION/;
+ if (/^CREATE TYPE (\w+)/) {
+ die "Type $1 declared more than once!\n" if $custom_type{$1}++;
+ $dtype = qr{($dtypelist|$1)};
+ next;
+ }
chomp;
@@ -233,6 +239,7 @@ my $COLMAP = q{
## INTS:
tinyint SMALLINT
int INTEGER SERIAL
+smallint SMALLINT
bigint BIGINT
real NUMERIC
float NUMERIC
@@ -276,6 +283,9 @@ rc_log_type varbinary(255) TEXT
## Simple text-only strings:
ar_flags tinyblob TEXT
+cf_name varbinary(255) TEXT
+cf_value blob TEXT
+ar_sha1 varbinary(32) TEXT
cl_collation varbinary(32) TEXT
cl_sortkey varbinary(230) TEXT
ct_params blob TEXT
@@ -298,8 +308,13 @@ log_params blob TEXT # LF separated list of args
log_type varbinary(10) TEXT
ls_field varbinary(32) TEXT
md_deps mediumblob TEXT # JSON
+md_module varbinary(255) TEXT
+md_skin varbinary(32) TEXT
mr_blob mediumblob TEXT # JSON
mr_lang varbinary(32) TEXT
+mr_resource varbinary(255) TEXT
+mrl_message varbinary(255) TEXT
+mrl_resource varbinary(255) TEXT
oi_minor_mime varbinary(100) TEXT
oi_sha1 varbinary(32) TEXT
old_flags tinyblob TEXT
@@ -316,12 +331,17 @@ qc_type varbinary(32) TEXT
qcc_type varbinary(32) TEXT
qci_type varbinary(32) TEXT
rc_params blob TEXT
+rev_sha1 varbinary(32) TEXT
rlc_to_blob blob TEXT
ts_tags blob TEXT
-ug_group varbinary(16) TEXT
+ufg_group varbinary(32) TEXT
+ug_group varbinary(32) TEXT
ul_value blob TEXT
-up_property varbinary(32) TEXT
+up_property varbinary(255) TEXT
up_value blob TEXT
+us_sha1 varchar(31) TEXT
+us_source_type varchar(50) TEXT
+us_status varchar(50) TEXT
user_email_token binary(32) TEXT
user_ip varbinary(40) TEXT
user_newpassword tinyblob TEXT
@@ -434,6 +454,9 @@ for my $t (sort keys %{$old{$oldfile}}) {
next if exists $colmapok{$c}{$old}{$new};
$old =~ s/ENUM.*/ENUM/;
+
+ next if $old eq 'ENUM' and $new eq 'media_type';
+
if (! exists $colmap{$old}{$new}) {
print "Column types for $t.$c do not match: $old does not map to $new\n";
}
diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql
index 6890df91..3ac19cb4 100644
--- a/maintenance/postgres/tables.sql
+++ b/maintenance/postgres/tables.sql
@@ -36,7 +36,6 @@ CREATE TABLE mwuser ( -- replace reserved word 'user'
user_email_token TEXT,
user_email_token_expires TIMESTAMPTZ,
user_email_authenticated TIMESTAMPTZ,
- user_options TEXT,
user_touched TIMESTAMPTZ,
user_registration TIMESTAMPTZ,
user_editcount INTEGER
@@ -278,12 +277,14 @@ CREATE TABLE ipblocks (
ipb_range_end TEXT,
ipb_deleted SMALLINT NOT NULL DEFAULT 0,
ipb_block_email SMALLINT NOT NULL DEFAULT 0,
- ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0
+ ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0,
+ ipb_parent_block_id INTEGER NULL REFERENCES ipblocks(ipb_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED
);
CREATE UNIQUE INDEX ipb_address_unique ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only);
CREATE INDEX ipb_user ON ipblocks (ipb_user);
CREATE INDEX ipb_range ON ipblocks (ipb_range_start,ipb_range_end);
+CREATE INDEX ipb_parent_block_id ON ipblocks (ipb_parent_block_id);
CREATE TABLE image (
@@ -378,7 +379,7 @@ CREATE TABLE uploadstash (
us_media_type media_type DEFAULT NULL,
us_image_width INTEGER,
us_image_height INTEGER,
- us_image_bits INTEGER
+ us_image_bits SMALLINT
);
CREATE INDEX us_user_idx ON uploadstash (us_user);
diff --git a/maintenance/preprocessDump.php b/maintenance/preprocessDump.php
index ad9b4f14..5952fd96 100644
--- a/maintenance/preprocessDump.php
+++ b/maintenance/preprocessDump.php
@@ -1,10 +1,10 @@
<?php
/**
* Take page text out of an XML dump file and preprocess it to obj.
- * It may be useful for getting preprocessor statistics or filling the
+ * It may be useful for getting preprocessor statistics or filling the
* preprocessor cache.
*
- * Copyright (C) 2011 Platonides - http://www.mediawiki.org/
+ * Copyright © 2011 Platonides - http://www.mediawiki.org/
*
* 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
@@ -25,8 +25,14 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/dumpIterator.php' );
+require_once( __DIR__ . '/dumpIterator.php' );
+/**
+ * Maintenance script that takes page text out of an XML dump file and
+ * preprocesses it to obj.
+ *
+ * @ingroup Maintenance
+ */
class PreprocessDump extends DumpIterator {
/* Variables for dressing up as a parser */
diff --git a/maintenance/preprocessorFuzzTest.php b/maintenance/preprocessorFuzzTest.php
index 9dee67e2..a53bc88c 100644
--- a/maintenance/preprocessorFuzzTest.php
+++ b/maintenance/preprocessorFuzzTest.php
@@ -21,7 +21,7 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
$wgHooks['BeforeParserFetchTemplateAndtitle'][] = 'PPFuzzTester::templateHook';
diff --git a/maintenance/protect.php b/maintenance/protect.php
index 56958ea7..2f6aa1ae 100644
--- a/maintenance/protect.php
+++ b/maintenance/protect.php
@@ -1,6 +1,6 @@
<?php
/**
- * Protect or unprotect an article.
+ * Protect or unprotect a page.
*
* 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
@@ -17,15 +17,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that protects or unprotects a page.
+ *
+ * @ingroup Maintenance
+ */
class Protect extends Maintenance {
public function __construct() {
parent::__construct();
- $this->mDescription = "Protect or unprotect an article from the command line.";
+ $this->mDescription = "Protect or unprotect a page from the command line.";
$this->addOption( 'unprotect', 'Removes protection' );
$this->addOption( 'semiprotect', 'Adds semi-protection' );
$this->addOption( 'cascade', 'Add cascading protection' );
@@ -35,8 +41,6 @@ class Protect extends Maintenance {
}
public function execute() {
- global $wgUser;
-
$userName = $this->getOption( 'u', 'Maintenance script' );
$reason = $this->getOption( 'r', '' );
diff --git a/maintenance/proxy_check.php b/maintenance/proxy_check.php
index 9c5f32b2..10892c42 100644
--- a/maintenance/proxy_check.php
+++ b/maintenance/proxy_check.php
@@ -1,6 +1,21 @@
<?php
/**
- * Command line script to check for an open proxy at a specified location
+ * 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
diff --git a/maintenance/pruneFileCache.php b/maintenance/pruneFileCache.php
index f1a1cfd4..e058e3ec 100644
--- a/maintenance/pruneFileCache.php
+++ b/maintenance/pruneFileCache.php
@@ -1,6 +1,6 @@
<?php
/**
- * Prune file cache for pages, objects, resources, ect...
+ * Prune file cache for pages, objects, resources, etc.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that prunes file cache for pages, objects, resources, etc.
+ *
+ * @ingroup Maintenance
+ */
class PruneFileCache extends Maintenance {
protected $minSurviveTimestamp;
diff --git a/maintenance/purgeDeletedFiles.php b/maintenance/purgeDeletedFiles.php
index c8d4fc07..cd62716b 100644
--- a/maintenance/purgeDeletedFiles.php
+++ b/maintenance/purgeDeletedFiles.php
@@ -1,6 +1,6 @@
<?php
/**
- * Scans the deletion log and purges affected files within a timeframe.
+ * 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
@@ -17,11 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+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();
@@ -74,7 +81,7 @@ class PurgeDeletedFiles extends Maintenance {
protected function purgeFromArchiveTable( LocalFile $file ) {
$db = $file->getRepo()->getSlaveDB();
- $res = $db->select( 'filearchive',
+ $res = $db->select( 'filearchive',
array( 'fa_archive_name' ),
array( 'fa_name' => $file->getName() ),
__METHOD__
diff --git a/maintenance/purgeList.php b/maintenance/purgeList.php
index f1452bca..4b3c3821 100644
--- a/maintenance/purgeList.php
+++ b/maintenance/purgeList.php
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that sends purge requests for listed pages to squid.
+ *
+ * @ingroup Maintenance
+ */
class PurgeList extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/purgeOldText.inc b/maintenance/purgeOldText.inc
index 45a7ae28..111c786a 100644
--- a/maintenance/purgeOldText.inc
+++ b/maintenance/purgeOldText.inc
@@ -27,7 +27,7 @@ function PurgeRedundantText( $delete = false ) {
# Data should come off the master, wrapped in a transaction
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$tbl_arc = $dbw->tableName( 'archive' );
$tbl_rev = $dbw->tableName( 'revision' );
@@ -73,6 +73,6 @@ function PurgeRedundantText( $delete = false ) {
}
# Done
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
diff --git a/maintenance/purgeOldText.php b/maintenance/purgeOldText.php
index 0cbc724e..1f0b063b 100644
--- a/maintenance/purgeOldText.php
+++ b/maintenance/purgeOldText.php
@@ -17,12 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that purges old text records from the database.
+ *
+ * @ingroup Maintenance
+ */
class PurgeOldText extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/purgeParserCache.php b/maintenance/purgeParserCache.php
index 4d775f95..1c417980 100644
--- a/maintenance/purgeParserCache.php
+++ b/maintenance/purgeParserCache.php
@@ -1,22 +1,45 @@
<?php
/**
- * @ingroup Maintenance
+ * Remove old objects from the parser cache.
+ * This only works when the parser cache is in an SQL database.
+ *
+ * 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( dirname( __FILE__ ) . '/Maintenance.php' );
+require( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to remove old objects from the parser cache.
+ *
+ * @ingroup Maintenance
+ */
class PurgeParserCache extends Maintenance {
var $lastProgress;
function __construct() {
parent::__construct();
- $this->addDescription( "Remove old objects from the parser cache. " .
+ $this->addDescription( "Remove old objects from the parser cache. " .
"This only works when the parser cache is in an SQL database." );
$this->addOption( 'expiredate', 'Delete objects expiring before this date.', false, true );
- $this->addOption( 'age',
- 'Delete objects created more than this many seconds ago, assuming $wgParserCacheExpireTime '.
- 'has been consistent.',
+ $this->addOption( 'age',
+ 'Delete objects created more than this many seconds ago, assuming $wgParserCacheExpireTime ' .
+ 'has been consistent.',
false, true );
}
diff --git a/maintenance/purgeStaleMemcachedText.php b/maintenance/purgeStaleMemcachedText.php
deleted file mode 100644
index fc9a6a89..00000000
--- a/maintenance/purgeStaleMemcachedText.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-/**
- * @ingroup Maintenance Memcached
- * @file
- */
-
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
-
-function purgeStaleMemcachedText() {
- global $wgMemc, $wgDBname;
- $db = wfGetDB( DB_MASTER );
- $maxTextId = $db->selectField( 'text', 'max(old_id)' );
- $latestReplicatedTextId = $db->selectField( array( 'recentchanges', 'revision' ), 'rev_text_id',
- array( 'rev_id = rc_this_oldid', "rc_timestamp < '20101225183000'"), 'purgeStaleMemcachedText',
- array( 'ORDER BY' => 'rc_timestamp DESC' ) );
- $latestReplicatedTextId -= 100; # A bit of paranoia
-
- echo "Going to purge text entries from $latestReplicatedTextId to $maxTextId in $wgDBname\n";
-
- for ( $i = $latestReplicatedTextId; $i < $maxTextId; $i++ ) {
- $key = wfMemcKey( 'revisiontext', 'textid', $i );
-
- while (1) {
- if (! $wgMemc->delete( $key ) ) {
- echo "Memcache delete for $key returned false\n";
- }
- if ( $wgMemc->get( $key ) ) {
- echo "There's still content in $key!\n";
- } else {
- break;
- }
- }
-
- }
-}
-
-purgeStaleMemcachedText();
-
diff --git a/maintenance/reassignEdits.php b/maintenance/reassignEdits.php
index 3830fe38..a91abf93 100644
--- a/maintenance/reassignEdits.php
+++ b/maintenance/reassignEdits.php
@@ -17,13 +17,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
* @licence GNU General Public Licence 2.0 or later
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that reassigns edits from a user or IP address
+ * to another user.
+ *
+ * @ingroup Maintenance
+ */
class ReassignEdits extends Maintenance {
public function __construct() {
parent::__construct();
@@ -62,13 +69,13 @@ class ReassignEdits extends Maintenance {
*
* @param $from User to take edits from
* @param $to User to assign edits to
- * @param $rc Update the recent changes table
- * @param $report Don't change things; just echo numbers
+ * @param $rc bool Update the recent changes table
+ * @param $report bool Don't change things; just echo numbers
* @return integer Number of entries changed, or that would be changed
*/
private function doReassignEdits( &$from, &$to, $rc = false, $report = false ) {
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
# Count things
$this->output( "Checking current edits..." );
@@ -117,7 +124,7 @@ class ReassignEdits extends Maintenance {
}
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
return (int)$total;
}
@@ -150,7 +157,7 @@ class ReassignEdits extends Maintenance {
/**
* Initialise the user object
*
- * @param $username Username or IP address
+ * @param $username string Username or IP address
* @return User
*/
private function initialiseUser( $username ) {
diff --git a/maintenance/rebuildFileCache.php b/maintenance/rebuildFileCache.php
index e7ce3521..3165b97f 100644
--- a/maintenance/rebuildFileCache.php
+++ b/maintenance/rebuildFileCache.php
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that builds file cache for content pages.
+ *
+ * @ingroup Maintenance
+ */
class RebuildFileCache extends Maintenance {
public function __construct() {
parent::__construct();
@@ -93,11 +99,11 @@ class RebuildFileCache extends Maintenance {
array( 'ORDER BY' => 'page_id ASC', 'USE INDEX' => 'PRIMARY' )
);
- $dbw->begin(); // for any changes
+ $dbw->begin( __METHOD__ ); // for any changes
foreach ( $res as $row ) {
$rebuilt = false;
$wgRequestTime = microtime( true ); # bug 22852
-
+
$wgTitle = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
if ( null == $wgTitle ) {
$this->output( "Page {$row->page_id} has bad title\n" );
@@ -139,7 +145,7 @@ class RebuildFileCache extends Maintenance {
$this->output( "Page {$row->page_id} not cacheable\n" );
}
}
- $dbw->commit(); // commit any changes (just for sanity)
+ $dbw->commit( __METHOD__ ); // commit any changes (just for sanity)
$blockStart += $this->mBatchSize;
$blockEnd += $this->mBatchSize;
diff --git a/maintenance/rebuildImages.php b/maintenance/rebuildImages.php
index fe3b35c9..2842b402 100644
--- a/maintenance/rebuildImages.php
+++ b/maintenance/rebuildImages.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to update image metadata records
+ * Update image metadata records.
*
* Usage: php rebuildImages.php [--missing] [--dry-run]
* Options:
@@ -30,8 +30,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to update image metadata records.
+ *
+ * @ingroup Maintenance
+ */
class ImageBuilder extends Maintenance {
/**
@@ -86,7 +91,7 @@ class ImageBuilder extends Maintenance {
$this->processed = 0;
$this->updated = 0;
$this->count = $count;
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
$this->table = $table;
}
@@ -99,7 +104,7 @@ class ImageBuilder extends Maintenance {
$portion = $this->processed / $this->count;
$updateRate = $this->updated / $this->processed;
- $now = wfTime();
+ $now = microtime( true );
$delta = $now - $this->startTime;
$estimatedTotalTime = $delta / $portion;
$eta = $this->startTime + $estimatedTotalTime;
@@ -189,7 +194,7 @@ class ImageBuilder extends Maintenance {
$filename = $altname;
$this->output( "Estimating transcoding... $altname\n" );
} else {
- # @FIXME: create renameFile()
+ # @todo FIXME: create renameFile()
$filename = $this->renameFile( $filename );
}
}
diff --git a/maintenance/rebuildLocalisationCache.php b/maintenance/rebuildLocalisationCache.php
index 831d808a..83849de6 100644
--- a/maintenance/rebuildLocalisationCache.php
+++ b/maintenance/rebuildLocalisationCache.php
@@ -25,21 +25,32 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to rebuild the localisation cache.
+ *
+ * @ingroup Maintenance
+ */
class RebuildLocalisationCache extends Maintenance {
public function __construct() {
parent::__construct();
$this->mDescription = "Rebuild the localisation cache";
$this->addOption( 'force', 'Rebuild all files, even ones not out of date' );
$this->addOption( 'threads', 'Fork more than one thread', false, true );
+ $this->addOption( 'outdir', 'Override the output directory (normally $wgCacheDirectory)',
+ false, true );
}
public function memoryLimit() {
- return '200M';
+ if ( $this->hasOption( 'memory-limit' ) ) {
+ return parent::memoryLimit();
+ }
+ return '1000M';
}
public function execute() {
@@ -65,9 +76,12 @@ class RebuildLocalisationCache extends Maintenance {
if ( $force ) {
$conf['forceRecache'] = true;
}
+ if ( $this->hasOption( 'outdir' ) ) {
+ $conf['storeDirectory'] = $this->getOption( 'outdir' );
+ }
$lc = new LocalisationCache_BulkLoad( $conf );
- $codes = array_keys( Language::getLanguageNames( true ) );
+ $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) );
sort( $codes );
// Initialise and split into chunks
@@ -111,7 +125,7 @@ class RebuildLocalisationCache extends Maintenance {
/**
* Helper function to rebuild list of languages codes. Prints the code
* for each language which is rebuilt.
- * @param $codes list List of language codes to rebuild.
+ * @param $codes array List of language codes to rebuild.
* @param $lc LocalisationCache Instance of LocalisationCache_BulkLoad (?)
* @param $force bool Rebuild up-to-date languages
* @return int Number of rebuilt languages
diff --git a/maintenance/rebuildall.php b/maintenance/rebuildall.php
index dbbed86d..882ae1b3 100644
--- a/maintenance/rebuildall.php
+++ b/maintenance/rebuildall.php
@@ -18,11 +18,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that rebuilds link tracking tables from scratch.
+ *
+ * @ingroup Maintenance
+ */
class RebuildAll extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/rebuildmessages.php b/maintenance/rebuildmessages.php
index de37da7e..a70e591f 100644
--- a/maintenance/rebuildmessages.php
+++ b/maintenance/rebuildmessages.php
@@ -1,6 +1,6 @@
<?php
/**
- * This script purges all language messages from the cache
+ * Purge all languages from the message cache.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that purges all languages from the message cache.
+ *
+ * @ingroup Maintenance
+ */
class RebuildMessages extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/rebuildrecentchanges.php b/maintenance/rebuildrecentchanges.php
index 92d60902..0278f72c 100644
--- a/maintenance/rebuildrecentchanges.php
+++ b/maintenance/rebuildrecentchanges.php
@@ -1,7 +1,7 @@
<?php
/**
- * Rebuild link tracking tables from scratch. This takes several
- * hours, depending on the database size and server configuration.
+ * Rebuild recent changes from scratch. This takes several hours,
+ * depending on the database size and server configuration.
*
* 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
@@ -18,12 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @todo Document
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that rebuilds recent changes from scratch.
+ *
+ * @ingroup Maintenance
+ */
class RebuildRecentchanges extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/rebuildtextindex.php b/maintenance/rebuildtextindex.php
index 494e0a75..41b245f8 100644
--- a/maintenance/rebuildtextindex.php
+++ b/maintenance/rebuildtextindex.php
@@ -20,12 +20,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @todo document
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that rebuilds search index table from scratch.
+ *
+ * @ingroup Maintenance
+ */
class RebuildTextIndex extends Maintenance {
const RTI_CHUNK_SIZE = 500;
diff --git a/maintenance/refreshImageMetadata.php b/maintenance/refreshImageMetadata.php
index 958b2ba1..12da7a8b 100644
--- a/maintenance/refreshImageMetadata.php
+++ b/maintenance/refreshImageMetadata.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to refresh image metadata fields. See also rebuildImages.php
+ * Refresh image metadata fields. See also rebuildImages.php
*
* Usage: php refreshImageMetadata.php
*
@@ -27,8 +27,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to refresh image metadata fields.
+ *
+ * @ingroup Maintenance
+ */
class RefreshImageMetadata extends Maintenance {
/**
diff --git a/maintenance/refreshLinks.php b/maintenance/refreshLinks.php
index c16b6963..3d9270b8 100644
--- a/maintenance/refreshLinks.php
+++ b/maintenance/refreshLinks.php
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to refresh link tables.
+ *
+ * @ingroup Maintenance
+ */
class RefreshLinks extends Maintenance {
public function __construct() {
parent::__construct();
@@ -174,10 +180,10 @@ class RefreshLinks extends Maintenance {
* @param $id int The page_id of the redirect
*/
private function fixRedirect( $id ) {
- $title = Title::newFromID( $id );
+ $page = WikiPage::newFromID( $id );
$dbw = wfGetDB( DB_MASTER );
- if ( is_null( $title ) ) {
+ if ( $page === null ) {
// This page doesn't exist (any more)
// Delete any redirect table entry for it
$dbw->delete( 'redirect', array( 'rd_from' => $id ),
@@ -185,11 +191,10 @@ class RefreshLinks extends Maintenance {
return;
}
- $page = WikiPage::factory( $title );
$rt = $page->getRedirectTarget();
if ( $rt === null ) {
- // $title is not a redirect
+ // The page is not a redirect
// Delete any redirect table entry for it
$dbw->delete( 'redirect', array( 'rd_from' => $id ),
__METHOD__ );
@@ -201,37 +206,38 @@ class RefreshLinks extends Maintenance {
* @param $id int The page_id
*/
public static function fixLinksFromArticle( $id ) {
- global $wgParser;
+ global $wgParser, $wgContLang;
- $title = Title::newFromID( $id );
- $dbw = wfGetDB( DB_MASTER );
+ $page = WikiPage::newFromID( $id );
LinkCache::singleton()->clear();
- if ( is_null( $title ) ) {
+ if ( $page === null ) {
return;
}
- $revision = Revision::newFromTitle( $title );
- if ( !$revision ) {
+ $text = $page->getRawText();
+ if ( $text === false ) {
return;
}
- $dbw->begin();
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin( __METHOD__ );
- $options = new ParserOptions;
- $parserOutput = $wgParser->parse( $revision->getText(), $title, $options, true, true, $revision->getId() );
- $update = new LinksUpdate( $title, $parserOutput, false );
+ $options = ParserOptions::newFromUserAndLang( new User, $wgContLang );
+ $parserOutput = $wgParser->parse( $text, $page->getTitle(), $options, true, true, $page->getLatest() );
+ $update = new LinksUpdate( $page->getTitle(), $parserOutput, false );
$update->doUpdate();
- $dbw->commit();
+
+ $dbw->commit( __METHOD__ );
}
/**
* Removes non-existing links from pages from pagelinks, imagelinks,
* categorylinks, templatelinks, externallinks, interwikilinks, langlinks and redirect tables.
*
- * @param $maxLag
- * @param $batchSize The size of deletion batches
+ * @param $maxLag int
+ * @param $batchSize int The size of deletion batches
*
* @author Merlijn van Deen <valhallasw@arctus.nl>
*/
@@ -287,6 +293,7 @@ class RefreshLinks extends Maintenance {
$dbw->delete( $table, array( $field => $list ), __METHOD__ );
}
$this->output( "\n" );
+ wfWaitForSlaves();
}
$lb->closeAll();
}
diff --git a/maintenance/removeUnusedAccounts.php b/maintenance/removeUnusedAccounts.php
index ba25efdd..8bc27c18 100644
--- a/maintenance/removeUnusedAccounts.php
+++ b/maintenance/removeUnusedAccounts.php
@@ -18,12 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that removes unused user accounts from the database.
+ *
+ * @ingroup Maintenance
+ */
class RemoveUnusedAccounts extends Maintenance {
public function __construct() {
parent::__construct();
@@ -86,7 +92,7 @@ class RemoveUnusedAccounts extends Maintenance {
* (No edits, no deleted edits, no log entries, no current/old uploads)
*
* @param $id User's ID
- * @param $master Perform checking on the master
+ * @param $master bool Perform checking on the master
* @return bool
*/
private function isInactiveAccount( $id, $master = false ) {
@@ -95,12 +101,12 @@ class RemoveUnusedAccounts extends Maintenance {
'image' => 'img', 'oldimage' => 'oi', 'filearchive' => 'fa' );
$count = 0;
- $dbo->begin();
+ $dbo->begin( __METHOD__ );
foreach ( $checks as $table => $fprefix ) {
$conds = array( $fprefix . '_user' => $id );
$count += (int)$dbo->selectField( $table, 'COUNT(*)', $conds, __METHOD__ );
}
- $dbo->commit();
+ $dbo->commit( __METHOD__ );
return $count == 0;
}
diff --git a/maintenance/renameDbPrefix.php b/maintenance/renameDbPrefix.php
index 289e747f..6f244791 100644
--- a/maintenance/renameDbPrefix.php
+++ b/maintenance/renameDbPrefix.php
@@ -1,5 +1,6 @@
<?php
/**
+ * Change the prefix of database tables.
* Run this script to after changing $wgDBprefix on a wiki.
* The wiki will have to get downtime to do this correctly.
*
@@ -18,11 +19,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that changes the prefix of database tables.
+ *
+ * @ingroup Maintenance
+ */
class RenameDbPrefix extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/renderDump.php b/maintenance/renderDump.php
index 78c5b6f3..24bedfa4 100644
--- a/maintenance/renderDump.php
+++ b/maintenance/renderDump.php
@@ -28,8 +28,14 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that takes page text out of an XML dump file
+ * and render basic HTML out to files.
+ *
+ * @ingroup Maintenance
+ */
class DumpRenderer extends Maintenance {
private $count = 0;
@@ -46,7 +52,7 @@ class DumpRenderer extends Maintenance {
public function execute() {
$this->outputDirectory = $this->getOption( 'output-dir' );
$this->prefix = $this->getOption( 'prefix', 'wiki' );
- $this->startTime = wfTime();
+ $this->startTime = microtime( true );
if ( $this->hasOption( 'parser' ) ) {
global $wgParserConf;
@@ -62,7 +68,7 @@ class DumpRenderer extends Maintenance {
$importer->doImport();
- $delta = wfTime() - $this->startTime;
+ $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" );
diff --git a/maintenance/resetUserTokens.php b/maintenance/resetUserTokens.php
index a1c4eaeb..d7f8c6d0 100644
--- a/maintenance/resetUserTokens.php
+++ b/maintenance/resetUserTokens.php
@@ -1,7 +1,7 @@
<?php
/**
- * Script to reset the user_token for all users on the wiki. Useful if you
- * believe that your user table was acidentally leaked to an external source.
+ * Reset the user_token for all users on the wiki. Useful if you believe
+ * that your user table was acidentally leaked to an external source.
*
* 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,8 +23,13 @@
* @author Daniel Friesen <mediawiki@danielfriesen.name>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to reset the user_token for all users on the wiki.
+ *
+ * @ingroup Maintenance
+ */
class ResetUserTokens extends Maintenance {
public function __construct() {
parent::__construct();
@@ -33,7 +38,7 @@ class ResetUserTokens extends Maintenance {
}
public function execute() {
-
+
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" );
@@ -42,7 +47,7 @@ class ResetUserTokens extends Maintenance {
$this->output( "Abort with control-c in the next five seconds (skip this countdown with --nowarn) ... " );
wfCountDown( 5 );
}
-
+
// We list user by user_id from one of the slave database
$dbr = wfGetDB( DB_SLAVE );
$result = $dbr->select( 'user',
@@ -53,19 +58,19 @@ class ResetUserTokens extends Maintenance {
foreach ( $result as $id ) {
$user = User::newFromId( $id->user_id );
-
+
$username = $user->getName();
-
+
$this->output( "Resetting user_token for $username: " );
-
+
// Change value
$user->setToken();
$user->saveSettings();
-
+
$this->output( " OK\n" );
-
+
}
-
+
}
}
diff --git a/maintenance/rollbackEdits.php b/maintenance/rollbackEdits.php
index 3e57e01f..4660bcef 100644
--- a/maintenance/rollbackEdits.php
+++ b/maintenance/rollbackEdits.php
@@ -18,11 +18,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to rollback all edits by a given user or IP provided
+ * they're the most recent edit.
+ *
+ * @ingroup Maintenance
+ */
class RollbackEdits extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/runBatchedQuery.php b/maintenance/runBatchedQuery.php
index 83e0cab8..e1139164 100644
--- a/maintenance/runBatchedQuery.php
+++ b/maintenance/runBatchedQuery.php
@@ -19,11 +19,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to run a database query in batches and wait for slaves.
+ *
+ * @ingroup Maintenance
+ */
class BatchedQueryRunner extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/runJobs.php b/maintenance/runJobs.php
index 6068311e..e909bc06 100644
--- a/maintenance/runJobs.php
+++ b/maintenance/runJobs.php
@@ -1,8 +1,8 @@
<?php
/**
- * This script starts pending jobs.
+ * Run pending jobs.
*
- * Usage:
+ * Options:
* --maxjobs <num> (default 10000)
* --type <job_cmd>
*
@@ -21,11 +21,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that runs pending jobs.
+ *
+ * @ingroup Maintenance
+ */
class RunJobs extends Maintenance {
public function __construct() {
parent::__construct();
@@ -37,6 +43,9 @@ class RunJobs extends Maintenance {
}
public function memoryLimit() {
+ if ( $this->hasOption( 'memory-limit' ) ) {
+ return parent::memoryLimit();
+ }
// Don't eat all memory on the machine if we get a bad job.
return "150M";
}
@@ -60,9 +69,11 @@ class RunJobs extends Maintenance {
$wgTitle = Title::newFromText( 'RunJobs.php' );
$dbw = wfGetDB( DB_MASTER );
$n = 0;
- $conds = '';
- if ( $type !== false ) {
- $conds = "job_cmd = " . $dbw->addQuotes( $type );
+
+ if ( $type === false ) {
+ $conds = Job::defaultQueueConditions( );
+ } else {
+ $conds = array( 'job_cmd' => $type );
}
while ( $dbw->selectField( 'job', 'job_id', $conds, 'runJobs.php' ) ) {
@@ -77,6 +88,7 @@ class RunJobs extends Maintenance {
wfWaitForSlaves();
$t = microtime( true );
$offset = $job->id;
+ $this->runJobsLog( $job->toString() . " STARTING" );
$status = $job->run();
$t = microtime( true ) - $t;
$timeMs = intval( $t * 1000 );
diff --git a/maintenance/showJobs.php b/maintenance/showJobs.php
index ff7d3fc0..1dceb790 100644
--- a/maintenance/showJobs.php
+++ b/maintenance/showJobs.php
@@ -1,9 +1,9 @@
<?php
/**
- * Based on runJobs.php
- *
* Report number of jobs currently waiting in master database.
*
+ * Based on runJobs.php
+ *
* 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
@@ -19,13 +19,20 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Tim Starling
* @author Antoine Musso
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that reports the number of jobs currently waiting
+ * in master database.
+ *
+ * @ingroup Maintenance
+ */
class ShowJobs extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/showStats.php b/maintenance/showStats.php
index b284a9ac..982c7cbb 100644
--- a/maintenance/showStats.php
+++ b/maintenance/showStats.php
@@ -1,7 +1,7 @@
<?php
/**
- * Maintenance script to show the cached statistics.
+ * Show the cached statistics.
* Give out the same output as [[Special:Statistics]]
*
* This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
* @author Antoine Musso <hashar at free dot fr>
* Based on initStats.php by:
@@ -28,8 +29,13 @@
* @license GNU General Public License 2.0 or later
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to show the cached statistics.
+ *
+ * @ingroup Maintenance
+ */
class ShowStats extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/sql.php b/maintenance/sql.php
index c4af6307..04e98d91 100644
--- a/maintenance/sql.php
+++ b/maintenance/sql.php
@@ -18,11 +18,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that sends SQL queries from the specified file to the database.
+ *
+ * @ingroup Maintenance
+ */
class MwSql extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/sqlite.inc b/maintenance/sqlite.inc
index 1f821917..a8a1fce6 100644
--- a/maintenance/sqlite.inc
+++ b/maintenance/sqlite.inc
@@ -23,6 +23,8 @@
/**
* This class contains code common to different SQLite-related maintenance scripts
+ *
+ * @ingroup Maintenance
*/
class Sqlite {
@@ -85,4 +87,4 @@ class Sqlite {
$db->close();
return true;
}
- }; \ No newline at end of file
+ };
diff --git a/maintenance/sqlite.php b/maintenance/sqlite.php
index 864d5ab6..4085c59b 100644
--- a/maintenance/sqlite.php
+++ b/maintenance/sqlite.php
@@ -1,6 +1,6 @@
<?php
/**
- * Performs some operations specific to SQLite database backend
+ * Performs some operations specific to SQLite database backend.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that performs some operations specific to SQLite database backend.
+ *
+ * @ingroup Maintenance
+ */
class SqliteMaintenance extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/sqlite/archives/patch-cat_hidden.sql b/maintenance/sqlite/archives/patch-cat_hidden.sql
new file mode 100644
index 00000000..272b8ef3
--- /dev/null
+++ b/maintenance/sqlite/archives/patch-cat_hidden.sql
@@ -0,0 +1,20 @@
+-- cat_hidden is no longer used, delete it
+
+CREATE TABLE /*_*/category_tmp (
+ cat_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ cat_title varchar(255) binary NOT NULL,
+ cat_pages int signed NOT NULL default 0,
+ cat_subcats int signed NOT NULL default 0,
+ cat_files int signed NOT NULL default 0
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/category_tmp
+ SELECT cat_id, cat_title, cat_pages, cat_subcats, cat_files
+ FROM /*_*/category;
+
+DROP TABLE /*_*/category;
+
+ALTER TABLE /*_*/category_tmp RENAME TO /*_*/category;
+
+CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title);
+CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages);
diff --git a/maintenance/sqlite/archives/patch-revision-user-page-index.sql b/maintenance/sqlite/archives/patch-revision-user-page-index.sql
new file mode 100644
index 00000000..a4554c8f
--- /dev/null
+++ b/maintenance/sqlite/archives/patch-revision-user-page-index.sql
@@ -0,0 +1,4 @@
+-- New index on revision table to allow searches for all edits by a given user
+-- to a given page. Added 2007-08-28
+
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
diff --git a/maintenance/stats.php b/maintenance/stats.php
index 46926dd0..be448f99 100644
--- a/maintenance/stats.php
+++ b/maintenance/stats.php
@@ -1,6 +1,6 @@
<?php
/**
- * Show statistics from the cache
+ * Show statistics from the cache.
*
* 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
@@ -17,11 +17,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that shows statistics from the cache.
+ *
+ * @ingroup Maintenance
+ */
class CacheStats extends Maintenance {
public function __construct() {
diff --git a/maintenance/storage/checkStorage.php b/maintenance/storage/checkStorage.php
index af1f9ee2..6c669bfa 100644
--- a/maintenance/storage/checkStorage.php
+++ b/maintenance/storage/checkStorage.php
@@ -22,7 +22,7 @@
*/
if ( !defined( 'MEDIAWIKI' ) ) {
- require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+ require_once( __DIR__ . '/../commandLine.inc' );
$cs = new CheckStorage;
$fix = isset( $options['fix'] );
@@ -381,14 +381,15 @@ class CheckStorage {
$extDb->freeResult( $res );
// Print errors for missing blobs rows
- foreach ( $oldIds as $blobId => $oldIds ) {
- $this->error( 'restore text', "Error: missing target $cluster/$blobId for two-part ES URL", $oldIds );
+ foreach ( $oldIds as $blobId => $oldIds2 ) {
+ $this->error( 'restore text', "Error: missing target $cluster/$blobId for two-part ES URL", $oldIds2 );
}
}
}
function restoreText( $revIds, $xml ) {
- global $wgTmpDirectory, $wgDBname;
+ global $wgDBname;
+ $tmpDir = wfTempDir();
if ( !count( $revIds ) ) {
return;
@@ -396,8 +397,8 @@ class CheckStorage {
print "Restoring text from XML backup...\n";
- $revFileName = "$wgTmpDirectory/broken-revlist-$wgDBname";
- $filteredXmlFileName = "$wgTmpDirectory/filtered-$wgDBname.xml";
+ $revFileName = "$tmpDir/broken-revlist-$wgDBname";
+ $filteredXmlFileName = "$tmpDir/filtered-$wgDBname.xml";
// Write revision list
if ( !file_put_contents( $revFileName, implode( "\n", $revIds ) ) ) {
@@ -481,4 +482,3 @@ class CheckStorage {
$this->errors['fixed'][$id] = true;
}
}
-
diff --git a/maintenance/storage/compressOld.php b/maintenance/storage/compressOld.php
index afe01458..4594db71 100644
--- a/maintenance/storage/compressOld.php
+++ b/maintenance/storage/compressOld.php
@@ -17,8 +17,9 @@
* -c <chunk-size> maximum number of revisions in a concat chunk
* -b <begin-date> earliest date to check for uncompressed revisions
* -e <end-date> latest revision date to compress
- * -s <startid> the old_id to start from
- * -n <endid> the old_id to stop at
+ * -s <startid> the id to start from (referring to the text table for
+ * type gzip, and to the page table for type concat)
+ * -n <endid> the page_id to stop at (only when using concat compression type)
* --extdb <cluster> store specified revisions in an external cluster (untested)
*
* This program is free software; you can redistribute it and/or modify
@@ -40,7 +41,7 @@
* @ingroup Maintenance ExternalStorage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class CompressOld extends Maintenance {
/**
@@ -56,9 +57,9 @@ class CompressOld extends Maintenance {
$this->addOption( 'chunksize', 'Maximum number of revisions in a concat chunk', false, true, 'c' );
$this->addOption( 'begin-date', 'Earliest date to check for uncompressed revisions', false, true, 'b' );
$this->addOption( 'end-date', 'Latest revision date to compress', false, true, 'e' );
- $this->addOption( 'startid', 'The old_id to start from', false, true, 's' );
+ $this->addOption( 'startid', 'The id to start from (gzip -> text table, concat -> page table)', false, true, 's' );
$this->addOption( 'extdb', 'Store specified revisions in an external cluster (untested)', false, true );
- $this->addOption( 'endid', 'Stop at this old_id', false, true, 'n' );
+ $this->addOption( 'endid', 'The page_id to stop at (only when using concat compression type)', false, true, 'n' );
}
public function execute() {
@@ -293,7 +294,7 @@ class CompressOld extends Maintenance {
$chunk = new ConcatenatedGzipHistoryBlob();
$stubs = array();
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$usedChunk = false;
$primaryOldid = $revs[$i]->rev_text_id;
@@ -393,7 +394,7 @@ class CompressOld extends Maintenance {
}
# Done, next
$this->output( "/" );
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$i += $thisChunkSize;
wfWaitForSlaves();
}
diff --git a/maintenance/storage/dumpRev.php b/maintenance/storage/dumpRev.php
index b200d8af..6020f22e 100644
--- a/maintenance/storage/dumpRev.php
+++ b/maintenance/storage/dumpRev.php
@@ -18,7 +18,7 @@
* @ingroup Maintenance ExternalStorage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class DumpRev extends Maintenance {
public function __construct() {
diff --git a/maintenance/storage/fixBug20757.php b/maintenance/storage/fixBug20757.php
index cb2663d1..52ee825c 100644
--- a/maintenance/storage/fixBug20757.php
+++ b/maintenance/storage/fixBug20757.php
@@ -21,7 +21,7 @@
* @ingroup Maintenance ExternalStorage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class FixBug20757 extends Maintenance {
var $batchSize = 10000;
@@ -213,7 +213,7 @@ class FixBug20757 extends Maintenance {
if ( !$dryRun ) {
// Reset the text row to point to the original copy
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$dbw->update(
'text',
// SET
@@ -241,7 +241,7 @@ class FixBug20757 extends Maintenance {
),
__METHOD__
);
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
$this->waitForSlaves();
}
diff --git a/maintenance/storage/moveToExternal.php b/maintenance/storage/moveToExternal.php
index 64f3adaa..2dcc25c2 100644
--- a/maintenance/storage/moveToExternal.php
+++ b/maintenance/storage/moveToExternal.php
@@ -24,8 +24,8 @@
define( 'REPORTING_INTERVAL', 1 );
if ( !defined( 'MEDIAWIKI' ) ) {
- require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
- require_once( dirname( __FILE__ ) . '/../../includes/ExternalStoreDB.php' );
+ require_once( __DIR__ . '/../commandLine.inc' );
+ require_once( __DIR__ . '/../../includes/ExternalStoreDB.php' );
require_once( 'resolveStubs.php' );
$fname = 'moveToExternal';
diff --git a/maintenance/storage/orphanStats.php b/maintenance/storage/orphanStats.php
index f30f07e4..82ee135b 100644
--- a/maintenance/storage/orphanStats.php
+++ b/maintenance/storage/orphanStats.php
@@ -20,7 +20,7 @@
*
* @ingroup Maintenance ExternalStorage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class OrphanStats extends Maintenance {
public function __construct() {
@@ -28,7 +28,7 @@ class OrphanStats extends Maintenance {
$this->mDescription = "how some statistics on the blob_orphans table, created with trackBlobs.php";
}
- private function getDB( $cluster ) {
+ protected function &getDB( $cluster, $groups = array(), $wiki = false ) {
$lb = wfGetLBFactory()->getExternalLB( $cluster );
return $lb->getConnection( DB_SLAVE );
}
diff --git a/maintenance/storage/recompressTracked.php b/maintenance/storage/recompressTracked.php
index c8aac64b..4098077f 100644
--- a/maintenance/storage/recompressTracked.php
+++ b/maintenance/storage/recompressTracked.php
@@ -23,7 +23,7 @@
*/
$optionsWithArgs = RecompressTracked::getOptionsWithArgs();
-require( dirname( __FILE__ ) . '/../commandLine.inc' );
+require( __DIR__ . '/../commandLine.inc' );
if ( count( $args ) < 1 ) {
echo "Usage: php recompressTracked.php [options] <cluster> [... <cluster>...]
@@ -528,7 +528,7 @@ class RecompressTracked {
exit( 1 );
}
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$dbw->update( 'text',
array( // set
'old_text' => $url,
@@ -544,7 +544,7 @@ class RecompressTracked {
array( 'bt_text_id' => $textId ),
__METHOD__
);
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
/**
@@ -739,7 +739,7 @@ class CgzCopyTransaction {
//
// We do a locking read to prevent closer-run race conditions.
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
$res = $dbw->select( 'blob_tracking',
array( 'bt_text_id', 'bt_moved' ),
array( 'bt_text_id' => array_keys( $this->referrers ) ),
@@ -773,7 +773,7 @@ class CgzCopyTransaction {
$store = $this->parent->store;
$targetDB = $store->getMaster( $targetCluster );
$targetDB->clearFlag( DBO_TRX ); // we manage the transactions
- $targetDB->begin();
+ $targetDB->begin( __METHOD__ );
$baseUrl = $this->parent->store->store( $targetCluster, serialize( $this->cgz ) );
// Write the new URLs to the blob_tracking table
@@ -789,10 +789,10 @@ class CgzCopyTransaction {
);
}
- $targetDB->commit();
+ $targetDB->commit( __METHOD__ );
// Critical section here: interruption at this point causes blob duplication
// Reversing the order of the commits would cause data loss instead
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
// Write the new URLs to the text table and set the moved flag
if ( !$this->parent->copyOnly ) {
diff --git a/maintenance/storage/resolveStubs.php b/maintenance/storage/resolveStubs.php
index 08d0ee04..7e288e13 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( dirname( __FILE__ ) . '/../commandLine.inc' );
+ require_once( __DIR__ . '/../commandLine.inc' );
resolveStubs();
}
diff --git a/maintenance/storage/storageTypeStats.php b/maintenance/storage/storageTypeStats.php
index 817659fc..1afecc4e 100644
--- a/maintenance/storage/storageTypeStats.php
+++ b/maintenance/storage/storageTypeStats.php
@@ -19,7 +19,7 @@
* @ingroup Maintenance ExternalStorage
*/
-require_once( dirname( __FILE__ ) . '/../Maintenance.php' );
+require_once( __DIR__ . '/../Maintenance.php' );
class StorageTypeStats extends Maintenance {
function execute() {
diff --git a/maintenance/storage/testCompression.php b/maintenance/storage/testCompression.php
index 9ae26335..998ebe48 100644
--- a/maintenance/storage/testCompression.php
+++ b/maintenance/storage/testCompression.php
@@ -21,7 +21,7 @@
*/
$optionsWithArgs = array( 'start', 'limit', 'type' );
-require( dirname( __FILE__ ) . '/../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 b5f80047..214168a8 100644
--- a/maintenance/storage/trackBlobs.php
+++ b/maintenance/storage/trackBlobs.php
@@ -22,7 +22,7 @@
* @see wfWaitForSlaves()
*/
-require( dirname( __FILE__ ) . '/../commandLine.inc' );
+require( __DIR__ . '/../commandLine.inc' );
if ( count( $args ) < 1 ) {
@@ -113,7 +113,7 @@ class TrackBlobs {
$dbw->query( 'DROP TABLE ' . $dbw->tableName( 'blob_tracking' ) );
$dbw->query( 'DROP TABLE ' . $dbw->tableName( 'blob_orphans' ) );
}
- $dbw->sourceFile( dirname( __FILE__ ) . '/blob_tracking.sql' );
+ $dbw->sourceFile( __DIR__ . '/blob_tracking.sql' );
}
function getTextClause() {
diff --git a/maintenance/syncFileBackend.php b/maintenance/syncFileBackend.php
new file mode 100644
index 00000000..a29647b5
--- /dev/null
+++ b/maintenance/syncFileBackend.php
@@ -0,0 +1,252 @@
+<?php
+/**
+ * Sync one file backend to another based on the journal of later.
+ *
+ * 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 syncs one file backend to another based on
+ * the journal of later.
+ *
+ * @ingroup Maintenance
+ */
+class SyncFileBackend extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Sync one file backend with another using the journal";
+ $this->addOption( 'src', 'Name of backend to sync from', true, true );
+ $this->addOption( 'dst', 'Name of destination backend to sync', true, true );
+ $this->addOption( 'start', 'Starting journal ID', false, true );
+ $this->addOption( 'end', 'Ending journal ID', false, true );
+ $this->addOption( 'posdir', 'Directory to read/record journal positions', false, true );
+ $this->addOption( 'verbose', 'Verbose mode', false, false, 'v' );
+ $this->setBatchSize( 50 );
+ }
+
+ public function execute() {
+ $src = FileBackendGroup::singleton()->get( $this->getOption( 'src' ) );
+ $dst = FileBackendGroup::singleton()->get( $this->getOption( 'dst' ) );
+
+ $posDir = $this->getOption( 'posdir' );
+ $posFile = $posDir ? $posDir . '/' . wfWikiID() : false;
+
+ $start = $this->getOption( 'start', 0 );
+ if ( !$start && $posFile && is_dir( $posDir ) ) {
+ $start = is_file( $posFile )
+ ? (int)trim( file_get_contents( $posFile ) )
+ : 0;
+ ++$start; // we already did this ID, start with the next one
+ $startFromPosFile = true;
+ } else {
+ $startFromPosFile = false;
+ }
+ $end = $this->getOption( 'end', INF );
+
+ $this->output( "Synchronizing backend '{$dst->getName()}' to '{$src->getName()}'...\n" );
+ $this->output( "Starting journal position is $start.\n" );
+ if ( is_finite( $end ) ) {
+ $this->output( "Ending journal position is $end.\n" );
+ }
+
+ // Actually sync the dest backend with the reference backend
+ $lastOKPos = $this->syncBackends( $src, $dst, $start, $end );
+
+ // Update the sync position file
+ if ( $startFromPosFile && $lastOKPos >= $start ) { // successfully advanced
+ if ( file_put_contents( $posFile, $lastOKPos, LOCK_EX ) !== false ) {
+ $this->output( "Updated journal position file.\n" );
+ } else {
+ $this->output( "Could not update journal position file.\n" );
+ }
+ }
+
+ if ( $lastOKPos === false ) {
+ if ( !$start ) {
+ $this->output( "No journal entries found.\n" );
+ } else {
+ $this->output( "No new journal entries found.\n" );
+ }
+ } else {
+ $this->output( "Stopped synchronization at journal position $lastOKPos.\n" );
+ }
+
+ if ( $this->isQuiet() ) {
+ print $lastOKPos; // give a single machine-readable number
+ }
+ }
+
+ /**
+ * Sync $dst backend to $src backend based on the $src logs given after $start.
+ * Returns the journal entry ID this advanced to and handled (inclusive).
+ *
+ * @param $src FileBackend
+ * @param $dst FileBackend
+ * @param $start integer Starting journal position
+ * @param $end integer Starting journal position
+ * @return integer|false Journal entry ID or false if there are none
+ */
+ protected function syncBackends( FileBackend $src, FileBackend $dst, $start, $end ) {
+ $lastOKPos = 0; // failed
+ $first = true; // first batch
+
+ if ( $start > $end ) { // sanity
+ $this->error( "Error: given starting ID greater than ending ID.", 1 );
+ }
+
+ do {
+ $limit = min( $this->mBatchSize, $end - $start + 1 ); // don't go pass ending ID
+ $this->output( "Doing id $start to " . ( $start + $limit - 1 ) . "...\n" );
+
+ $entries = $src->getJournal()->getChangeEntries( $start, $limit, $next );
+ $start = $next; // start where we left off next time
+ if ( $first && !count( $entries ) ) {
+ return false; // nothing to do
+ }
+ $first = false;
+
+ $lastPosInBatch = 0;
+ $pathsInBatch = array(); // changed paths
+ foreach ( $entries as $entry ) {
+ if ( $entry['op'] !== 'null' ) { // null ops are just for reference
+ $pathsInBatch[$entry['path']] = 1; // remove duplicates
+ }
+ $lastPosInBatch = $entry['id'];
+ }
+
+ $status = $this->syncFileBatch( array_keys( $pathsInBatch ), $src, $dst );
+ if ( $status->isOK() ) {
+ $lastOKPos = max( $lastOKPos, $lastPosInBatch );
+ } else {
+ $this->error( print_r( $status->getErrorsArray(), true ) );
+ break; // no gaps; everything up to $lastPos must be OK
+ }
+
+ if ( !$start ) {
+ $this->output( "End of journal entries.\n" );
+ }
+ } while ( $start && $start <= $end );
+
+ return $lastOKPos;
+ }
+
+ /**
+ * Sync particular files of backend $src to the corresponding $dst backend files
+ *
+ * @param $paths Array
+ * @param $src FileBackend
+ * @param $dst FileBackend
+ * @return Status
+ */
+ protected function syncFileBatch( array $paths, FileBackend $src, FileBackend $dst ) {
+ $status = Status::newGood();
+ if ( !count( $paths ) ) {
+ return $status; // nothing to do
+ }
+
+ // Source: convert internal backend names (FileBackendMultiWrite) to the public one
+ $sPaths = $this->replaceNamePaths( $paths, $src );
+ // Destination: get corresponding path name
+ $dPaths = $this->replaceNamePaths( $paths, $dst );
+
+ // Lock the live backend paths from modification
+ $sLock = $src->getScopedFileLocks( $sPaths, LockManager::LOCK_UW, $status );
+ $eLock = $dst->getScopedFileLocks( $dPaths, LockManager::LOCK_EX, $status );
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+
+ $ops = array();
+ $fsFiles = array();
+ foreach ( $sPaths as $i => $sPath ) {
+ $dPath = $dPaths[$i]; // destination
+ $sExists = $src->fileExists( array( 'src' => $sPath, 'latest' => 1 ) );
+ if ( $sExists === true ) { // exists in source
+ if ( $this->filesAreSame( $src, $dst, $sPath, $dPath ) ) {
+ continue; // avoid local copies for non-FS backends
+ }
+ // Note: getLocalReference() is fast for FS backends
+ $fsFile = $src->getLocalReference( array( 'src' => $sPath, 'latest' => 1 ) );
+ if ( !$fsFile ) {
+ $this->error( "Unable to sync '$dPath': could not get local copy." );
+ $status->fatal( 'backend-fail-internal', $src->getName() );
+ return $status;
+ }
+ $fsFiles[] = $fsFile; // keep TempFSFile objects alive as needed
+ // Note: prepare() is usually fast for key/value backends
+ $status->merge( $dst->prepare( array(
+ 'dir' => dirname( $dPath ), 'bypassReadOnly' => 1 ) ) );
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+ $ops[] = array( 'op' => 'store',
+ 'src' => $fsFile->getPath(), 'dst' => $dPath, 'overwrite' => 1 );
+ } elseif ( $sExists === false ) { // does not exist in source
+ $ops[] = array( 'op' => 'delete', 'src' => $dPath, 'ignoreMissingSource' => 1 );
+ } else { // error
+ $this->error( "Unable to sync '$dPath': could not stat file." );
+ $status->fatal( 'backend-fail-internal', $src->getName() );
+ return $status;
+ }
+ }
+
+ $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->getOption( 'verbose' ) ) {
+ $this->output( "Synchronized these file(s) [{$ellapsed_ms}ms]:\n" .
+ implode( "\n", $dPaths ) . "\n" );
+ }
+
+ return $status;
+ }
+
+ /**
+ * Substitute the backend name of storage paths with that of a given one
+ *
+ * @param $paths Array|string List of paths or single string path
+ * @return Array|string
+ */
+ protected function replaceNamePaths( $paths, FileBackend $backend ) {
+ return preg_replace(
+ '!^mwstore://([^/]+)!',
+ StringUtils::escapeRegexReplacement( "mwstore://" . $backend->getName() ),
+ $paths // string or array
+ );
+ }
+
+ protected function filesAreSame( FileBackend $src, FileBackend $dst, $sPath, $dPath ) {
+ return (
+ ( $src->getFileSize( array( 'src' => $sPath ) )
+ === $dst->getFileSize( array( 'src' => $dPath ) ) // short-circuit
+ ) && ( $src->getFileSha1Base36( array( 'src' => $sPath ) )
+ === $dst->getFileSha1Base36( array( 'src' => $dPath ) )
+ )
+ );
+ }
+}
+
+$maintClass = "SyncFileBackend";
+require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/tables.sql b/maintenance/tables.sql
index db89c37e..52b835fd 100644
--- a/maintenance/tables.sql
+++ b/maintenance/tables.sql
@@ -25,7 +25,7 @@
-- in early 2002 after a lot of trouble with the fields
-- auto-updating.
--
--- The Postgres backend uses DATETIME fields for timestamps,
+-- The Postgres backend uses TIMESTAMPTZ fields for timestamps,
-- and we will migrate the MySQL definitions at some point as
-- well.
--
@@ -159,7 +159,8 @@ CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group);
CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group);
-- Stores the groups the user has once belonged to.
--- The user may still belong these groups. Check user_groups.
+-- The user may still belong to these groups (check user_groups).
+-- Users are not autopromoted to groups from which they were removed.
CREATE TABLE /*_*/user_former_groups (
-- Key to user_id
ufg_user int unsigned NOT NULL default 0,
@@ -325,6 +326,7 @@ CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
--
-- Holds text of individual page revisions.
@@ -569,10 +571,7 @@ CREATE TABLE /*_*/category (
-- ing is not.
cat_pages int signed NOT NULL default 0,
cat_subcats int signed NOT NULL default 0,
- cat_files int signed NOT NULL default 0,
-
- -- Reserved for future use
- cat_hidden tinyint unsigned NOT NULL default 0
+ cat_files int signed NOT NULL default 0
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title);
@@ -770,7 +769,13 @@ CREATE TABLE /*_*/ipblocks (
ipb_block_email bool NOT NULL default 0,
-- Block allows user to edit their own talk page
- ipb_allow_usertalk bool NOT NULL default 0
+ ipb_allow_usertalk bool NOT NULL default 0,
+
+ -- ID of the block that caused this block to exist
+ -- Autoblocks set this to the original block
+ -- so that the original block being deleted also
+ -- deletes the autoblocks
+ ipb_parent_block_id int default NULL
) /*$wgDBTableOptions*/;
@@ -782,6 +787,7 @@ CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start(8), ipb_range_end(8));
CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
--
@@ -944,44 +950,44 @@ CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timesta
-- moved into the actual filestore
--
CREATE TABLE /*_*/uploadstash (
- us_id int unsigned NOT NULL PRIMARY KEY auto_increment,
+ us_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
- -- the user who uploaded the file.
- us_user int unsigned NOT NULL,
+ -- the user who uploaded the file.
+ us_user int unsigned NOT NULL,
- -- file key. this is how applications actually search for the file.
- -- this might go away, or become the primary key.
- us_key varchar(255) NOT NULL,
+ -- file key. this is how applications actually search for the file.
+ -- this might go away, or become the primary key.
+ us_key varchar(255) NOT NULL,
- -- the original path
- us_orig_path varchar(255) NOT NULL,
+ -- the original path
+ us_orig_path varchar(255) NOT NULL,
- -- the temporary path at which the file is actually stored
- us_path varchar(255) NOT NULL,
+ -- the temporary path at which the file is actually stored
+ us_path varchar(255) NOT NULL,
- -- which type of upload the file came from (sometimes)
- us_source_type varchar(50),
+ -- which type of upload the file came from (sometimes)
+ us_source_type varchar(50),
- -- the date/time on which the file was added
- us_timestamp varbinary(14) not null,
+ -- the date/time on which the file was added
+ us_timestamp varbinary(14) NOT NULL,
- us_status varchar(50) not null,
+ us_status varchar(50) NOT NULL,
- -- chunk counter starts at 0, current offset is stored in us_size
- us_chunk_inx int unsigned NULL,
+ -- chunk counter starts at 0, current offset is stored in us_size
+ us_chunk_inx int unsigned NULL,
- -- file properties from File::getPropsFromPath. these may prove unnecessary.
- --
- us_size int unsigned NOT NULL,
- -- this hash comes from File::sha1Base36(), and is 31 characters
- us_sha1 varchar(31) NOT NULL,
- us_mime varchar(255),
- -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
- us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
- -- image-specific properties
- us_image_width int unsigned,
- us_image_height int unsigned,
- us_image_bits smallint unsigned
+ -- file properties from File::getPropsFromPath. these may prove unnecessary.
+ --
+ us_size int unsigned NOT NULL,
+ -- this hash comes from File::sha1Base36(), and is 31 characters
+ us_sha1 varchar(31) NOT NULL,
+ us_mime varchar(255),
+ -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
+ us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+ -- image-specific properties
+ us_image_width int unsigned,
+ us_image_height int unsigned,
+ us_image_bits smallint unsigned
) /*$wgDBTableOptions*/;
@@ -1235,7 +1241,7 @@ CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_times
CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp);
CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
-CREATE INDEX /*i*/type_action ON /*_*/logging(log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
CREATE TABLE /*_*/log_search (
@@ -1273,7 +1279,7 @@ CREATE TABLE /*_*/job (
) /*$wgDBTableOptions*/;
CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title, job_params(128));
-CREATE INDEX /*i*/job_timestamp ON /*_*/job(job_timestamp);
+CREATE INDEX /*i*/job_timestamp ON /*_*/job (job_timestamp);
-- Details of updates to cached special pages
@@ -1439,7 +1445,7 @@ CREATE TABLE /*_*/l10n_cache (
) /*$wgDBTableOptions*/;
CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
--- Table for storing JSON message blobs for the resource loader
+-- Table for caching JSON message blobs for the resource loader
CREATE TABLE /*_*/msg_resource (
-- Resource name
mr_resource varbinary(255) NOT NULL,
@@ -1460,8 +1466,8 @@ CREATE TABLE /*_*/msg_resource_links (
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource);
--- Table for tracking which local files a module depends on that aren't
--- registered directly.
+-- Table caching which local files a module depends on that aren't
+-- registered directly, used for fast retrieval of file dependency.
-- Currently only used for tracking images that CSS depends on
CREATE TABLE /*_*/module_deps (
-- Module name
diff --git a/maintenance/term/MWTerm.php b/maintenance/term/MWTerm.php
index 36fb8eec..ca0f95d2 100644
--- a/maintenance/term/MWTerm.php
+++ b/maintenance/term/MWTerm.php
@@ -1,14 +1,31 @@
<?php
-
/**
- * @ingroup Testing
- *
* Set of classes to help with test output and such. Right now pretty specific
* to the parser tests but could be more useful one day :)
*
+ * 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 Testing
* @todo Fixme: Make this more generic
*/
+/**
+ * Terminal that supports ANSI escape sequences.
+ */
class AnsiTermColorer {
function __construct() {
}
@@ -37,7 +54,9 @@ class AnsiTermColorer {
}
}
-/* A colour-less terminal */
+/**
+ * A colour-less terminal
+ */
class DummyTermColorer {
public function color( $color ) {
return '';
diff --git a/maintenance/undelete.php b/maintenance/undelete.php
index 1c3b14a5..ea8b0c4b 100644
--- a/maintenance/undelete.php
+++ b/maintenance/undelete.php
@@ -21,7 +21,7 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
class Undelete extends Maintenance {
public function __construct() {
diff --git a/maintenance/update.php b/maintenance/update.php
index c4bf3b22..877f1366 100644
--- a/maintenance/update.php
+++ b/maintenance/update.php
@@ -25,15 +25,20 @@
* @ingroup Maintenance
*/
-if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.2.3' ) < 0 ) ) {
- echo "You are using PHP version " . phpversion() . " but MediaWiki needs PHP 5.2.3 or higher. ABORTING.\n" .
+if ( !function_exists( 'version_compare' ) || ( version_compare( phpversion(), '5.3.2' ) < 0 ) ) {
+ echo "You are using PHP version " . phpversion() . " but MediaWiki needs PHP 5.3.2 or higher. ABORTING.\n" .
"Check if you have a newer php executable with a different name, such as php5.\n";
die( 1 );
}
$wgUseMasterForMaintenance = true;
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to run database schema updates.
+ *
+ * @ingroup Maintenance
+ */
class UpdateMediaWiki extends Maintenance {
function __construct() {
diff --git a/maintenance/updateArticleCount.php b/maintenance/updateArticleCount.php
index dbbfb80c..4d49dd2d 100644
--- a/maintenance/updateArticleCount.php
+++ b/maintenance/updateArticleCount.php
@@ -1,7 +1,7 @@
<?php
/**
- * Maintenance script to provide a better count of the number of articles
- * and update the site statistics table, if desired
+ * Provide a better count of the number of articles
+ * and update the site statistics table, if desired.
*
* 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,8 +23,14 @@
* @author Rob Church <robchur@gmail.com>
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to provide a better count of the number of articles
+ * and update the site statistics table, if desired.
+ *
+ * @ingroup Maintenance
+ */
class UpdateArticleCount extends Maintenance {
public function __construct() {
diff --git a/maintenance/updateCollation.php b/maintenance/updateCollation.php
index 023409fa..b732508f 100644
--- a/maintenance/updateCollation.php
+++ b/maintenance/updateCollation.php
@@ -1,7 +1,7 @@
<?php
/**
- * Script will find all rows in the categorylinks table whose collation is
- * out-of-date (cl_collation != $wgCategoryCollation) and repopulate cl_sortkey
+ * Find all rows in the categorylinks table whose collation is out-of-date
+ * (cl_collation != $wgCategoryCollation) and repopulate cl_sortkey
* using the page title and cl_sortkey_prefix.
*
* This program is free software; you can redistribute it and/or modify
@@ -26,12 +26,20 @@
#$optionsWithArgs = array( 'begin', 'max-slave-lag' );
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that will find all rows in the categorylinks table
+ * whose collation is out-of-date.
+ *
+ * @ingroup Maintenance
+ */
class UpdateCollation extends Maintenance {
const BATCH_SIZE = 50; // Number of rows to process in one batch
const SYNC_INTERVAL = 20; // Wait for slaves after this many batches
+ var $sizeHistogram = array();
+
public function __construct() {
parent::__construct();
@@ -50,6 +58,13 @@ TEXT;
'categorylinks table is large. This will only update rows with that ' .
'collation, though, so it may miss out-of-date rows with a different, ' .
'even older collation.', false, true );
+ $this->addOption( 'target-collation', 'Set this to the new collation type to ' .
+ 'use instead of $wgCategoryCollation. Usually you should not use this, ' .
+ 'you should just update $wgCategoryCollation in LocalSettings.php.',
+ false, true );
+ $this->addOption( 'dry-run', 'Don\'t actually change the collations, just ' .
+ 'compile statistics.' );
+ $this->addOption( 'verbose-stats', 'Show more statistics.' );
}
public function execute() {
@@ -57,10 +72,19 @@ TEXT;
$dbw = $this->getDB( DB_MASTER );
$force = $this->getOption( 'force' );
+ $dryRun = $this->getOption( 'dry-run' );
+ $verboseStats = $this->getOption( 'verbose-stats' );
+ if ( $this->hasOption( 'target-collation' ) ) {
+ $collationName = $this->getOption( 'target-collation' );
+ $collation = Collation::factory( $collationName );
+ } else {
+ $collationName = $wgCategoryCollation;
+ $collation = Collation::singleton();
+ }
$options = array( 'LIMIT' => self::BATCH_SIZE, 'STRAIGHT_JOIN' );
- if ( $force ) {
+ if ( $force || $dryRun ) {
$options['ORDER BY'] = 'cl_from, cl_to';
$collationConds = array();
} else {
@@ -68,7 +92,7 @@ TEXT;
$collationConds['cl_collation'] = $this->getOption( 'previous-collation' );
} else {
$collationConds = array( 0 =>
- 'cl_collation != ' . $dbw->addQuotes( $wgCategoryCollation )
+ 'cl_collation != ' . $dbw->addQuotes( $collationName )
);
}
@@ -79,13 +103,19 @@ TEXT;
$collationConds,
__METHOD__
);
-
- if ( $count == 0 ) {
- $this->output( "Collations up-to-date.\n" );
- return;
- }
- $this->output( "Fixing collation for $count rows.\n" );
+ } else {
+ $count = $dbw->estimateRowCount(
+ 'categorylinks',
+ '*',
+ $collationConds,
+ __METHOD__
+ );
+ }
+ if ( $count == 0 ) {
+ $this->output( "Collations up-to-date.\n" );
+ return;
}
+ $this->output( "Fixing collation for $count rows.\n" );
}
$count = 0;
@@ -104,7 +134,9 @@ TEXT;
);
$this->output( " processing..." );
- $dbw->begin();
+ if ( !$dryRun ) {
+ $dbw->begin( __METHOD__ );
+ }
foreach ( $res as $row ) {
$title = Title::newFromRow( $row );
if ( !$row->cl_collation ) {
@@ -129,23 +161,32 @@ TEXT;
} else {
$type = 'page';
}
- $dbw->update(
- 'categorylinks',
- array(
- 'cl_sortkey' => Collation::singleton()->getSortKey(
- $title->getCategorySortkey( $prefix ) ),
- 'cl_sortkey_prefix' => $prefix,
- 'cl_collation' => $wgCategoryCollation,
- 'cl_type' => $type,
- 'cl_timestamp = cl_timestamp',
- ),
- array( 'cl_from' => $row->cl_from, 'cl_to' => $row->cl_to ),
- __METHOD__
- );
+ $newSortKey = $collation->getSortKey(
+ $title->getCategorySortkey( $prefix ) );
+ if ( $verboseStats ) {
+ $this->updateSortKeySizeHistogram( $newSortKey );
+ }
+
+ if ( !$dryRun ) {
+ $dbw->update(
+ 'categorylinks',
+ array(
+ 'cl_sortkey' => $newSortKey,
+ 'cl_sortkey_prefix' => $prefix,
+ 'cl_collation' => $collationName,
+ 'cl_type' => $type,
+ 'cl_timestamp = cl_timestamp',
+ ),
+ array( 'cl_from' => $row->cl_from, 'cl_to' => $row->cl_to ),
+ __METHOD__
+ );
+ }
+ }
+ if ( !$dryRun ) {
+ $dbw->commit( __METHOD__ );
}
- $dbw->commit();
- if ( $force && $row ) {
+ if ( ( $force || $dryRun ) && $row ) {
$encFrom = $dbw->addQuotes( $row->cl_from );
$encTo = $dbw->addQuotes( $row->cl_to );
$batchConds = array(
@@ -156,12 +197,83 @@ TEXT;
$count += $res->numRows();
$this->output( "$count done.\n" );
- if ( ++$batchCount % self::SYNC_INTERVAL == 0 ) {
+ if ( !$dryRun && ++$batchCount % self::SYNC_INTERVAL == 0 ) {
$this->output( "Waiting for slaves ... " );
wfWaitForSlaves();
$this->output( "done\n" );
}
} while ( $res->numRows() == self::BATCH_SIZE );
+
+ $this->output( "$count rows processed\n" );
+
+ if ( $verboseStats ) {
+ $this->output( "\n" );
+ $this->showSortKeySizeHistogram();
+ }
+ }
+
+ function updateSortKeySizeHistogram( $key ) {
+ $length = strlen( $key );
+ if ( !isset( $this->sizeHistogram[$length] ) ) {
+ $this->sizeHistogram[$length] = 0;
+ }
+ $this->sizeHistogram[$length]++;
+ }
+
+ function showSortKeySizeHistogram() {
+ $maxLength = max( array_keys( $this->sizeHistogram ) );
+ if ( $maxLength == 0 ) {
+ return;
+ }
+ $numBins = 20;
+ $coarseHistogram = array_fill( 0, $numBins, 0 );
+ $coarseBoundaries = array();
+ $boundary = 0;
+ for ( $i = 0; $i < $numBins - 1; $i++ ) {
+ $boundary += $maxLength / $numBins;
+ $coarseBoundaries[$i] = round( $boundary );
+ }
+ $coarseBoundaries[$numBins - 1] = $maxLength + 1;
+ $raw = '';
+ for ( $i = 0; $i <= $maxLength; $i++ ) {
+ if ( $raw !== '' ) {
+ $raw .= ', ';
+ }
+ if ( !isset( $this->sizeHistogram[$i] ) ) {
+ $val = 0;
+ } else {
+ $val = $this->sizeHistogram[$i];
+ }
+ for ( $coarseIndex = 0; $coarseIndex < $numBins - 1; $coarseIndex++ ) {
+ if ( $coarseBoundaries[$coarseIndex] > $i ) {
+ $coarseHistogram[$coarseIndex] += $val;
+ break;
+ }
+ }
+ if ( $coarseIndex == $numBins - 1 ) {
+ $coarseHistogram[$coarseIndex] += $val;
+ }
+ $raw .= $val;
+ }
+
+ $this->output( "Sort key size histogram\nRaw data: $raw\n\n" );
+
+ $maxBinVal = max( $coarseHistogram );
+ $scale = 60 / $maxBinVal;
+ $prevBoundary = 0;
+ for ( $coarseIndex = 0; $coarseIndex < $numBins; $coarseIndex++ ) {
+ if ( !isset( $coarseHistogram[$coarseIndex] ) ) {
+ $val = 0;
+ } else {
+ $val = $coarseHistogram[$coarseIndex];
+ }
+ $boundary = $coarseBoundaries[$coarseIndex];
+ $this->output( sprintf( "%-10s %-10d |%s\n",
+ $prevBoundary . '-' . ( $boundary - 1 ) . ': ',
+ $val,
+ str_repeat( '*', $scale * $val ) ) );
+ $prevBoundary = $boundary;
+ }
}
}
diff --git a/maintenance/updateDoubleWidthSearch.php b/maintenance/updateDoubleWidthSearch.php
index 61545f8d..dc7398ad 100644
--- a/maintenance/updateDoubleWidthSearch.php
+++ b/maintenance/updateDoubleWidthSearch.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to normalize double-byte latin UTF-8 characters
+ * Normalize double-byte latin UTF-8 characters
*
* Usage: php updateDoubleWidthSearch.php
*
@@ -23,8 +23,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to normalize double-byte latin UTF-8 characters.
+ *
+ * @ingroup Maintenance
+ */
class UpdateDoubleWidthSearch extends Maintenance {
public function __construct() {
diff --git a/maintenance/updateRestrictions.php b/maintenance/updateRestrictions.php
index ffbdb2ba..8699dc26 100644
--- a/maintenance/updateRestrictions.php
+++ b/maintenance/updateRestrictions.php
@@ -24,8 +24,14 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script that updates page_restrictions table from
+ * old page_restriction column.
+ *
+ * @ingroup Maintenance
+ */
class UpdateRestrictions extends Maintenance {
public function __construct() {
parent::__construct();
diff --git a/maintenance/updateSearchIndex.php b/maintenance/updateSearchIndex.php
index eed3571c..2a71e7ed 100644
--- a/maintenance/updateSearchIndex.php
+++ b/maintenance/updateSearchIndex.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script for periodic off-peak updating of the search index
+ * Periodic off-peak updating of the search index.
*
* Usage: php updateSearchIndex.php [-s START] [-e END] [-p POSFILE] [-l LOCKTIME] [-q]
* Where START is the starting timestamp
@@ -28,8 +28,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script for periodic off-peak updating of the search index.
+ *
+ * @ingroup Maintenance
+ */
class UpdateSearchIndex extends Maintenance {
public function __construct() {
diff --git a/maintenance/updateSpecialPages.php b/maintenance/updateSpecialPages.php
index ddf1601b..3f1a90bb 100644
--- a/maintenance/updateSpecialPages.php
+++ b/maintenance/updateSpecialPages.php
@@ -1,7 +1,7 @@
<?php
/**
- * Run this script periodically if you have miser mode enabled, to refresh the
- * caches
+ * Update for cached special pages.
+ * Run this script periodically if you have miser mode enabled.
*
* 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
@@ -22,8 +22,13 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to update cached special pages.
+ *
+ * @ingroup Maintenance
+ */
class UpdateSpecialPages extends Maintenance {
public function __construct() {
parent::__construct();
@@ -128,7 +133,7 @@ class UpdateSpecialPages extends Maintenance {
$this->output( "Reconnected\n\n" );
} else {
# Commit the results
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
# Wait for the slave to catch up
wfWaitForSlaves();
diff --git a/maintenance/upgrade1_5.php b/maintenance/upgrade1_5.php
index 1577c237..1e268de3 100644
--- a/maintenance/upgrade1_5.php
+++ b/maintenance/upgrade1_5.php
@@ -28,7 +28,7 @@
* @ingroup Maintenance
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
define( 'MW_UPGRADE_COPY', false );
define( 'MW_UPGRADE_ENCODE', true );
@@ -116,7 +116,7 @@ class FiveUpgrade extends Maintenance {
/**
* Open a connection to the master server with the admin rights.
- * @return Database
+ * @return DatabaseBase
* @access private
*/
function newConnection() {
@@ -141,7 +141,7 @@ class FiveUpgrade extends Maintenance {
* Open a second connection to the master server, with buffering off.
* This will let us stream large datasets in and write in chunks on the
* other end.
- * @return Database
+ * @return DatabaseBase
* @access private
*/
function streamConnection() {
@@ -252,7 +252,7 @@ class FiveUpgrade extends Maintenance {
$this->chunkSize = $chunksize;
$this->chunkFinal = $final;
$this->chunkCount = 0;
- $this->chunkStartTime = wfTime();
+ $this->chunkStartTime = microtime( true );
$this->chunkOptions = array( 'IGNORE' );
$this->chunkTable = $table;
$this->chunkFunction = $fname;
@@ -273,7 +273,7 @@ class FiveUpgrade extends Maintenance {
$this->insertChunk( $chunk );
$this->chunkCount += count( $chunk );
- $now = wfTime();
+ $now = microtime( true );
$delta = $now - $this->chunkStartTime;
$rate = $this->chunkCount / $delta;
@@ -342,7 +342,7 @@ class FiveUpgrade extends Maintenance {
* MW_UPGRADE_COPY - straight copy
* MW_UPGRADE_ENCODE - for old Latin1 wikis, conv to UTF-8
* MW_UPGRADE_NULL - just put NULL
- * @param callable $callback An optional callback to modify the data
+ * @param $callback callback An optional callback to modify the data
* or perform other processing. Func should be
* ( object $row, array $copy ) and return $copy
* @access private
diff --git a/maintenance/userOptions.inc b/maintenance/userOptions.inc
index a6659fe7..2a066579 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( dirname( __FILE__ ) . '/commandLine.inc' );
+require_once( __DIR__ . '/commandLine.inc' );
/**
* @ingroup Maintenance
@@ -76,7 +76,7 @@ class userOptions {
* @param $opts array
* @param $args array
*
- * @return true
+ * @return bool
*/
private function initializeOpts( $opts, $args ) {
diff --git a/maintenance/userOptions.php b/maintenance/userOptions.php
index 64368f63..2181e44d 100644
--- a/maintenance/userOptions.php
+++ b/maintenance/userOptions.php
@@ -1,8 +1,6 @@
<?php
/**
- * Script to change users skins on the fly.
- * This is for at least MediaWiki 1.10alpha (r19611) and have not been
- * tested with previous versions. It should probably work with 1.7+.
+ * Script to change users preferences on the fly.
*
* Made on an original idea by Fooey (freenode)
*
diff --git a/maintenance/waitForSlave.php b/maintenance/waitForSlave.php
index 720ca288..655be43d 100644
--- a/maintenance/waitForSlave.php
+++ b/maintenance/waitForSlave.php
@@ -1,6 +1,6 @@
<?php
/**
- * Script to wait until slave lag goes under a certain value.
+ * Wait until slave lag goes under a certain value.
*
* 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
@@ -22,8 +22,13 @@
* @see wfWaitForSlaves()
*/
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+require_once( __DIR__ . '/Maintenance.php' );
+/**
+ * Maintenance script to wait until slave lag goes under a certain value.
+ *
+ * @ingroup Maintenance
+ */
class WaitForSlave extends Maintenance {
public function __construct() {
$this->addArg( 'maxlag', 'How long to wait for the slaves, default 10 seconds', false );