X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSpecialWhatlinkshere.php;h=881510c9a8be54787904a8ae7d91172e75e39e5b;hb=114fb4e555eb4e4fb2c8e131a3e2e754bc36f9b9;hp=087b517cebb82e204ccbb526c72a1b2511f61726;hpb=69e546c19c017cd268ede1ed1fc679394b37357b;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialWhatlinkshere.php b/includes/SpecialWhatlinkshere.php index 087b517ceb..881510c9a8 100644 --- a/includes/SpecialWhatlinkshere.php +++ b/includes/SpecialWhatlinkshere.php @@ -1,8 +1,7 @@ execute(); +} - $target = isset($par) ? $par : $wgRequest->getVal( 'target' ); - list( $limit, $offset ) = $wgRequest->getLimitOffset(); +/** + * implements Special:Whatlinkshere + * @addtogroup SpecialPage + */ +class WhatLinksHerePage { + var $request, $par; + var $limit, $from, $back, $target; + var $selfTitle, $skin; - if (is_null($target)) { - $wgOut->errorpage( 'notargettitle', 'notargettext' ); - return; - } + private $namespace; - $nt = Title::newFromURL( $target ); - if( !$nt ) { - $wgOut->errorpage( 'notargettitle', 'notargettext' ); - return; + function WhatLinksHerePage( &$request, $par = null ) { + global $wgUser; + $this->request =& $request; + $this->skin = $wgUser->getSkin(); + $this->par = $par; } - $wgOut->setPagetitle( $nt->getPrefixedText() ); - $wgOut->setSubtitle( wfMsg( 'linklistsub' ) ); - $sk = $wgUser->getSkin(); - $isredir = ' (' . wfMsg( 'isredirect' ) . ")\n"; + function execute() { + global $wgOut; - $wgOut->addHTML('< '.$sk->makeLinkObj($nt, '', 'redirect=no' )."
\n"); + $this->limit = min( $this->request->getInt( 'limit', 50 ), 5000 ); + if ( $this->limit <= 0 ) { + $this->limit = 50; + } + $this->from = $this->request->getInt( 'from' ); + $this->back = $this->request->getInt( 'back' ); - wfShowIndirectLinks( 0, $nt, $limit, $offset ); -} + $targetString = isset($this->par) ? $this->par : $this->request->getVal( 'target' ); -/** - * @param int $level - * @param Title $target - * @param int $limit - * @param int $offset - * @access private - */ -function wfShowIndirectLinks( $level, $target, $limit, $offset = 0 ) { - global $wgOut, $wgUser; - $fname = 'wfShowIndirectLinks'; - - $dbr =& wfGetDB( DB_READ ); - - // Read one extra row as an at-end check - $queryLimit = $limit + 1; - $limitSql = ( $level == 0 ) - ? "$offset,$queryLimit" - : $queryLimit; - - $res = $dbr->select( array( 'pagelinks', 'page' ), - array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ), - array( - 'pl_from=page_id', - 'pl_namespace' => $target->getNamespace(), - 'pl_title' => $target->getDbKey() ), - $fname, - array( 'LIMIT' => $limitSql ) ); + if ( is_null( $targetString ) ) { + $wgOut->addHTML( $this->whatlinkshereForm() ); + return; + } - if ( 0 == $dbr->numRows( $res ) ) { - if ( 0 == $level ) { - $wgOut->addWikiText( wfMsg( 'nolinkshere' ) ); + $this->target = Title::newFromURL( $targetString ); + if( !$this->target ) { + $wgOut->addHTML( $this->whatlinkshereForm() ); + return; } - return; - } - if ( 0 == $level ) { - $wgOut->addWikiText( wfMsg( 'linkshere' ) ); + $this->selfTitle = Title::makeTitleSafe( NS_SPECIAL, + 'Whatlinkshere/' . $this->target->getPrefixedDBkey() ); + + $wgOut->setPageTitle( wfMsg( 'whatlinkshere-title', $this->target->getPrefixedText() ) ); + $wgOut->setSubtitle( wfMsg( 'linklistsub' ) ); + + $wgOut->addHTML( wfMsg( 'whatlinkshere-barrow' ) . ' ' .$this->skin->makeLinkObj($this->target, '', 'redirect=no' )."
\n"); + + $this->showIndirectLinks( 0, $this->target, $this->limit, $this->from, $this->back ); } - $sk = $wgUser->getSkin(); - $isredir = ' (' . wfMsg( 'isredirect' ) . ")\n"; - if( $dbr->numRows( $res ) == 0 ) { - return; + /** + * @param int $level Recursion level + * @param Title $target Target title + * @param int $limit Number of entries to display + * @param Title $from Display from this article ID + * @param Title $back Display from this article ID at backwards scrolling + * @private + */ + function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) { + global $wgOut; + $fname = 'WhatLinksHerePage::showIndirectLinks'; + $dbr = wfGetDB( DB_READ ); + $options = array(); + + $ns = $this->request->getIntOrNull( 'namespace' ); + if ( isset( $ns ) ) { + $options['namespace'] = $ns; + $this->setNamespace( $options['namespace'] ); + } else { + $options['namespace'] = ''; + } + + // Make the query + $plConds = array( + 'page_id=pl_from', + 'pl_namespace' => $target->getNamespace(), + 'pl_title' => $target->getDBkey(), + ); + + $tlConds = array( + 'page_id=tl_from', + 'tl_namespace' => $target->getNamespace(), + 'tl_title' => $target->getDBkey(), + ); + + if ( $this->namespace !== null ){ + $plConds['page_namespace'] = (int)$this->namespace; + $tlConds['page_namespace'] = (int)$this->namespace; + } + + if ( $from ) { + $from = (int)$from; // just in case + $tlConds[] = "tl_from >= $from"; + $plConds[] = "pl_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', 'page_is_redirect' ); + + $options['ORDER BY'] = 'pl_from'; + $plRes = $dbr->select( array( 'pagelinks', 'page' ), $fields, + $plConds, $fname, $options ); + + $options['ORDER BY'] = 'tl_from'; + $tlRes = $dbr->select( array( 'templatelinks', 'page' ), $fields, + $tlConds, $fname, $options ); + + if ( !$dbr->numRows( $plRes ) && !$dbr->numRows( $tlRes ) ) { + if ( 0 == $level ) { + $options = array(); // reinitialize for a further namespace search + // really no links to here + $options['namespace'] = $this->namespace; + $options['target'] = $this->target->getPrefixedText(); + list( $options['limit'], $options['offset']) = wfCheckLimits(); + $wgOut->addHTML( $this->whatlinkshereForm( $options ) ); + $errMsg = isset( $this->namespace ) ? 'nolinkshere-ns' : 'nolinkshere'; + $wgOut->addWikiText( wfMsg( $errMsg, $this->target->getPrefixedText() ) ); + } + return; + } + + $options = array(); + list( $options['limit'], $options['offset']) = wfCheckLimits(); + if ( ( $ns = $this->request->getVal( 'namespace', null ) ) !== null && $ns !== '' && ctype_digit($ns) ) { + $options['namespace'] = intval( $ns ); + $this->setNamespace( $options['namespace'] ); + } else { + $options['namespace'] = ''; + $this->setNamespace( null ); + } + $options['offset'] = $this->request->getVal( 'offset' ); + /* Offset must be an integral. */ + if ( !strlen( $options['offset'] ) || !preg_match( '/^[0-9]+$/', $options['offset'] ) ) + $options['offset'] = ''; + $options['target'] = $this->target->getPrefixedText(); + + // Read the rows into an array and remove duplicates + // templatelinks comes second so that the templatelinks row overwrites the + // pagelinks row, so we get (inclusion) rather than nothing + while ( $row = $dbr->fetchObject( $plRes ) ) { + $row->is_template = 0; + $rows[$row->page_id] = $row; + } + $dbr->freeResult( $plRes ); + while ( $row = $dbr->fetchObject( $tlRes ) ) { + $row->is_template = 1; + $rows[$row->page_id] = $row; + } + $dbr->freeResult( $tlRes ); + + // Sort by key and then change the keys to 0-based indices + ksort( $rows ); + $rows = array_values( $rows ); + + $numRows = count( $rows ); + + // Work out the start and end IDs, for prev/next links + if ( $numRows > $limit ) { + // More rows available after these ones + // Get the ID from the last row in the result set + $nextId = $rows[$limit]->page_id; + // Remove undisplayed rows + $rows = array_slice( $rows, 0, $limit ); + } else { + // No more rows after + $nextId = false; + } + $prevId = $from; + + if ( $level == 0 ) { + $wgOut->addHTML( $this->whatlinkshereForm( $options ) ); + $wgOut->addWikiText( wfMsg( 'linkshere', $this->target->getPrefixedText() ) ); + } + $isredir = wfMsg( 'isredirect' ); + $istemplate = wfMsg( 'istemplate' ); + + if( $level == 0 ) { + $prevnext = $this->getPrevNext( $limit, $prevId, $nextId, $options['namespace'] ); + $wgOut->addHTML( $prevnext ); + } + + $wgOut->addHTML( '\n" ); + + if( $level == 0 ) { + $wgOut->addHTML( $prevnext ); + } } - $atend = ( $dbr->numRows( $res ) <= $limit ); - - if( $level == 0 ) { - $specialTitle = Title::makeTitle( NS_SPECIAL, 'Whatlinkshere' ); - $prevnext = wfViewPrevNext( $offset, $limit, $specialTitle, - 'target=' . urlencode( $target->getPrefixedDbKey() ), - $atend ); - $wgOut->addHTML( $prevnext ); + + function makeSelfLink( $text, $query ) { + return $this->skin->makeKnownLinkObj( $this->selfTitle, $text, $query ); } - - $wgOut->addHTML( '\n" ); - - if( $level == 0 ) { - $wgOut->addHTML( $prevnext ); + + /** Set the namespace we are filtering on */ + private function setNamespace( $ns ) { + $this->namespace = $ns; } -} -?> +}