MediaWiki  master
SpecialDoubleRedirects.php
Go to the documentation of this file.
1 <?php
27 
35  function __construct( $name = 'DoubleRedirects' ) {
36  parent::__construct( $name );
37  }
38 
39  public function isExpensive() {
40  return true;
41  }
42 
43  function isSyndicated() {
44  return false;
45  }
46 
47  function sortDescending() {
48  return false;
49  }
50 
51  function getPageHeader() {
52  return $this->msg( 'doubleredirectstext' )->parseAsBlock();
53  }
54 
55  function reallyGetQueryInfo( $namespace = null, $title = null ) {
56  $limitToTitle = !( $namespace === null && $title === null );
57  $dbr = wfGetDB( DB_REPLICA );
58  $retval = [
59  'tables' => [
60  'ra' => 'redirect',
61  'rb' => 'redirect',
62  'pa' => 'page',
63  'pb' => 'page'
64  ],
65  'fields' => [
66  'namespace' => 'pa.page_namespace',
67  'title' => 'pa.page_title',
68  'value' => 'pa.page_title',
69 
70  'b_namespace' => 'pb.page_namespace',
71  'b_title' => 'pb.page_title',
72 
73  // Select fields from redirect instead of page. Because there may
74  // not actually be a page table row for this target (e.g. for interwiki redirects)
75  'c_namespace' => 'rb.rd_namespace',
76  'c_title' => 'rb.rd_title',
77  'c_fragment' => 'rb.rd_fragment',
78  'c_interwiki' => 'rb.rd_interwiki',
79  ],
80  'conds' => [
81  'ra.rd_from = pa.page_id',
82 
83  // Filter out redirects where the target goes interwiki (T42353).
84  // This isn't an optimization, it is required for correct results,
85  // otherwise a non-double redirect like Bar -> w:Foo will show up
86  // like "Bar -> Foo -> w:Foo".
87 
88  // Need to check both NULL and "" for some reason,
89  // apparently either can be stored for non-iw entries.
90  'ra.rd_interwiki IS NULL OR ra.rd_interwiki = ' . $dbr->addQuotes( '' ),
91 
92  'pb.page_namespace = ra.rd_namespace',
93  'pb.page_title = ra.rd_title',
94 
95  'rb.rd_from = pb.page_id',
96  ]
97  ];
98 
99  if ( $limitToTitle ) {
100  $retval['conds']['pa.page_namespace'] = $namespace;
101  $retval['conds']['pa.page_title'] = $title;
102  }
103 
104  return $retval;
105  }
106 
107  public function getQueryInfo() {
108  return $this->reallyGetQueryInfo();
109  }
110 
111  function getOrderFields() {
112  return [ 'ra.rd_namespace', 'ra.rd_title' ];
113  }
114 
120  function formatResult( $skin, $result ) {
121  // If no Title B or C is in the query, it means this came from
122  // querycache (which only saves the 3 columns for title A).
123  // That does save the bulk of the query cost, but now we need to
124  // get a little more detail about each individual entry quickly
125  // using the filter of reallyGetQueryInfo.
126  $deep = false;
127  if ( $result ) {
128  if ( isset( $result->b_namespace ) ) {
129  $deep = $result;
130  } else {
131  $dbr = wfGetDB( DB_REPLICA );
132  $qi = $this->reallyGetQueryInfo(
133  $result->namespace,
134  $result->title
135  );
136  $res = $dbr->select(
137  $qi['tables'],
138  $qi['fields'],
139  $qi['conds'],
140  __METHOD__
141  );
142 
143  if ( $res ) {
144  $deep = $dbr->fetchObject( $res ) ?: false;
145  }
146  }
147  }
148 
149  $titleA = Title::makeTitle( $result->namespace, $result->title );
150 
151  $linkRenderer = $this->getLinkRenderer();
152  if ( !$deep ) {
153  return '<del>' . $linkRenderer->makeLink( $titleA, null, [], [ 'redirect' => 'no' ] ) . '</del>';
154  }
155 
156  // if the page is editable, add an edit link
157  if (
158  // check user permissions
159  MediaWikiServices::getInstance()
161  ->userHasRight( $this->getUser(), 'edit' ) &&
162  // check, if the content model is editable through action=edit
163  ContentHandler::getForTitle( $titleA )->supportsDirectEditing()
164  ) {
165  $edit = $linkRenderer->makeKnownLink(
166  $titleA,
167  $this->msg( 'parentheses', $this->msg( 'editlink' )->text() )->text(),
168  [],
169  [ 'action' => 'edit' ]
170  );
171  } else {
172  $edit = '';
173  }
174 
175  $linkA = $linkRenderer->makeKnownLink(
176  $titleA,
177  null,
178  [],
179  [ 'redirect' => 'no' ]
180  );
181 
182  $titleB = Title::makeTitle( $deep->b_namespace, $deep->b_title );
183  $linkB = $linkRenderer->makeKnownLink(
184  $titleB,
185  null,
186  [],
187  [ 'redirect' => 'no' ]
188  );
189 
190  $titleC = Title::makeTitle(
191  $deep->c_namespace,
192  $deep->c_title,
193  $deep->c_fragment,
194  $deep->c_interwiki
195  );
196  $linkC = $linkRenderer->makeKnownLink( $titleC, $titleC->getFullText() );
197 
198  $lang = $this->getLanguage();
199  $arr = $lang->getArrow() . $lang->getDirMark();
200 
201  return ( "{$linkA} {$edit} {$arr} {$linkB} {$arr} {$linkC}" );
202  }
203 
204  public function execute( $par ) {
205  $this->addHelpLink( 'Help:Redirects' );
206  parent::execute( $par );
207  }
208 
215  function preprocessResults( $db, $res ) {
216  if ( !$res->numRows() ) {
217  return;
218  }
219 
220  $batch = new LinkBatch;
221  foreach ( $res as $row ) {
222  $batch->add( $row->namespace, $row->title );
223  if ( isset( $row->b_namespace ) ) {
224  // lazy loaded when using cached results
225  $batch->add( $row->b_namespace, $row->b_title );
226  }
227  if ( isset( $row->c_interwiki ) && !$row->c_interwiki ) {
228  // lazy loaded when using cached result, not added when interwiki link
229  $batch->add( $row->c_namespace, $row->c_title );
230  }
231  }
232  $batch->execute();
233 
234  // Back to start for display
235  $res->seek( 0 );
236  }
237 
238  protected function getGroupName() {
239  return 'maintenance';
240  }
241 }
add( $ns, $dbkey)
Definition: LinkBatch.php:83
if(!isset( $args[0])) $lang
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
__construct( $name='DoubleRedirects')
This is a class for doing query pages; since they&#39;re almost all the same, we factor out some of the f...
Definition: QueryPage.php:36
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
getPermissionManager()
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
reallyGetQueryInfo( $namespace=null, $title=null)
preprocessResults( $db, $res)
Cache page content model and gender distinction for performance.
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:586
getUser()
Shortcut to get the User executing this instance.
getLanguage()
Shortcut to get user&#39;s language.
A special page listing redirects to redirecting page.
const DB_REPLICA
Definition: defines.php:25
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:67