32$IP = getenv(
"MW_INSTALL_PATH" ) ? getenv(
"MW_INSTALL_PATH" ) : __DIR__ .
"/../../..";
33if ( !is_readable(
"$IP/maintenance/Maintenance.php" ) ) {
34 die(
"MW_INSTALL_PATH needs to be set to your MediaWiki installation.\n" );
36require_once (
"$IP/maintenance/Maintenance.php" );
60 parent::__construct();
61 $this->mDescription =
"CLI utility to replace text wherever it is " .
64 $this->
addArg(
"target",
"Target text to find.",
false );
65 $this->
addArg(
"replace",
"Text to replace.",
false );
67 $this->
addOption(
"dry-run",
"Only find the texts, don't replace.",
69 $this->
addOption(
"regex",
"This is a regex (false).",
71 $this->
addOption(
"user",
"The user to attribute this to (uid 1).",
73 $this->
addOption(
"yes",
"Skip all prompts with an assumed 'yes'.",
75 $this->
addOption(
"summary",
"Alternate edit summary. (%r is where to " .
76 " place the replacement text, %f the text to look for.)",
78 $this->
addOption(
"nsall",
"Search all canonical namespaces (false). " .
79 "If true, this option overrides the ns option.",
false,
false,
'a' );
80 $this->
addOption(
"ns",
"Comma separated namespaces to search in " .
81 "(Main) .",
false,
true );
82 $this->
addOption(
"replacements",
"File containing the list of " .
83 "replacements to be made. Fields in the file are tab-separated. " .
84 "See --show-file-format for more information.",
false,
true,
"f" );
85 $this->
addOption(
"show-file-format",
"Show a description of the " .
86 "file format to use with --replacements.",
false,
false );
87 $this->
addOption(
"no-announce",
"Do not announce edits on Special:RecentChanges or " .
88 "watchlists.",
false,
false,
"m" );
89 $this->
addOption(
"debug",
"Display replacements being made.",
false,
false );
90 $this->
addOption(
"listns",
"List out the namespaces on this wiki.",
92 $this->
addOption(
'rename',
"Rename page titles instead of replacing contents.",
96 if ( method_exists( $this,
'requireExtension' ) ) {
102 $userReplacing = $this->
getOption(
"user", 1 );
104 $user = is_numeric( $userReplacing ) ?
108 if ( get_class( $user ) !==
'User' ) {
110 "Couldn't translate '$userReplacing' to a user.",
true
120 $this->
error(
"You have to specify a target.",
true );
128 $this->
error(
"You have to specify replacement text.",
true );
134 $file = $this->
getOption(
"replacements" );
139 if ( !is_readable( $file ) ) {
140 throw new MWException(
"File does not exist or is not readable: "
144 $handle = fopen( $file,
"r" );
145 if ( $handle ===
false ) {
146 throw new MWException(
"Trouble opening file: $file\n" );
150 $this->defaultContinue =
true;
152 while ( (
$line = fgets( $handle ) ) !==
false ) {
154 $field = explode(
"\t", substr(
$line, 0, -1 ) );
155 if ( !isset( $field[1] ) ) {
159 $this->target[] = $field[0];
160 $this->replacement[] = $field[1];
167 if ( !is_bool( $this->defaultContinue ) ) {
168 $this->defaultContinue =
179 if ( $this->
getOption(
"summary" ) !==
null ) {
180 $msg = str_replace( [
'%f',
'%r' ],
181 [ $this->target, $this->replacement ],
188 echo
"Index\tNamespace\n";
189 $nsList = MWNamespace::getCanonicalNamespaces();
191 foreach ( $nsList as $int => $val ) {
195 echo
" $int\t$val\n";
202The format of the replacements file is tab separated with three fields.
203Any line that does not have a tab is ignored and can be considered a comment.
207 1. String to search
for.
208 2. String to
replace found text with.
209 3. (optional) The presence of
this field indicates that the previous two
210 are considered a regular expression.
216regex(p*) Count the Ps; \\1
true
225 if ( !$nsall && !$ns ) {
228 $canonical = MWNamespace::getCanonicalNamespaces();
234 if ( is_numeric( $n ) ) {
235 if ( isset( $canonical[ $n ] ) ) {
244 }, explode(
",", $ns ) );
248 return $val !==
null;
272 foreach (
$titles as $title ) {
276 $this->
output(
"$title -> $newTitle\n" );
284 foreach (
$titles as $title ) {
289 'user_id' => $this->user->getId(),
296 $params[
'create_redirect' ] =
false;
297 $params[
'watch_page' ] =
false;
300 echo
"Replacing on $title... ";
302 if (
$job->run() !==
true ) {
303 $this->
error(
"Trouble on the page '$title'." );
314 while ( $reply !==
"y" && $reply !==
"n" ) {
316 $reply = substr( strtolower( $reply ), 0, 1 );
318 return $reply ===
"y";
326 if ( $this->
getOption(
"show-file-format" ) ) {
330 $this->user = $this->
getUser();
351 $this->doAnnounce =
true;
357 $this->
error(
"No matching namespaces.",
true );
360 foreach ( array_keys( $this->target ) as $index ) {
361 $target = $this->target[$index];
366 echo
"Replacing '$target' with '$replacement'";
368 echo
" as regular expression.";
373 if ( $this->rename ) {
393 if ( count(
$titles ) === 0 ) {
394 $this->
error(
'No targets found to replace.',
true );
406 if ( !$this->
getReply(
'Replace instances on these pages?' ) ) {
412 if ( $this->
getOption(
"user",
null ) ===
null ) {
413 $comment =
" (Use --user to override)";
415 if ( $this->
getOption(
"no-announce",
false ) ) {
416 $this->doAnnounce =
false;
419 "Attribute changes to the user '{$this->user}'?$comment"
to move a page</td >< td > &*You are moving the page across namespaces
$wgShowExceptionDetails
If set to true, uncaught exceptions will print the exception message and a complete stack trace to ou...
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
addArg( $arg, $description, $required=true)
Add some args that are needed.
requireExtension( $name)
Indicate that the specified extension must be loaded before the script can run.
output( $out, $channel=null)
Throw some output to the user.
hasOption( $name)
Checks to see if a particular option exists.
static readconsole( $prompt='> ')
Prompt the console for input.
getArg( $argId=0, $default=null)
Get an argument.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
Maintenance script that replaces text in pages.
listTitles( $titles, $target, $replacement, $regex, $rename)
__construct()
Default constructor.
getSummary( $target, $replacement)
shouldContinueByDefault()
replaceTitles( $titles, $target, $replacement, $useRegex, $rename)
Background job to replace text in a given page.
static doSearchQuery( $search, $namespaces, $category, $prefix, $use_regex=false)
static getReplacedTitle(Title $title, $search, $replacement, $regex)
Do a replacement on a title.
static getMatchingTitles( $str, $namespaces, $category, $prefix, $use_regex=false)
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
static newFromId( $id)
Static factory method for creation from a given user ID.
The ContentHandler facility adds support for arbitrary content types on wiki instead of relying on wikitext for everything It was introduced in MediaWiki Each kind of and so on Built in content types are
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title e g db for database replication lag or jobqueue for job queue size converted to pseudo seconds It is possible to add more fields and they will be returned to the user in the API response after the basic globals have been set but before ordinary actions take place replace
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults error
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation use $formDescriptor instead default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "<div ...>$1</div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
require_once RUN_MAINTENANCE_IF_MAIN
if(count( $args)< 1) $job