public function execute() { $async = $this->getOption('async', false); $dryrun = $this->getOption('dry-run', false); if ($this->hasOption('title')) { $title = Title::newFromText($this->getOption('title')); if (!$title || !$title->isRedirect()) { $this->error($title->getPrefixedText() . " is not a redirect!\n", true); } } else { $title = null; } $dbr = wfGetDB(DB_SLAVE); // See also SpecialDoubleRedirects $tables = array('redirect', 'pa' => 'page', 'pb' => 'page'); $fields = array('pa.page_namespace AS pa_namespace', 'pa.page_title AS pa_title', 'pb.page_namespace AS pb_namespace', 'pb.page_title AS pb_title'); $conds = array('rd_from = pa.page_id', 'rd_namespace = pb.page_namespace', 'rd_title = pb.page_title', 'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes(''), 'pb.page_is_redirect' => 1); if ($title != null) { $conds['pb.page_namespace'] = $title->getNamespace(); $conds['pb.page_title'] = $title->getDBkey(); } // TODO: support batch querying $res = $dbr->select($tables, $fields, $conds, __METHOD__); if (!$res->numRows()) { $this->output("No double redirects found.\n"); return; } $jobs = array(); $processedTitles = "\n"; $n = 0; foreach ($res as $row) { $titleA = Title::makeTitle($row->pa_namespace, $row->pa_title); $titleB = Title::makeTitle($row->pb_namespace, $row->pb_title); $processedTitles .= "* [[{$titleA}]]\n"; $job = new DoubleRedirectJob($titleA, array('reason' => 'maintenance', 'redirTitle' => $titleB->getPrefixedDBkey())); if (!$async) { $success = $dryrun ? true : $job->run(); if (!$success) { $this->error("Error fixing " . $titleA->getPrefixedText() . ": " . $job->getLastError() . "\n"); } } else { $jobs[] = $job; // @todo FIXME: Hardcoded constant 10000 copied from DoubleRedirectJob class if (count($jobs) > 10000) { $this->queueJobs($jobs, $dryrun); $jobs = array(); } } if (++$n % 100 == 0) { $this->output("{$n}...\n"); } } if (count($jobs)) { $this->queueJobs($jobs, $dryrun); } $this->output("{$n} double redirects processed" . $processedTitles . "\n"); }