From eb7d060fd6dc49838d90730be82a81b8191e9c1f Mon Sep 17 00:00:00 2001 From: Bryan Tong Minh Date: Sun, 12 Jul 2009 21:16:58 +0000 Subject: [PATCH] Refactored the querying code out of the display code, to allow a future API module for query pages. No user visible changes. --- includes/QueryPage.php | 150 +++++++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 51 deletions(-) diff --git a/includes/QueryPage.php b/includes/QueryPage.php index 86a988e987..a8abee3385 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -172,6 +172,18 @@ class QueryPage { function formatResult( $skin, $result ) { return ''; } + /** + * Formats the result as something that can be understood by the API. + * Defaults to setting id, ns and title + */ + function formatApiResult( $result ) { + $title = Title::makeTitle( $row->namespace, $row->title ); + return array( + 'pageid' => intval( $row->id ), + 'ns' => intval( $title->getNamespace() ), + 'title' => $title->getPrefixedText(), + ); + } /** * The content returned by this function will be output before any result @@ -278,21 +290,94 @@ class QueryPage { function doQuery( $offset, $limit, $shownavigation=true ) { global $wgUser, $wgOut, $wgLang, $wgContLang; + $wgOut->setSyndicated( $this->isSyndicated() ); + + # Really really do the query now + $result = $this->reallyDoQuery( $offset, $limit ); + + # Tell about cachiness + if ( $result['cached'] !== false ) { + if ( $result['cached'] === true ) { + $wgOut->addWikiMsg( 'perfcached' ); + } else { + $updated = $wgLang->timeAndDate( $result['cached'], true, true ); + $wgOut->addMeta( 'Data-Cache-Time', $result['cached'] ); + $wgOut->addInlineScript( "var dataCacheTime = '{$result['cached']}';" ); + $wgOut->addWikiMsg( 'perfcachedts', $updated ); + } + } + if ( $result['disabled'] ) { + # If updates on this page have been disabled, let the user know + # that the data set won't be refreshed for now + + $wgOut->addWikiMsg( 'querypage-no-updates' ); + } + + $wgOut->addHTML( XML::openElement( 'div', array('class' => 'mw-spcontent') ) ); + + # Top header and navigation + if( $shownavigation ) { + $wgOut->addHTML( $this->getPageHeader() ); + if( $result['count'] > 0 ) { + $wgOut->addHTML( '

' . wfShowingResults( $offset, $result['count'] ) . '

' ); + # Disable the "next" link when we reach the end + $paging = wfViewPrevNext( $offset, $limit, $wgContLang->specialPage( $this->getName() ), + wfArrayToCGI( $this->linkParameters() ), ( $result['count'] < $limit ) ); + $wgOut->addHTML( '

' . $paging . '

' ); + } 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( '

' . wfMsgHtml( 'specialpage-empty' ) . '

' ); + $wgOut->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(), + $result['dbr'], # Should use a ResultWrapper for this + $result['result'], + $result['count'], + $offset ); + + # Repeat the paging links at the bottom + if( $shownavigation ) { + $wgOut->addHTML( '

' . $paging . '

' ); + } + + $wgOut->addHTML( XML::closeElement( 'div' ) ); + + return $result['count']; + } + + /** + * Really really do the query. Returns an array with: + * 'disabled' => true if the data will not be further refreshed, + * 'cached' => false if uncached, the timestamp of the last cache if known, else simply true, + * 'result' => the real result object, + * 'count' => number of results, + * 'dbr' => the database used for fetching the data + */ + protected function reallyDoQuery( $offset, $limit ) { + $result = array( 'disabled' => false ); + $this->offset = $offset; $this->limit = $limit; - $sname = $this->getName(); - $fname = get_class($this) . '::doQuery'; + $fname = get_class($this) . '::reallyDoQuery'; $dbr = wfGetDB( DB_SLAVE ); - $wgOut->setSyndicated( $this->isSyndicated() ); if ( !$this->isCached() ) { $sql = $this->getSQL(); + $result['cached'] = false; } else { # Get the cached result $querycache = $dbr->tableName( 'querycache' ); - $type = $dbr->strencode( $sname ); + $type = $dbr->strencode( $this->getName() ); $sql = "SELECT qc_type as type, qc_namespace as namespace,qc_title as title, qc_value as value FROM $querycache WHERE qc_type='$type'"; @@ -304,21 +389,17 @@ class QueryPage { $tRow = $dbr->fetchObject( $tRes ); if( $tRow ) { - $updated = $wgLang->timeAndDate( $tRow->qci_timestamp, true, true ); - $wgOut->addMeta( 'Data-Cache-Time', $tRow->qci_timestamp ); - $wgOut->addInlineScript( "var dataCacheTime = '{$tRow->qci_timestamp}';" ); - $wgOut->addWikiMsg( 'perfcachedts', $updated ); + $result['cached'] = $tRow->qci_timestamp; } else { - $wgOut->addWikiMsg( 'perfcached' ); + $result['cached'] = true; } # 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' ); + $result['disabled'] = true; } - } } @@ -329,45 +410,11 @@ class QueryPage { $num = $dbr->numRows($res); $this->preprocessResults( $dbr, $res ); - - $wgOut->addHTML( XML::openElement( 'div', array('class' => 'mw-spcontent') ) ); - - # Top header and navigation - if( $shownavigation ) { - $wgOut->addHTML( $this->getPageHeader() ); - if( $num > 0 ) { - $wgOut->addHTML( '

' . wfShowingResults( $offset, $num ) . '

' ); - # Disable the "next" link when we reach the end - $paging = wfViewPrevNext( $offset, $limit, $wgContLang->specialPage( $sname ), - wfArrayToCGI( $this->linkParameters() ), ( $num < $limit ) ); - $wgOut->addHTML( '

' . $paging . '

' ); - } 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( '

' . wfMsgHtml( 'specialpage-empty' ) . '

' ); - $wgOut->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(), - $dbr, # Should use a ResultWrapper for this - $res, - $dbr->numRows( $res ), - $offset ); - - # Repeat the paging links at the bottom - if( $shownavigation ) { - $wgOut->addHTML( '

' . $paging . '

' ); - } - - $wgOut->addHTML( XML::closeElement( 'div' ) ); - - return $num; + + $result['result'] = $res; + $result['count'] = $num; + $result['dbr'] = $dbr; + return $result; } /** @@ -391,7 +438,7 @@ class QueryPage { # $res might contain the whole 1,000 rows, so we read up to # $num [should update this to use a Pager] - for( $i = 0; $i < $num && $row = $dbr->fetchObject( $res ); $i++ ) { + for ( $i = 0; $i < $num && $row = $dbr->fetchObject( $res ); $i++ ) { $line = $this->formatResult( $skin, $row ); if( $line ) { $attr = ( isset( $row->usepatrol ) && $row->usepatrol && $row->patrolled == 0 ) @@ -428,6 +475,7 @@ class QueryPage { } } + function openList( $offset ) { return "\n
    \n"; } -- 2.20.1