MediaWiki REL1_30
fixDoubleRedirects.php
Go to the documentation of this file.
1<?php
28require_once __DIR__ . '/Maintenance.php';
29
36 public function __construct() {
37 parent::__construct();
38 $this->addDescription( 'Script to fix double redirects' );
39 $this->addOption( 'async', 'Don\'t fix anything directly, just queue the jobs' );
40 $this->addOption( 'title', 'Fix only redirects pointing to this page', false, true );
41 $this->addOption( 'dry-run', 'Perform a dry run, fix nothing' );
42 }
43
44 public function execute() {
45 $async = $this->hasOption( 'async' );
46 $dryrun = $this->hasOption( 'dry-run' );
47
48 if ( $this->hasOption( 'title' ) ) {
49 $title = Title::newFromText( $this->getOption( 'title' ) );
50 if ( !$title || !$title->isRedirect() ) {
51 $this->error( $title->getPrefixedText() . " is not a redirect!\n", true );
52 }
53 } else {
54 $title = null;
55 }
56
57 $dbr = $this->getDB( DB_REPLICA );
58
59 // See also SpecialDoubleRedirects
60 $tables = [
61 'redirect',
62 'pa' => 'page',
63 'pb' => 'page',
64 ];
65 $fields = [
66 'pa.page_namespace AS pa_namespace',
67 'pa.page_title AS pa_title',
68 'pb.page_namespace AS pb_namespace',
69 'pb.page_title AS pb_title',
70 ];
71 $conds = [
72 'rd_from = pa.page_id',
73 'rd_namespace = pb.page_namespace',
74 'rd_title = pb.page_title',
75 'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ), // T42352
76 'pb.page_is_redirect' => 1,
77 ];
78
79 if ( $title != null ) {
80 $conds['pb.page_namespace'] = $title->getNamespace();
81 $conds['pb.page_title'] = $title->getDBkey();
82 }
83 // TODO: support batch querying
84
85 $res = $dbr->select( $tables, $fields, $conds, __METHOD__ );
86
87 if ( !$res->numRows() ) {
88 $this->output( "No double redirects found.\n" );
89
90 return;
91 }
92
93 $jobs = [];
94 $processedTitles = "\n";
95 $n = 0;
96 foreach ( $res as $row ) {
97 $titleA = Title::makeTitle( $row->pa_namespace, $row->pa_title );
98 $titleB = Title::makeTitle( $row->pb_namespace, $row->pb_title );
99
100 $processedTitles .= "* [[$titleA]]\n";
101
102 $job = new DoubleRedirectJob( $titleA, [
103 'reason' => 'maintenance',
104 'redirTitle' => $titleB->getPrefixedDBkey()
105 ] );
106
107 if ( !$async ) {
108 $success = ( $dryrun ? true : $job->run() );
109 if ( !$success ) {
110 $this->error( "Error fixing " . $titleA->getPrefixedText()
111 . ": " . $job->getLastError() . "\n" );
112 }
113 } else {
114 $jobs[] = $job;
115 // @todo FIXME: Hardcoded constant 10000 copied from DoubleRedirectJob class
116 if ( count( $jobs ) > 10000 ) {
117 $this->queueJobs( $jobs, $dryrun );
118 $jobs = [];
119 }
120 }
121
122 if ( ++$n % 100 == 0 ) {
123 $this->output( "$n...\n" );
124 }
125 }
126
127 if ( count( $jobs ) ) {
128 $this->queueJobs( $jobs, $dryrun );
129 }
130 $this->output( "$n double redirects processed" . $processedTitles . "\n" );
131 }
132
133 protected function queueJobs( $jobs, $dryrun = false ) {
134 $this->output( "Queuing batch of " . count( $jobs ) . " double redirects.\n" );
135 JobQueueGroup::singleton()->push( $dryrun ? [] : $jobs );
136 }
137}
138
139$maintClass = "FixDoubleRedirects";
140require_once RUN_MAINTENANCE_IF_MAIN;
Job to fix double redirects after moving a page.
Maintenance script that fixes double redirects.
queueJobs( $jobs, $dryrun=false)
__construct()
Default constructor.
execute()
Do the actual work.
static singleton( $wiki=false)
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
getDB( $db, $groups=[], $wiki=false)
Returns a database to be used by current maintenance script.
hasOption( $name)
Checks to see if a particular param exists.
addDescription( $text)
Set the description text.
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.
if(! $regexes) $dbr
Definition cleanup.php:94
$res
Definition database.txt:21
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling output() to send it all. It could be easily changed to send incrementally if that becomes useful
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist & $tables
Definition hooks.txt:1013
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
Definition hooks.txt:2581
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
Definition hooks.txt:1976
require_once RUN_MAINTENANCE_IF_MAIN
const DB_REPLICA
Definition defines.php:25
if(count( $args)< 1) $job