Merge "(bug 43942) Skip screen sheets with media queries when printing"
[lhc/web/wiklou.git] / includes / specials / SpecialDoubleRedirects.php
index 566f8f6..ee07323 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 /**
+ * Implements Special:DoubleRedirects
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
  */
 
 /**
  * A special page listing redirects to redirecting page.
  * The software will automatically not follow double redirects, to prevent loops.
  *
- * @file
  * @ingroup SpecialPage
  */
-class DoubleRedirectsPage extends PageQueryPage {
+class DoubleRedirectsPage extends QueryPage {
 
-       function getName() {
-               return 'DoubleRedirects';
+       function __construct( $name = 'DoubleRedirects' ) {
+               parent::__construct( $name );
        }
 
-       function isExpensive( ) { return true; }
-       function isSyndicated() { return false; }
+       function isExpensive() {
+               return true;
+       }
 
-       function getPageHeader( ) {
-               return wfMsgExt( 'doubleredirectstext', array( 'parse' ) );
+       function isSyndicated() {
+               return false;
        }
 
-       function getSQLText( &$dbr, $namespace = null, $title = null ) {
+       function sortDescending() {
+               return false;
+       }
 
-               list( $page, $redirect ) = $dbr->tableNamesN( 'page', 'redirect' );
+       function getPageHeader() {
+               return $this->msg( 'doubleredirectstext' )->parseAsBlock();
+       }
 
+       function reallyGetQueryInfo( $namespace = null, $title = null ) {
                $limitToTitle = !( $namespace === null && $title === null );
-               $sql = $limitToTitle ? "SELECT" : "SELECT 'DoubleRedirects' as type," ;
-               $sql .=
-                        " pa.page_namespace as namespace, pa.page_title as title," .
-                        " pb.page_namespace as nsb, pb.page_title as tb," .
-                        " pc.page_namespace as nsc, pc.page_title as tc" .
-                  " FROM $redirect AS ra, $redirect AS rb, $page AS pa, $page AS pb, $page AS pc" .
-                  " WHERE ra.rd_from=pa.page_id" .
-                        " AND ra.rd_namespace=pb.page_namespace" .
-                        " AND ra.rd_title=pb.page_title" .
-                        " AND rb.rd_from=pb.page_id" .
-                        " AND rb.rd_namespace=pc.page_namespace" .
-                        " AND rb.rd_title=pc.page_title";
-
-               if( $limitToTitle ) {
-                       $encTitle = $dbr->addQuotes( $title );
-                       $sql .= " AND pa.page_namespace=$namespace" .
-                                       " AND pa.page_title=$encTitle";
+               $retval = array (
+                       'tables' => array (
+                               'ra' => 'redirect',
+                               'rb' => 'redirect',
+                               'pa' => 'page',
+                               'pb' => 'page'
+                       ),
+                       'fields' => array(
+                               'namespace' => 'pa.page_namespace',
+                               'title' => 'pa.page_title',
+                               'value' => 'pa.page_title',
+
+                               'nsb' => 'pb.page_namespace',
+                               'tb' => 'pb.page_title',
+
+                               // Select fields from redirect instead of page. Because there may
+                               // not actually be a page table row for this target (e.g. for interwiki redirects)
+                               'nsc' => 'rb.rd_namespace',
+                               'tc' => 'rb.rd_title',
+                               'iwc' => 'rb.rd_interwiki',
+                       ),
+                       'conds' => array(
+                               'ra.rd_from = pa.page_id',
+
+                               // Filter out redirects where the target goes interwiki (bug 40353).
+                               // This isn't an optimization, it is required for correct results,
+                               // otherwise a non-double redirect like Bar -> w:Foo will show up
+                               // like "Bar -> Foo -> w:Foo".
+
+                               // Need to check both NULL and "" for some reason,
+                               // apparently either can be stored for non-iw entries.
+                               '(ra.rd_interwiki IS NULL OR ra.rd_interwiki = "")',
+
+                               'pb.page_namespace = ra.rd_namespace',
+                               'pb.page_title = ra.rd_title',
+
+                               'rb.rd_from = pb.page_id',
+                       )
+               );
+               if ( $limitToTitle ) {
+                       $retval['conds']['pa.page_namespace'] = $namespace;
+                       $retval['conds']['pa.page_title'] = $title;
                }
-
-               return $sql;
+               return $retval;
        }
 
-       function getSQL() {
-               $dbr = wfGetDB( DB_SLAVE );
-               return $this->getSQLText( $dbr );
+       function getQueryInfo() {
+               return $this->reallyGetQueryInfo();
        }
 
-       function getOrder() {
-               return '';
+       function getOrderFields() {
+               return array ( 'ra.rd_namespace', 'ra.rd_title' );
        }
 
        function formatResult( $skin, $result ) {
-               global $wgContLang;
-
-               $fname = 'DoubleRedirectsPage::formatResult';
                $titleA = Title::makeTitle( $result->namespace, $result->title );
 
+               // If only titleA is in the query, it means this came from
+               // querycache (which only saves 3 columns).
+               // That does save the bulk of the query cost, but now we need to
+               // get a little more detail about each individual entry quickly
+               // using the filter of reallyGetQueryInfo.
                if ( $result && !isset( $result->nsb ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $sql = $this->getSQLText( $dbr, $result->namespace, $result->title );
-                       $res = $dbr->query( $sql, $fname );
+                       $qi = $this->reallyGetQueryInfo( $result->namespace,
+                                       $result->title );
+                       $res = $dbr->select($qi['tables'], $qi['fields'],
+                                       $qi['conds'], __METHOD__ );
                        if ( $res ) {
                                $result = $dbr->fetchObject( $res );
-                               $dbr->freeResult( $res );
                        }
                }
                if ( !$result ) {
-                       return '<del>' . $skin->link( $titleA, null, array(), array( 'redirect' => 'no' ) ) . '</del>';
+                       return '<del>' . Linker::link( $titleA, null, array(), array( 'redirect' => 'no' ) ) . '</del>';
                }
 
                $titleB = Title::makeTitle( $result->nsb, $result->tb );
-               $titleC = Title::makeTitle( $result->nsc, $result->tc );
+               $titleC = Title::makeTitle( $result->nsc, $result->tc, '',  $result->iwc );
 
-               $linkA = $skin->linkKnown(
+               $linkA = Linker::linkKnown(
                        $titleA,
                        null,
                        array(),
                        array( 'redirect' => 'no' )
                );
-               $edit = $skin->linkKnown(
+
+               $edit = Linker::linkKnown(
                        $titleA,
-                       wfMsgExt( 'parentheses', array( 'escape' ), wfMsg( 'editlink' ) ),
+                       $this->msg( 'parentheses', $this->msg( 'editlink' )->text() )->escaped(),
                        array(),
                        array(
                                'redirect' => 'no',
                                'action' => 'edit'
                        )
                );
-               $linkB = $skin->linkKnown(
+
+               $linkB = Linker::linkKnown(
                        $titleB,
                        null,
                        array(),
                        array( 'redirect' => 'no' )
                );
-               $linkC = $skin->linkKnown( $titleC );
-               $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
 
-               return( "{$linkA} {$edit} {$arr} {$linkB} {$arr} {$linkC}" );
-       }
-}
+               $linkC = Linker::linkKnown( $titleC );
 
-/**
- * constructor
- */
-function wfSpecialDoubleRedirects() {
-       list( $limit, $offset ) = wfCheckLimits();
-
-       $sdr = new DoubleRedirectsPage();
-
-       return $sdr->doQuery( $offset, $limit );
+               $lang = $this->getLanguage();
+               $arr = $lang->getArrow() . $lang->getDirMark();
 
+               return( "{$linkA} {$edit} {$arr} {$linkB} {$arr} {$linkC}" );
+       }
 }