Index: trunk/phase3/includes/Article.php |
— | — | @@ -103,8 +103,7 @@ |
104 | 104 | * @return Title object |
105 | 105 | */ |
106 | 106 | public function insertRedirect() { |
107 | | - // set noRecurse so that we always get an entry even if redirects are "disabled" |
108 | | - $retval = Title::newFromRedirect( $this->getContent(), false, true ); |
| 107 | + $retval = Title::newFromRedirect( $this->getContent() ); |
109 | 108 | if( !$retval ) { |
110 | 109 | return null; |
111 | 110 | } |
— | — | @@ -136,7 +135,7 @@ |
137 | 136 | * @return mixed false, Title of in-wiki target, or string with URL |
138 | 137 | */ |
139 | 138 | public function followRedirectText( $text ) { |
140 | | - $rt = Title::newFromRedirect( $text ); // only get the final target |
| 139 | + $rt = Title::newFromRedirectRecurse( $text ); // recurse through to only get the final target |
141 | 140 | # process if title object is valid and not special:userlogout |
142 | 141 | if( $rt ) { |
143 | 142 | if( $rt->getInterwiki() != '' ) { |
— | — | @@ -607,10 +606,9 @@ |
608 | 607 | } |
609 | 608 | // Apparently loadPageData was never called |
610 | 609 | $this->loadContent(); |
611 | | - // Only get the next target to reduce load times |
612 | | - $titleObj = Title::newFromRedirect( $this->fetchContent(), false, true ); |
| 610 | + $titleObj = Title::newFromRedirectRe( $this->fetchContent() ); |
613 | 611 | } else { |
614 | | - $titleObj = Title::newFromRedirect( $text, false, true ); |
| 612 | + $titleObj = Title::newFromRedirect( $text ); |
615 | 613 | } |
616 | 614 | return $titleObj !== NULL; |
617 | 615 | } |
— | — | @@ -943,7 +941,7 @@ |
944 | 942 | $wgOut->addHTML( htmlspecialchars( $this->mContent ) ); |
945 | 943 | $wgOut->addHTML( "\n</pre>\n" ); |
946 | 944 | } |
947 | | - } else if( $rt = Title::newFromRedirect( $text, true ) ) { # get an array of redirect targets |
| 945 | + } else if( $rt = Title::newFromRedirectArray( $text ) ) { # get an array of redirect targets |
948 | 946 | # Don't append the subtitle if this was an old revision |
949 | 947 | $wgOut->addHTML( $this->viewRedirect( $rt, !$wasRedirected && $this->isCurrent() ) ); |
950 | 948 | $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser)); |
— | — | @@ -3475,9 +3473,9 @@ |
3476 | 3474 | public static function getAutosummary( $oldtext, $newtext, $flags ) { |
3477 | 3475 | # Decide what kind of autosummary is needed. |
3478 | 3476 | |
3479 | | - # Redirect autosummaries -- should only get the next target and not recurse |
3480 | | - $ot = Title::newFromRedirect( $oldtext, false, true ); |
3481 | | - $rt = Title::newFromRedirect( $newtext, false, true ); |
| 3477 | + # Redirect autosummaries |
| 3478 | + $ot = Title::newFromRedirect( $oldtext ); |
| 3479 | + $rt = Title::newFromRedirect( $newtext ); |
3482 | 3480 | if( is_object( $rt ) && ( !is_object( $ot ) || !$rt->equals( $ot ) || $ot->getFragment() != $rt->getFragment() ) ) { |
3483 | 3481 | return wfMsgForContent( 'autoredircomment', $rt->getFullText() ); |
3484 | 3482 | } |
Index: trunk/phase3/includes/EditPage.php |
— | — | @@ -1683,7 +1683,7 @@ |
1684 | 1684 | $parserOptions->setTidy(true); |
1685 | 1685 | $parserOutput = $wgParser->parse( $previewtext, $this->mTitle, $parserOptions ); |
1686 | 1686 | $previewHTML = $parserOutput->mText; |
1687 | | - } elseif ( $rt = Title::newFromRedirect( $this->textbox1, true ) ) { |
| 1687 | + } elseif ( $rt = Title::newFromRedirectArray( $this->textbox1 ) ) { |
1688 | 1688 | $previewHTML = $this->mArticle->viewRedirect( $rt, false ); |
1689 | 1689 | } else { |
1690 | 1690 | $toparse = $this->textbox1; |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -294,21 +294,77 @@ |
295 | 295 | /** |
296 | 296 | * Extract a redirect destination from a string and return the |
297 | 297 | * Title, or null if the text doesn't contain a valid redirect |
| 298 | + * This will only return the very next target, useful for |
| 299 | + * the redirect table and other checks that don't need full recursion |
298 | 300 | * |
299 | 301 | * @param $text \type{\string} Text with possible redirect |
300 | | - * @param $getAllTargets \type{\bool} Should we get an array of every target or just the final one? |
301 | | - * @param $noRecurse \type{\bool} This will prevent any and all recursion, only getting the very next target |
302 | | - * This is mainly meant for Article::insertRedirect so that the redirect table still works properly |
303 | | - * (makes double redirect and broken redirect reports display accurate results). |
304 | 302 | * @return \type{Title} The corresponding Title |
305 | | - * @return \type{\array} Array of redirect targets (Title objects), with the destination being last |
306 | 303 | */ |
307 | | - public static function newFromRedirect( $text, $getAllTargets = false, $noRecurse = false ) { |
| 304 | + public static function newFromRedirect( $text ) { |
| 305 | + return self::newFromRedirectInternal( $text ); |
| 306 | + } |
| 307 | + |
| 308 | + /** |
| 309 | + * Extract a redirect destination from a string and return the |
| 310 | + * Title, or null if the text doesn't contain a valid redirect |
| 311 | + * This will recurse down $wgMaxRedirects times or until a non-redirect target is hit |
| 312 | + * in order to provide (hopefully) the Title of the final destination instead of another redirect |
| 313 | + * |
| 314 | + * @param $text \type{\string} Text with possible redirect |
| 315 | + * @return \type{Title} The corresponding Title |
| 316 | + */ |
| 317 | + public static function newFromRedirectRecurse( $text ) { |
| 318 | + $titles = self::newFromRedirectArray( $text ); |
| 319 | + return array_pop( $titles ); |
| 320 | + } |
| 321 | + |
| 322 | + /** |
| 323 | + * Extract a redirect destination from a string and return an |
| 324 | + * array of Titles, or null if the text doesn't contain a valid redirect |
| 325 | + * The last element in the array is the final destination after all redirects |
| 326 | + * have been resolved (up to $wgMaxRedirects times) |
| 327 | + * |
| 328 | + * @param $text \type{\string} Text with possible redirect |
| 329 | + * @return \type{\array} Array of Titles, with the destination last |
| 330 | + */ |
| 331 | + public static function newFromRedirectArray( $text ) { |
308 | 332 | global $wgMaxRedirects; |
309 | 333 | // are redirects disabled? |
310 | | - // Note that we should get a Title object if possible if $noRecurse is true so that the redirect table functions properly |
311 | | - if( !$noRecurse && $wgMaxRedirects < 1 ) |
| 334 | + if( $wgMaxRedirects < 1 ) |
312 | 335 | return null; |
| 336 | + $title = self::newFromRedirectInternal( $text ); |
| 337 | + if( is_null( $title ) ) |
| 338 | + return null; |
| 339 | + // recursive check to follow double redirects |
| 340 | + $recurse = $wgMaxRedirects; |
| 341 | + $titles = array( $title ); |
| 342 | + while( --$recurse >= 0 ) { |
| 343 | + if( $title->isRedirect() ) { |
| 344 | + $article = new Article( $title, 0 ); |
| 345 | + $newtitle = $article->getRedirectTarget(); |
| 346 | + } else { |
| 347 | + break; |
| 348 | + } |
| 349 | + // Redirects to some special pages are not permitted |
| 350 | + if( $newtitle instanceOf Title && $newtitle->isValidRedirectTarget() ) { |
| 351 | + // the new title passes the checks, so make that our current title so that further recursion can be checked |
| 352 | + $title = $newtitle; |
| 353 | + $titles[] = $newtitle; |
| 354 | + } else { |
| 355 | + break; |
| 356 | + } |
| 357 | + } |
| 358 | + return $titles; |
| 359 | + } |
| 360 | + |
| 361 | + /** |
| 362 | + * Really extract the redirect destination |
| 363 | + * Do not call this function directly, use one of the newFromRedirect* functions above |
| 364 | + * |
| 365 | + * @param $text \type{\string} Text with possible redirect |
| 366 | + * @return \type{Title} The corresponding Title |
| 367 | + */ |
| 368 | + protected static function newFromRedirectInternal( $text ) { |
313 | 369 | $redir = MagicWord::get( 'redirect' ); |
314 | 370 | $text = trim($text); |
315 | 371 | if( $redir->matchStartAndRemove( $text ) ) { |
— | — | @@ -326,38 +382,11 @@ |
327 | 383 | $m[1] = urldecode( ltrim( $m[1], ':' ) ); |
328 | 384 | } |
329 | 385 | $title = Title::newFromText( $m[1] ); |
330 | | - // If the initial title is a redirect to bad special pages or is invalid, quit early |
| 386 | + // If the title is a redirect to bad special pages or is invalid, return null |
331 | 387 | if( !$title instanceof Title || !$title->isValidRedirectTarget() ) { |
332 | 388 | return null; |
333 | 389 | } |
334 | | - // If $noRecurse is true, simply return here |
335 | | - if( $noRecurse ) { |
336 | | - return $title; |
337 | | - } |
338 | | - // recursive check to follow double redirects |
339 | | - $recurse = $wgMaxRedirects; |
340 | | - $targets = array(); |
341 | | - while( --$recurse >= 0 ) { |
342 | | - // Redirects to some special pages are not permitted |
343 | | - if( $title instanceof Title && $title->isValidRedirectTarget() ) { |
344 | | - $targets[] = $title; |
345 | | - if( $title->isRedirect() ) { |
346 | | - $article = new Article( $title, 0 ); |
347 | | - $title = $article->getRedirectTarget(); |
348 | | - } else { |
349 | | - break; |
350 | | - } |
351 | | - } else { |
352 | | - break; |
353 | | - } |
354 | | - } |
355 | | - if( $getAllTargets ) { |
356 | | - // return every target or null if no targets due to invalid title or whatever |
357 | | - return ( $targets === array() ) ? null : $targets; |
358 | | - } else { |
359 | | - // return the final destination -- invalid titles are checked earlier |
360 | | - return $title; |
361 | | - } |
| 390 | + return $title; |
362 | 391 | } |
363 | 392 | } |
364 | 393 | return null; |