MediaWiki master
dumpIterator.php
Go to the documentation of this file.
1<?php
26use Wikimedia\Timestamp\ConvertibleTimestamp;
27
28// @codeCoverageIgnoreStart
29require_once __DIR__ . '/Maintenance.php';
30// @codeCoverageIgnoreEnd
31
37abstract class DumpIterator extends Maintenance {
39 private $count = 0;
41 private $startTime;
43 private $from;
44
45 public function __construct() {
46 parent::__construct();
47 $this->addDescription( 'Does something with a dump' );
48 $this->addOption( 'file', 'File with text to run.', false, true );
49 $this->addOption( 'dump', 'XML dump to execute all revisions.', false, true );
50 $this->addOption( 'from', 'Article from XML dump to start from.', false, true );
51 }
52
53 public function execute() {
54 if ( !( $this->hasOption( 'file' ) xor $this->hasOption( 'dump' ) ) ) {
55 $this->fatalError( "You must provide a file or dump" );
56 }
57
58 $this->checkOptions();
59
60 if ( $this->hasOption( 'file' ) ) {
61 $file = $this->getOption( 'file' );
62 $revision = new WikiRevision();
63 $text = file_get_contents( $file );
64 $title = Title::newFromText( rawurldecode( basename( $file, '.txt' ) ) );
65 $revision->setTitle( $title );
66 $content = ContentHandler::makeContent( $text, $title );
67 $revision->setContent( SlotRecord::MAIN, $content );
68
69 $this->from = false;
70 $this->handleRevision( $revision );
71
72 return;
73 }
74
75 $this->startTime = ConvertibleTimestamp::hrtime();
76
77 if ( $this->getOption( 'dump' ) == '-' ) {
78 $source = new ImportStreamSource( $this->getStdin() );
79 } else {
80 $this->fatalError( "Sorry, I don't support dump filenames yet. "
81 . "Use - and provide it on stdin on the meantime." );
82 }
83
84 $user = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [ 'steal' => true ] );
85
86 $importer = $this->getServiceContainer()
87 ->getWikiImporterFactory()
88 ->getWikiImporter( $source, new UltimateAuthority( $user ) );
89
90 $importer->setRevisionCallback(
91 $this->handleRevision( ... ) );
92 $importer->setNoticeCallback( static function ( $msg, $params ) {
93 echo wfMessage( $msg, $params )->text() . "\n";
94 } );
95
96 $this->from = $this->getOption( 'from', null );
97 $this->count = 0;
98 $importer->doImport();
99
100 $this->conclusions();
101
102 $delta = ( ConvertibleTimestamp::hrtime() - $this->startTime ) / 1e9;
103 $this->error( "Done {$this->count} revisions in " . round( $delta, 2 ) . " seconds " );
104 if ( $delta > 0 ) {
105 $this->error( round( $this->count / $delta, 2 ) . " pages/sec" );
106 }
107
108 # Perform the memory_get_peak_usage() when all the other data has been
109 # output so there's no damage if it dies. It is only available since
110 # 5.2.0 (since 5.2.1 if you haven't compiled with --enable-memory-limit)
111 $this->error( "Memory peak usage of " . memory_get_peak_usage() . " bytes\n" );
112 }
113
114 public function finalSetup( SettingsBuilder $settingsBuilder ) {
115 parent::finalSetup( $settingsBuilder );
116
117 if ( $this->getDbType() == Maintenance::DB_NONE ) {
118 // TODO: Allow hooks to be registered via SettingsBuilder as well!
119 // This matches the idea of unifying SettingsBuilder with ExtensionRegistry.
120 // phpcs:disable MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgHooks
121 global $wgHooks;
122 $wgHooks['InterwikiLoadPrefix'][] = 'DumpIterator::disableInterwikis';
123
124 $settingsBuilder->putConfigValues( [
125 MainConfigNames::UseDatabaseMessages => false,
126 MainConfigNames::LocalisationCacheConf => [ 'storeClass' => LCStoreNull::class ],
127 ] );
128 }
129 }
130
131 public static function disableInterwikis( string $prefix, array &$data ): bool {
132 # Title::newFromText will check on each namespaced article if it's an interwiki.
133 # We always answer that it is not.
134
135 return false;
136 }
137
143 public function handleRevision( $rev ) {
144 $title = $rev->getTitle();
145 if ( !$title ) {
146 $this->error( "Got bogus revision with null title!" );
147
148 return;
149 }
150
151 $this->count++;
152 if ( $this->from !== false ) {
153 if ( $this->from != $title ) {
154 return;
155 }
156 $this->output( "Skipped " . ( $this->count - 1 ) . " pages\n" );
157
158 $this->count = 1;
159 $this->from = null;
160 }
161
162 $this->processRevision( $rev );
163 }
164
168 public function checkOptions() {
169 }
170
174 public function conclusions() {
175 }
176
180 abstract public function processRevision( WikiRevision $rev );
181}
182
188class SearchDump extends DumpIterator {
189
190 public function __construct() {
191 parent::__construct();
192 $this->addDescription( 'Runs a regex in the revisions from a dump' );
193 $this->addOption( 'regex', 'Searching regex', true, true );
194 }
195
197 public function getDbType() {
198 return Maintenance::DB_NONE;
199 }
200
201 public function processRevision( WikiRevision $rev ) {
202 if ( preg_match( $this->getOption( 'regex' ), $rev->getContent()->getTextForSearchIndex() ) ) {
203 $this->output( $rev->getTitle() . " matches at edit from " . $rev->getTimestamp() . "\n" );
204 }
205 }
206}
207
208// @codeCoverageIgnoreStart
209$maintClass = SearchDump::class;
210require_once RUN_MAINTENANCE_IF_MAIN;
211// @codeCoverageIgnoreEnd
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:71
Base class for iterating over a dump.
__construct()
Default constructor.
execute()
Do the actual work.
conclusions()
Stub function for giving data about what was computed.
static disableInterwikis(string $prefix, array &$data)
checkOptions()
Stub function for processing additional options.
handleRevision( $rev)
Callback function for each revision, child classes should override processRevision instead.
finalSetup(SettingsBuilder $settingsBuilder)
Handle some last-minute setup here.
Base class for content handling.
Imports a XML dump from a file (either from file upload, files on disk, or HTTP)
Represents a revision, log entry or upload during the import process.
Null store backend, used to avoid DB errors during MediaWiki installation.
A class containing constants representing the names of configuration variables.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
error( $err)
Throw an error to the user.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
hasOption( $name)
Checks to see if a particular option was set.
getOption( $name, $default=null)
Get an option, or return the default.
getServiceContainer()
Returns the main service container.
getStdin( $len=null)
Return input from stdin.
addDescription( $text)
Set the description text.
Represents an authority that has all permissions.
Value object representing a content slot associated with a page revision.
Builder class for constructing a Config object from a set of sources during bootstrap.
putConfigValues(array $values)
Sets the value of multiple config variables.
Represents a title within MediaWiki.
Definition Title.php:69
User class for the MediaWiki software.
Definition User.php:129
$wgHooks
Config variable stub for the Hooks setting, for use by phpdoc and IDEs.
$source