*/
protected $numRows;
+ protected $cachedTimestamp = null;
+
/**
* Wheter to show prev/next links
*/
- var $shownavigation = true;
+ protected $shownavigation = true;
/**
* A mutator for $this->listoutput;
* join_conds => JOIN conditions
*
* Note that the query itself should return the following three columns:
- * 'namespace', 'title', and 'value'
- * *in that order*. 'value' is used for sorting.
+ * 'namespace', 'title', and 'value'. 'value' is used for sorting.
*
* These may be stored in the querycache table for expensive queries,
* and that cached data will be returned sometimes, so the presence of
function getQueryInfo() {
return null;
}
-
+
/**
* For back-compat, subclasses may return a raw SQL query here, as a string.
* This is stronly deprecated; getQueryInfo() should be overridden instead.
* @return string
- * @deprecated since 1.18
*/
function getSQL() {
+ /* Implement getQueryInfo() instead */
throw new MWException( "Bug in a QueryPage: doesn't implement getQueryInfo() nor getQuery() properly" );
}
* @param $ignoreErrors Boolean: whether to ignore database errors
*/
function recache( $limit, $ignoreErrors = true ) {
+ if ( !$this->isCacheable() ) {
+ return 0;
+ }
+
$fname = get_class( $this ) . '::recache';
$dbw = wfGetDB( DB_MASTER );
$dbr = wfGetDB( DB_SLAVE, array( $this->getName(), __METHOD__, 'vslow' ) );
- if ( !$dbw || !$dbr || !$this->isCacheable() ) {
+ if ( !$dbw || !$dbr ) {
return false;
}
*/
function reallyDoQuery( $limit, $offset = false ) {
$fname = get_class( $this ) . "::reallyDoQuery";
+ $dbr = wfGetDB( DB_SLAVE );
$query = $this->getQueryInfo();
$order = $this->getOrderFields();
if ( $this->sortDescending() ) {
$options['OFFSET'] = intval( $offset );
}
- $dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( $tables, $fields, $conds, $fname,
$options, $join_conds
);
$sql = $this->getSQL();
$sql .= ' ORDER BY ' . implode( ', ', $order );
$sql = $dbr->limitResult( $sql, $limit, $offset );
- $res = $dbr->query( $sql );
+ $res = $dbr->query( $sql, $fname );
}
return $dbr->resultObject( $res );
}
/**
- * Parameters and order changed in 1.18
+ * Somewhat deprecated, you probably want to be using execute()
*/
- function doQuery( $limit, $offset = false ) {
+ function doQuery( $offset = false, $limit = false ) {
if ( $this->isCached() && $this->isCacheable() ) {
return $this->fetchFromCache( $limit, $offset );
} else {
if ( $offset !== false ) {
$options['OFFSET'] = intval( $offset );
}
+ if ( $this->sortDescending() ) {
+ $options['ORDER BY'] = 'qc_value DESC';
+ } else {
+ $options['ORDER BY'] = 'qc_value ASC';
+ }
$res = $dbr->select( 'querycache', array( 'qc_type',
'qc_namespace AS namespace',
'qc_title AS title',
return $dbr->resultObject( $res );
}
+ public function getCachedTimestamp() {
+ if ( !is_null( $this->cachedTimestamp ) ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ $fname = get_class( $this ) . '::getCachedTimestamp';
+ $this->cachedTimestamp = $dbr->selectField( 'querycache_info', 'qci_timestamp',
+ array( 'qci_type' => $this->getName() ), $fname );
+ }
+ return $this->cachedTimestamp;
+ }
+
/**
* This is the actual workhorse. It does everything needed to make a
* real, honest-to-gosh query page.
*/
function execute( $par ) {
- global $wgUser, $wgOut, $wgLang;
-
- if ( !$this->userCanExecute( $wgUser ) ) {
+ if ( !$this->userCanExecute( $this->getUser() ) ) {
$this->displayRestrictionError();
return;
}
- if ( $this->limit == 0 && $this->offset == 0 )
- list( $this->limit, $this->offset ) = wfCheckLimits();
- $sname = $this->getName();
- $fname = get_class( $this ) . '::doQuery';
+ if ( $this->limit == 0 && $this->offset == 0 ) {
+ list( $this->limit, $this->offset ) = $this->getRequest()->getLimitOffset();
+ }
$dbr = wfGetDB( DB_SLAVE );
$this->setHeaders();
- $wgOut->setSyndicated( $this->isSyndicated() );
+ $out = $this->getOutput();
+ $out->setSyndicated( $this->isSyndicated() );
if ( $this->isCached() && !$this->isCacheable() ) {
- $wgOut->setSyndicated( false );
- $wgOut->addWikiMsg( 'querypage-disabled' );
+ $out->setSyndicated( false );
+ $out->addWikiMsg( 'querypage-disabled' );
return 0;
}
if ( !$this->listoutput ) {
# Fetch the timestamp of this update
- $tRes = $dbr->select( 'querycache_info', array( 'qci_timestamp' ), array( 'qci_type' => $sname ), $fname );
- $tRow = $dbr->fetchObject( $tRes );
-
- if ( $tRow ) {
- $updated = $wgLang->timeanddate( $tRow->qci_timestamp, true, true );
- $updateddate = $wgLang->date( $tRow->qci_timestamp, true, true );
- $updatedtime = $wgLang->time( $tRow->qci_timestamp, true, true );
- $wgOut->addMeta( 'Data-Cache-Time', $tRow->qci_timestamp );
- $wgOut->addInlineScript( "var dataCacheTime = '{$tRow->qci_timestamp}';" );
- $wgOut->addWikiMsg( 'perfcachedts', $updated, $updateddate, $updatedtime );
+ $ts = $this->getCachedTimestamp();
+
+ if ( $ts ) {
+ $lang = $this->getLang();
+ $updated = $lang->timeanddate( $ts, true, true );
+ $updateddate = $lang->date( $ts, true, true );
+ $updatedtime = $lang->time( $ts, true, true );
+ $out->addMeta( 'Data-Cache-Time', $ts );
+ $out->addInlineScript( "var dataCacheTime = '$ts';" );
+ $out->addWikiMsg( 'perfcachedts', $updated, $updateddate, $updatedtime );
} else {
- $wgOut->addWikiMsg( 'perfcached' );
+ $out->addWikiMsg( 'perfcached' );
}
# If updates on this page have been disabled, let the user know
# that the data set won't be refreshed for now
global $wgDisableQueryPageUpdate;
if ( is_array( $wgDisableQueryPageUpdate ) && in_array( $this->getName(), $wgDisableQueryPageUpdate ) ) {
- $wgOut->addWikiMsg( 'querypage-no-updates' );
+ $out->addWikiMsg( 'querypage-no-updates' );
}
}
$this->preprocessResults( $dbr, $res );
- $wgOut->addHTML( Xml::openElement( 'div', array( 'class' => 'mw-spcontent' ) ) );
+ $out->addHTML( Xml::openElement( 'div', array( 'class' => 'mw-spcontent' ) ) );
# Top header and navigation
if ( $this->shownavigation ) {
- $wgOut->addHTML( $this->getPageHeader() );
+ $out->addHTML( $this->getPageHeader() );
if ( $this->numRows > 0 ) {
- $wgOut->addHTML( '<p>' . wfShowingResults( $this->offset, $this->numRows ) . '</p>' );
+ $out->addHTML( '<p>' . wfShowingResults( $this->offset, $this->numRows ) . '</p>' );
# Disable the "next" link when we reach the end
$paging = wfViewPrevNext( $this->offset, $this->limit,
$this->getTitle( $par ),
wfArrayToCGI( $this->linkParameters() ), ( $this->numRows < $this->limit ) );
- $wgOut->addHTML( '<p>' . $paging . '</p>' );
+ $out->addHTML( '<p>' . $paging . '</p>' );
} else {
# No results to show, so don't bother with "showing X of Y" etc.
# -- just let the user know and give up now
- $wgOut->addHTML( '<p>' . wfMsgHtml( 'specialpage-empty' ) . '</p>' );
- $wgOut->addHTML( Xml::closeElement( 'div' ) );
+ $out->addHTML( '<p>' . wfMsgHtml( 'specialpage-empty' ) . '</p>' );
+ $out->addHTML( Xml::closeElement( 'div' ) );
return;
}
}
# The actual results; specialist subclasses will want to handle this
# with more than a straight list, so we hand them the info, plus
# an OutputPage, and let them get on with it
- $this->outputResults( $wgOut,
- $wgUser->getSkin(),
+ $this->outputResults( $out,
+ $this->getSkin(),
$dbr, # Should use a ResultWrapper for this
$res,
$this->numRows,
# Repeat the paging links at the bottom
if ( $this->shownavigation ) {
- $wgOut->addHTML( '<p>' . $paging . '</p>' );
+ $out->addHTML( '<p>' . $paging . '</p>' );
}
- $wgOut->addHTML( Xml::closeElement( 'div' ) );
+ $out->addHTML( Xml::closeElement( 'div' ) );
return $this->numRows;
}
if ( $num > 0 ) {
$html = array();
- if ( !$this->listoutput )
+ if ( !$this->listoutput ) {
$html[] = $this->openList( $offset );
+ }
# $res might contain the whole 1,000 rows, so we read up to
# $num [should update this to use a Pager]
}
}
- if ( !$this->listoutput )
+ if ( !$this->listoutput ) {
$html[] = $this->closeList();
+ }
$html = $this->listoutput
? $wgContLang->listToText( $html )
global $wgFeed, $wgFeedClasses;
if ( !$wgFeed ) {
- global $wgOut;
- $wgOut->addWikiMsg( 'feed-unavailable' );
+ $this->getOutput()->addWikiMsg( 'feed-unavailable' );
return;
}
$this->feedUrl() );
$feed->outHeader();
- $dbr = wfGetDB( DB_SLAVE );
$res = $this->reallyDoQuery( $limit, 0 );
foreach ( $res as $obj ) {
$item = $this->feedResult( $obj );
function feedTitle() {
global $wgLanguageCode, $wgSitename;
- $page = SpecialPage::getPage( $this->getName() );
- $desc = $page->getDescription();
+ $desc = $this->getDescription();
return "$wgSitename - $desc [$wgLanguageCode]";
}
}
function feedUrl() {
- $title = SpecialPage::getTitleFor( $this->getName() );
- return $title->getFullURL();
+ return $this->getTitle()->getFullURL();
}
}
* @return string
*/
private function makeWlhLink( $title, $skin, $result ) {
- global $wgLang;
$wlh = SpecialPage::getTitleFor( 'Whatlinkshere' );
$label = wfMsgExt( 'nlinks', array( 'parsemag', 'escape' ),
- $wgLang->formatNum( $result->value ) );
+ $this->getLang()->formatNum( $result->value ) );
return $skin->link( $wlh, $label, array(), array( 'target' => $title->getPrefixedText() ) );
}
}