From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- includes/specials/SpecialWhatlinkshere.php | 216 ++++++++++++++++------------- 1 file changed, 119 insertions(+), 97 deletions(-) (limited to 'includes/specials/SpecialWhatlinkshere.php') diff --git a/includes/specials/SpecialWhatlinkshere.php b/includes/specials/SpecialWhatlinkshere.php index 05c7dd5f..7dc6da1f 100644 --- a/includes/specials/SpecialWhatlinkshere.php +++ b/includes/specials/SpecialWhatlinkshere.php @@ -26,18 +26,13 @@ * * @ingroup SpecialPage */ -class SpecialWhatLinksHere extends SpecialPage { - - /** - * @var FormOptions - */ +class SpecialWhatLinksHere extends IncludableSpecialPage { + /** @var FormOptions */ protected $opts; protected $selfTitle; - /** - * @var Title - */ + /** @var Title */ protected $target; protected $limits = array( 20, 50, 100, 250, 500 ); @@ -47,7 +42,6 @@ class SpecialWhatLinksHere extends SpecialPage { } function execute( $par ) { - global $wgQueryPageDefaultLimit; $out = $this->getOutput(); $this->setHeaders(); @@ -57,7 +51,7 @@ class SpecialWhatLinksHere extends SpecialPage { $opts->add( 'target', '' ); $opts->add( 'namespace', '', FormOptions::INTNULL ); - $opts->add( 'limit', $wgQueryPageDefaultLimit ); + $opts->add( 'limit', $this->getConfig()->get( 'QueryPageDefaultLimit' ) ); $opts->add( 'from', 0 ); $opts->add( 'back', 0 ); $opts->add( 'hideredirs', false ); @@ -69,7 +63,7 @@ class SpecialWhatLinksHere extends SpecialPage { $opts->validateIntBounds( 'limit', 0, 5000 ); // Give precedence to subpage syntax - if ( isset( $par ) ) { + if ( $par !== null ) { $opts->setValue( 'target', $par ); } @@ -79,18 +73,23 @@ class SpecialWhatLinksHere extends SpecialPage { $this->target = Title::newFromURL( $opts->getValue( 'target' ) ); if ( !$this->target ) { $out->addHTML( $this->whatlinkshereForm() ); + return; } $this->getSkin()->setRelevantTitle( $this->target ); - $this->selfTitle = $this->getTitle( $this->target->getPrefixedDBkey() ); + $this->selfTitle = $this->getPageTitle( $this->target->getPrefixedDBkey() ); $out->setPageTitle( $this->msg( 'whatlinkshere-title', $this->target->getPrefixedText() ) ); $out->addBacklinkSubtitle( $this->target ); - - $this->showIndirectLinks( 0, $this->target, $opts->getValue( 'limit' ), - $opts->getValue( 'from' ), $opts->getValue( 'back' ) ); + $this->showIndirectLinks( + 0, + $this->target, + $opts->getValue( 'limit' ), + $opts->getValue( 'from' ), + $opts->getValue( 'back' ) + ); } /** @@ -101,10 +100,8 @@ class SpecialWhatLinksHere extends SpecialPage { * @param int $back Display from this article ID at backwards scrolling (default: 0) */ function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) { - global $wgMaxRedirectLinksRetrieved; $out = $this->getOutput(); $dbr = wfGetDB( DB_SLAVE ); - $options = array(); $hidelinks = $this->opts->getValue( 'hidelinks' ); $hideredirs = $this->opts->getValue( 'hideredirs' ); @@ -113,95 +110,108 @@ class SpecialWhatLinksHere extends SpecialPage { $fetchlinks = ( !$hidelinks || !$hideredirs ); - // Make the query - $plConds = array( - 'page_id=pl_from', + // Build query conds in concert for all three tables... + $conds['pagelinks'] = array( 'pl_namespace' => $target->getNamespace(), 'pl_title' => $target->getDBkey(), ); - if ( $hideredirs ) { - $plConds['rd_from'] = null; - } elseif ( $hidelinks ) { - $plConds[] = 'rd_from is NOT NULL'; - } - - $tlConds = array( - 'page_id=tl_from', + $conds['templatelinks'] = array( 'tl_namespace' => $target->getNamespace(), 'tl_title' => $target->getDBkey(), ); - - $ilConds = array( - 'page_id=il_from', + $conds['imagelinks'] = array( 'il_to' => $target->getDBkey(), ); + $useLinkNamespaceDBFields = $this->getConfig()->get( 'UseLinkNamespaceDBFields' ); $namespace = $this->opts->getValue( 'namespace' ); if ( is_int( $namespace ) ) { - $plConds['page_namespace'] = $namespace; - $tlConds['page_namespace'] = $namespace; - $ilConds['page_namespace'] = $namespace; + if ( $useLinkNamespaceDBFields ) { + $conds['pagelinks']['pl_from_namespace'] = $namespace; + $conds['templatelinks']['tl_from_namespace'] = $namespace; + $conds['imagelinks']['il_from_namespace'] = $namespace; + } else { + $conds['pagelinks']['page_namespace'] = $namespace; + $conds['templatelinks']['page_namespace'] = $namespace; + $conds['imagelinks']['page_namespace'] = $namespace; + } } if ( $from ) { - $tlConds[] = "tl_from >= $from"; - $plConds[] = "pl_from >= $from"; - $ilConds[] = "il_from >= $from"; + $conds['templatelinks'][] = "tl_from >= $from"; + $conds['pagelinks'][] = "pl_from >= $from"; + $conds['imagelinks'][] = "il_from >= $from"; } - // Read an extra row as an at-end check - $queryLimit = $limit + 1; - - // Enforce join order, sometimes namespace selector may - // trigger filesorts which are far less efficient than scanning many entries - $options[] = 'STRAIGHT_JOIN'; - - $options['LIMIT'] = $queryLimit; - $fields = array( 'page_id', 'page_namespace', 'page_title', 'rd_from' ); + if ( $hideredirs ) { + $conds['pagelinks']['rd_from'] = null; + } elseif ( $hidelinks ) { + $conds['pagelinks'][] = 'rd_from is NOT NULL'; + } - $joinConds = array( 'redirect' => array( 'LEFT JOIN', array( - 'rd_from = page_id', - 'rd_namespace' => $target->getNamespace(), - 'rd_title' => $target->getDBkey(), - 'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL' - ))); + $queryFunc = function ( $dbr, $table, $fromCol ) use ( $conds, $target, $limit, $useLinkNamespaceDBFields ) { + // Read an extra row as an at-end check + $queryLimit = $limit + 1; + $on = array( + "rd_from = $fromCol", + 'rd_title' => $target->getDBkey(), + 'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL' + ); + if ( $useLinkNamespaceDBFields ) { // migration check + $on['rd_namespace'] = $target->getNamespace(); + } + // Inner LIMIT is 2X in case of stale backlinks with wrong namespaces + $subQuery = $dbr->selectSqlText( + array( $table, 'page', 'redirect' ), + array( $fromCol, 'rd_from' ), + $conds[$table], + __CLASS__ . '::showIndirectLinks', + array( 'ORDER BY' => $fromCol, 'LIMIT' => 2 * $queryLimit ), + array( + 'page' => array( 'INNER JOIN', "$fromCol = page_id" ), + 'redirect' => array( 'LEFT JOIN', $on ) + ) + ); + return $dbr->select( + array( 'page', 'temp_backlink_range' => "($subQuery)" ), + array( 'page_id', 'page_namespace', 'page_title', 'rd_from' ), + array(), + __CLASS__ . '::showIndirectLinks', + array( 'ORDER BY' => 'page_id', 'LIMIT' => $queryLimit ), + array( 'page' => array( 'INNER JOIN', "$fromCol = page_id" ) ) + ); + }; if ( $fetchlinks ) { - $options['ORDER BY'] = 'pl_from'; - $plRes = $dbr->select( array( 'pagelinks', 'page', 'redirect' ), $fields, - $plConds, __METHOD__, $options, - $joinConds - ); + $plRes = $queryFunc( $dbr, 'pagelinks', 'pl_from' ); } if ( !$hidetrans ) { - $options['ORDER BY'] = 'tl_from'; - $tlRes = $dbr->select( array( 'templatelinks', 'page', 'redirect' ), $fields, - $tlConds, __METHOD__, $options, - $joinConds - ); + $tlRes = $queryFunc( $dbr, 'templatelinks', 'tl_from' ); } if ( !$hideimages ) { - $options['ORDER BY'] = 'il_from'; - $ilRes = $dbr->select( array( 'imagelinks', 'page', 'redirect' ), $fields, - $ilConds, __METHOD__, $options, - $joinConds - ); + $ilRes = $queryFunc( $dbr, 'imagelinks', 'il_from' ); } - if ( ( !$fetchlinks || !$plRes->numRows() ) && ( $hidetrans || !$tlRes->numRows() ) && ( $hideimages || !$ilRes->numRows() ) ) { + if ( ( !$fetchlinks || !$plRes->numRows() ) + && ( $hidetrans || !$tlRes->numRows() ) + && ( $hideimages || !$ilRes->numRows() ) + ) { if ( 0 == $level ) { - $out->addHTML( $this->whatlinkshereForm() ); - - // Show filters only if there are links - if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) { - $out->addHTML( $this->getFilterPanel() ); + if ( !$this->including() ) { + $out->addHTML( $this->whatlinkshereForm() ); + + // Show filters only if there are links + if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) { + $out->addHTML( $this->getFilterPanel() ); + } + $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere'; + $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() ); + $out->setStatusCode( 404 ); } - - $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere'; - $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() ); } + return; } @@ -250,31 +260,34 @@ class SpecialWhatLinksHere extends SpecialPage { $prevId = $from; if ( $level == 0 ) { - $out->addHTML( $this->whatlinkshereForm() ); - $out->addHTML( $this->getFilterPanel() ); - $out->addWikiMsg( 'linkshere', $this->target->getPrefixedText() ); + if ( !$this->including() ) { + $out->addHTML( $this->whatlinkshereForm() ); + $out->addHTML( $this->getFilterPanel() ); + $out->addWikiMsg( 'linkshere', $this->target->getPrefixedText() ); - $prevnext = $this->getPrevNext( $prevId, $nextId ); - $out->addHTML( $prevnext ); + $prevnext = $this->getPrevNext( $prevId, $nextId ); + $out->addHTML( $prevnext ); + } } - $out->addHTML( $this->listStart( $level ) ); foreach ( $rows as $row ) { $nt = Title::makeTitle( $row->page_namespace, $row->page_title ); if ( $row->rd_from && $level < 2 ) { - $out->addHTML( $this->listItem( $row, $nt, true ) ); - $this->showIndirectLinks( $level + 1, $nt, $wgMaxRedirectLinksRetrieved ); + $out->addHTML( $this->listItem( $row, $nt, $target, true ) ); + $this->showIndirectLinks( $level + 1, $nt, $this->getConfig()->get( 'MaxRedirectLinksRetrieved' ) ); $out->addHTML( Xml::closeElement( 'li' ) ); } else { - $out->addHTML( $this->listItem( $row, $nt ) ); + $out->addHTML( $this->listItem( $row, $nt, $target ) ); } } $out->addHTML( $this->listEnd() ); if ( $level == 0 ) { - $out->addHTML( $prevnext ); + if ( !$this->including() ) { + $out->addHTML( $prevnext ); + } } } @@ -282,7 +295,7 @@ class SpecialWhatLinksHere extends SpecialPage { return Xml::openElement( 'ul', ( $level ? array() : array( 'id' => 'mw-whatlinkshere-list' ) ) ); } - protected function listItem( $row, $nt, $notClose = false ) { + protected function listItem( $row, $nt, $target, $notClose = false ) { $dirmark = $this->getLanguage()->getDirMark(); # local message cache @@ -322,13 +335,19 @@ class SpecialWhatLinksHere extends SpecialPage { $props[] = $msgcache['isimage']; } + wfRunHooks( 'WhatLinksHereProps', array( $row, $nt, $target, &$props ) ); + if ( count( $props ) ) { - $propsText = $this->msg( 'parentheses' )->rawParams( implode( $msgcache['semicolon-separator'], $props ) )->escaped(); + $propsText = $this->msg( 'parentheses' ) + ->rawParams( implode( $msgcache['semicolon-separator'], $props ) )->escaped(); } # Space for utilities links, with a what-links-here link provided $wlhLink = $this->wlhLink( $nt, $msgcache['whatlinkshere-links'] ); - $wlh = Xml::wrapClass( $this->msg( 'parentheses' )->rawParams( $wlhLink )->escaped(), 'mw-whatlinkshere-tools' ); + $wlh = Xml::wrapClass( + $this->msg( 'parentheses' )->rawParams( $wlhLink )->escaped(), + 'mw-whatlinkshere-tools' + ); return $notClose ? Xml::openElement( 'li' ) . "$link $propsText $dirmark $wlh\n" : @@ -342,7 +361,7 @@ class SpecialWhatLinksHere extends SpecialPage { protected function wlhLink( Title $target, $text ) { static $title = null; if ( $title === null ) { - $title = $this->getTitle(); + $title = $this->getPageTitle(); } return Linker::linkKnown( @@ -393,8 +412,6 @@ class SpecialWhatLinksHere extends SpecialPage { } function whatlinkshereForm() { - global $wgScript; - // We get nicer value from the title object $this->opts->consumeValue( 'target' ); // Reset these for new requests @@ -404,10 +421,10 @@ class SpecialWhatLinksHere extends SpecialPage { $namespace = $this->opts->consumeValue( 'namespace' ); # Build up the form - $f = Xml::openElement( 'form', array( 'action' => $wgScript ) ); + $f = Xml::openElement( 'form', array( 'action' => wfScript() ) ); # Values that should not be forgotten - $f .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() ); + $f .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ); foreach ( $this->opts->getUnconsumedValues() as $name => $value ) { $f .= Html::hidden( $name, $value ); } @@ -416,7 +433,7 @@ class SpecialWhatLinksHere extends SpecialPage { # Target input $f .= Xml::inputLabel( $this->msg( 'whatlinkshere-page' )->text(), 'target', - 'mw-whatlinkshere-target', 40, $target ); + 'mw-whatlinkshere-target', 40, $target ); $f .= ' '; @@ -462,7 +479,8 @@ class SpecialWhatLinksHere extends SpecialPage { $types[] = 'hideimages'; } - // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans', 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages' + // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans', + // 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages' // To be sure they will be found by grep foreach ( $types as $type ) { $chosen = $this->opts->getValue( $type ); @@ -471,7 +489,11 @@ class SpecialWhatLinksHere extends SpecialPage { $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams( $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped(); } - return Xml::fieldset( $this->msg( 'whatlinkshere-filters' )->text(), $this->getLanguage()->pipeList( $links ) ); + + return Xml::fieldset( + $this->msg( 'whatlinkshere-filters' )->text(), + $this->getLanguage()->pipeList( $links ) + ); } protected function getGroupName() { -- cgit v1.2.3-54-g00ecf