X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FQueryPage.php;h=37b48161c847ed112264c1c084facedabb40dc47;hb=cd724523d697bdbaa2c86d222f81ff660d05d51e;hp=b7901adb9369b335b22e1766ccfe2980e4e81e3c;hpb=7f07ad70b742741eb7867b6badc0cb9d7adad987;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/QueryPage.php b/includes/QueryPage.php index b7901adb93..37b48161c8 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -1,117 +1,248 @@ sortDescending() ? 'DESC' : ''); } - # Is this query expensive (for some definition of expensive)? Then we - # don't let it run in miser mode. $wgDisableQueryPages causes all query - # pages to be declared expensive. Some query pages are always expensive. + /** + * Is this query expensive (for some definition of expensive)? Then we + * don't let it run in miser mode. $wgDisableQueryPages causes all query + * pages to be declared expensive. Some query pages are always expensive. + */ function isExpensive( ) { global $wgDisableQueryPages; return $wgDisableQueryPages; } - # Formats the results of the query for display. The skin is the current - # skin; you can use it for making links. The result is a single row of - # result data. You should be able to grab SQL results off of it. + /** + * Sometime we dont want to build rss / atom feeds. + */ + function isSyndicated() { + return true; + } + /** + * Formats the results of the query for display. The skin is the current + * skin; you can use it for making links. The result is a single row of + * result data. You should be able to grab SQL results off of it. + * If the function return "false", the line output will be skipped. + */ function formatResult( $skin, $result ) { - return ""; + return ''; + } + + /** + * The content returned by this function will be output before any result + */ + function getPageHeader( ) { + return ''; } - # This is the actual workhorse. It does everything needed to make a - # real, honest-to-gosh query page. + /** + * Some special pages (for example SpecialListusers) might not return the + * current object formatted, but return the previous one instead. + * Setting this to return true, will call one more time wfFormatResult to + * be sure that the very last result is formatted and shown. + */ + function tryLastResult( ) { + return false; + } + /** + * This is the actual workhorse. It does everything needed to make a + * real, honest-to-gosh query page. + * + * @param $offset database query offset + * @param $limit database query limit + */ function doQuery( $offset, $limit ) { - global $wgUser, $wgOut, $wgLang, $wgMiserMode; + global $wgUser, $wgOut, $wgLang, $wgRequest, $wgContLang; + global $wgMiserMode; $sname = $this->getName(); - $fname = get_class($this) . "::doQuery"; - - $wgOut->setSyndicated( true ); - - if ( $this->isExpensive( ) ) { - $vsp = $wgLang->getValidSpecialPages(); - $logpage = new LogPage( "!" . $vsp[$sname] ); - $logpage->mUpdateRecentChanges = false; - - if ( $wgMiserMode ) { - $logpage->showAsDisabledPage(); - return; + $fname = get_class($this) . '::doQuery'; + $sql = $this->getSQL(); + $dbr =& wfGetDB( DB_SLAVE ); + $dbw =& wfGetDB( DB_MASTER ); + $querycache = $dbr->tableName( 'querycache' ); + + $wgOut->setSyndicated( $this->isSyndicated() ); + $res = false; + + if ( $this->isExpensive() ) { + $recache = $wgRequest->getBool( 'recache' ); + if( $recache ) { + # Clear out any old cached data + $dbw->delete( 'querycache', array( 'qc_type' => $sname ), $fname ); + + # Do query on the (possibly out of date) slave server + $maxstored = 1000; + $res = $dbr->query( $sql . $this->getOrder() . $dbr->limitResult( $maxstored,0 ), $fname ); + + # Fetch results + $insertSql = "INSERT INTO $querycache (qc_type,qc_namespace,qc_title,qc_value) VALUES "; + $first = true; + while ( $row = $dbr->fetchObject( $res ) ) { + if ( $first ) { + $first = false; + } else { + $insertSql .= ','; + } + $insertSql .= '(' . + $dbw->addQuotes( $row->type ) . ',' . + $dbw->addQuotes( $row->namespace ) . ',' . + $dbw->addQuotes( $row->title ) . ',' . + $dbw->addQuotes( $row->value ) . ')'; + } + + # Save results into the querycache table on the master + $dbw->query( $insertSql, $fname ); + + # Set result pointer to allow reading for display + $numRows = $dbr->numRows( $res ); + if ( $numRows <= $offset ) { + $num = 0; + } else { + $dbr->dataSeek( $res, $offset ); + $num = max( $limit, $numRows - $offset ); + } + } + if( $wgMiserMode || $recache ) { + $type = $dbr->strencode( $sname ); + $sql = + "SELECT qc_type as type, qc_namespace as namespace,qc_title as title, qc_value as value + FROM $querycache WHERE qc_type='$type'"; } + if( $wgMiserMode ) { + $wgOut->addWikiText( wfMsg( 'perfcached' ) ); + } + } + if ( $res === false ) { + $res = $dbr->query( $sql . $this->getOrder() . + $dbr->limitResult( $limit,$offset ), $fname ); + $num = $dbr->numRows($res); } - $sql = $this->getSQL( $offset, $limit ); - $res = wfQuery( $sql, DB_READ, $fname ); - - $num = wfNumRows($res); - $sk = $wgUser->getSkin( ); + $wgOut->addHTML( $this->getPageHeader() ); + $top = wfShowingResults( $offset, $num); $wgOut->addHTML( "

{$top}\n" ); # often disable 'next' link when we reach the end if($num < $limit) { $atend = true; } else { $atend = false; } - - $sl = wfViewPrevNext( $offset, $limit , $wgLang->specialPage( $sname ), "" ,$atend ); + + $sl = wfViewPrevNext( $offset, $limit , $wgContLang->specialPage( $sname ), "" ,$atend ); $wgOut->addHTML( "
{$sl}

\n" ); - $s = "
    "; - while ( $obj = wfFetchObject( $res ) ) { - $format = $this->formatResult( $sk, $obj ); - $s .= "
  1. {$format}
  2. \n"; - } - wfFreeResult( $res ); - $s .= "
"; - $wgOut->addHTML( $s ); - $wgOut->addHTML( "

{$sl}

\n" ); + if ( $num > 0 ) { + $s = "
    "; - # Saving cache + # Only read at most $num rows, because $res may contain the whole 1000 + for ( $i = 0; $i < $num && $obj = $dbr->fetchObject( $res ); $i++ ) { + $format = $this->formatResult( $sk, $obj ); + if ( $format ) { + $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol && + $obj->patrolled == 0 ) ? ' class="not-patrolled"' : ''; + $s .= "{$format}\n"; + } + } - if ( $this->isExpensive() && $offset == 0 && $limit >= 50 ) { - $logpage->replaceContent( $s ); + if($this->tryLastResult()) { + // flush the very last result + $obj = null; + $format = $this->formatResult( $sk, $obj ); + if( $format ) { + $attr = ( isset ( $obj->usepatrol ) && $obj->usepatrol && + $obj->patrolled == 0 ) ? ' class="not-patrolled"' : ''; + $s .= "{$format}\n"; + } + } + + $dbr->freeResult( $res ); + $s .= '
'; + $wgOut->addHTML( $s ); } + $wgOut->addHTML( "

{$sl}

\n" ); } - - # Similar to above, but packaging in a syndicated feed instead of a web page - function doFeed( $class = "" ) { + + /** + * Similar to above, but packaging in a syndicated feed instead of a web page + */ + function doFeed( $class = '' ) { global $wgFeedClasses; global $wgOut, $wgLanguageCode, $wgLang; - if( $class == "rss" ) { - $feed = new RSSFeed( + if( isset($wgFeedClasses[$class]) ) { + $feed = new $wgFeedClasses[$class]( $this->feedTitle(), $this->feedDesc(), $this->feedUrl() ); $feed->outHeader(); - - $sql = $this->getSQL( 0, 50 ); - $res = wfQuery( $sql, DB_READ, "QueryPage::doFeed" ); - while( $obj = wfFetchObject( $res ) ) { + + $dbr =& wfGetDB( DB_SLAVE ); + $sql = $this->getSQL() . $this->getOrder().$dbr->limitResult( 50, 0 ); + $res = $dbr->query( $sql, 'QueryPage::doFeed' ); + while( $obj = $dbr->fetchObject( $res ) ) { $item = $this->feedResult( $obj ); if( $item ) $feed->outItem( $item ); } - wfFreeResult( $res ); + $dbr->freeResult( $res ); $feed->outFooter(); return true; @@ -120,74 +251,65 @@ class QueryPage { } } - # Override for custom handling. If the titles/links are ok, just do feedItemDesc() + /** + * Override for custom handling. If the titles/links are ok, just do + * feedItemDesc() + */ function feedResult( $row ) { - if( isset( $row->cur_title ) ) { - $title = Title::MakeTitle( $row->cur_namespace, $row->cur_title ); - } elseif( isset( $row->old_title ) ) { - $title = Title::MakeTitle( $row->old_namespace, $row->old_title ); - } elseif( isset( $row->rc_title ) ) { - $title = Title::MakeTitle( $row->rc_namespace, $row->rc_title ); - } else { + if( !isset( $row->title ) ) { return NULL; } + $title = Title::MakeTitle( IntVal( $row->namespace ), $row->title ); if( $title ) { - $date = ""; - if( isset( $row->cur_timestamp ) ) { - $date = $row->cur_timestamp; - } elseif( isset( $row->old_timestamp ) ) { - $date = $row->old_timestamp; - } elseif( isset( $row->rc_cur_timestamp ) ) { - $date = $row->rc_cur_timestamp; + if( isset( $row->timestamp ) ) { + $date = $row->timestamp; + } else { + $date = ''; } + + $comments = ''; + if( $title ) { + $talkpage = $title->getTalkPage(); + $comments = $talkpage->getFullURL(); + } + return new FeedItem( - $title->getText(), + $title->getPrefixedText(), $this->feedItemDesc( $row ), $title->getFullURL(), $date, - $this->feedItemAuthor( $row ) ); + $this->feedItemAuthor( $row ), + $comments); } else { return NULL; } } - + function feedItemDesc( $row ) { - $text = ""; - if( isset( $row->cur_comment ) ) { - $text = $row->cur_comment; - } elseif( isset( $row->old_comment ) ) { - $text = $row->old_comment; - } elseif( isset( $row->rc_comment ) ) { - $text = $row->rc_comment; - } - $text = htmlspecialchars( $text ); - - if( isset( $row->cur_text ) ) { - $text = "

" . htmlspecialchars( wfMsg( "summary" ) ) . ": " . $text . "

\n
\n
" . - nl2br( $row->cur_text ) . "
";; - } - return $text; + return isset( $row->comment ) + ? htmlspecialchars( $row->comment ) + : ''; } - + function feedItemAuthor( $row ) { - $fields = array( "cur_user_text", "old_user_text", "rc_user_text" ); - foreach( $fields as $field ) { - if( isset( $row->$field ) ) return $row->field; + if( isset( $row->user_text ) ) { + return $row->user_text; + } else { + return ''; } - return ""; } - + function feedTitle() { global $wgLanguageCode, $wgSitename, $wgLang; - $pages = $wgLang->getValidSpecialPages(); - $title = $pages[$this->getName()]; - return "$wgSitename - $title [$wgLanguageCode]"; + $page = SpecialPage::getPage( $this->getName() ); + $desc = $page->getDescription(); + return "$wgSitename - $desc [$wgLanguageCode]"; } - + function feedDesc() { - return wfMsg( "fromwikipedia" ); + return wfMsg( 'tagline' ); } - + function feedUrl() { global $wgLang; $title = Title::MakeTitle( NS_SPECIAL, $this->getName() ); @@ -195,14 +317,19 @@ class QueryPage { } } -# This is a subclass for very simple queries that are just looking for page -# titles that match some criteria. It formats each result item as a link to -# that page. - +/** + * This is a subclass for very simple queries that are just looking for page + * titles that match some criteria. It formats each result item as a link to + * that page. + * + * @package MediaWiki + */ class PageQueryPage extends QueryPage { function formatResult( $skin, $result ) { - return $skin->makeKnownLink( $result->cur_title, "" ); + global $wgContLang; + $nt = Title::makeTitle( $result->namespace, $result->title ); + return $skin->makeKnownLinkObj( $nt, $wgContLang->convert( $result->title ) ); } }