X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=blobdiff_plain;f=includes%2FChangesFeed.php;h=ee4c2d647d864eb2cef581c265f5b9403733b4bc;hb=21b7b27f0379cff1b06efa95d27fa88684b65c57;hp=ce49b005fd42797c81309f7ee76df576172bcc71;hpb=523ce0a9b9fac162f38a0772f2e1568b1a208261;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ChangesFeed.php b/includes/ChangesFeed.php index ce49b005fd..ee4c2d647d 100644 --- a/includes/ChangesFeed.php +++ b/includes/ChangesFeed.php @@ -1,41 +1,96 @@ format = $format; $this->type = $type; } - public function getFeedObject( $title, $description ) { - global $wgSitename, $wgContLanguageCode, $wgFeedClasses, $wgTitle; - $feedTitle = "$wgSitename - {$title} [$wgContLanguageCode]"; - if( !isset($wgFeedClasses[$this->format] ) ) + /** + * Get a ChannelFeed subclass object to use + * + * @param $title String: feed's title + * @param $description String: feed's description + * @param $url String: url of origin page + * @return ChannelFeed subclass or false on failure + */ + public function getFeedObject( $title, $description, $url ) { + global $wgSitename, $wgLanguageCode, $wgFeedClasses; + + if ( !isset( $wgFeedClasses[$this->format] ) ) { return false; + } + + if( !array_key_exists( $this->format, $wgFeedClasses ) ) { + // falling back to atom + $this->format = 'atom'; + } + + $feedTitle = "$wgSitename - {$title} [$wgLanguageCode]"; return new $wgFeedClasses[$this->format]( - $feedTitle, htmlspecialchars( $description ), $wgTitle->getFullUrl() ); + $feedTitle, htmlspecialchars( $description ), $url ); } - public function execute( $feed, $rows, $limit=0, $hideminor=false, $lastmod=false, $target='' ) { - global $messageMemc, $wgFeedCacheTimeout; - global $wgSitename, $wgContLanguageCode; + /** + * Generates feed's content + * + * @param $feed ChannelFeed subclass object (generally the one returned by getFeedObject()) + * @param $rows ResultWrapper object with rows in recentchanges table + * @param $lastmod Integer: timestamp of the last item in the recentchanges table (only used for the cache key) + * @param $opts FormOptions as in SpecialRecentChanges::getDefaultOptions() + * @return null|bool True or null + */ + public function execute( $feed, $rows, $lastmod, $opts ) { + global $wgLang, $wgRenderHashAppend; if ( !FeedUtils::checkFeedOutput( $this->format ) ) { - return; + return null; } - $timekey = wfMemcKey( $this->type, $this->format, 'timestamp' ); - $key = wfMemcKey( $this->type, $this->format, $limit, $hideminor, $target ); + $optionsHash = md5( serialize( $opts->getAllValues() ) ) . $wgRenderHashAppend; + $timekey = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash, 'timestamp' ); + $key = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash ); - FeedUtils::checkPurge($timekey, $key); + FeedUtils::checkPurge( $timekey, $key ); - /* - * Bumping around loading up diffs can be pretty slow, so where - * possible we want to cache the feed output so the next visitor - * gets it quick too. - */ + /** + * Bumping around loading up diffs can be pretty slow, so where + * possible we want to cache the feed output so the next visitor + * gets it quick too. + */ $cachedFeed = $this->loadFromCache( $lastmod, $timekey, $key ); if( is_string( $cachedFeed ) ) { wfDebug( "RC: Outputting cached feed\n" ); @@ -52,24 +107,40 @@ class ChangesFeed { return true; } + /** + * Save to feed result to $messageMemc + * + * @param $feed String: feed's content + * @param $timekey String: memcached key of the last modification + * @param $key String: memcached key of the content + */ public function saveToCache( $feed, $timekey, $key ) { global $messageMemc; $expire = 3600 * 24; # One day - $messageMemc->set( $key, $feed ); + $messageMemc->set( $key, $feed, $expire ); $messageMemc->set( $timekey, wfTimestamp( TS_MW ), $expire ); } + /** + * Try to load the feed result from $messageMemc + * + * @param $lastmod Integer: timestamp of the last item in the recentchanges table + * @param $timekey String: memcached key of the last modification + * @param $key String: memcached key of the content + * @return string|bool feed's content on cache hit or false on cache miss + */ public function loadFromCache( $lastmod, $timekey, $key ) { - global $wgFeedCacheTimeout, $messageMemc; + global $wgFeedCacheTimeout, $wgOut, $messageMemc; + $feedLastmod = $messageMemc->get( $timekey ); if( ( $wgFeedCacheTimeout > 0 ) && $feedLastmod ) { - /* - * If the cached feed was rendered very recently, we may - * go ahead and use it even if there have been edits made - * since it was rendered. This keeps a swarm of requests - * from being too bad on a super-frequently edited wiki. - */ + /** + * If the cached feed was rendered very recently, we may + * go ahead and use it even if there have been edits made + * since it was rendered. This keeps a swarm of requests + * from being too bad on a super-frequently edited wiki. + */ $feedAge = time() - wfTimestamp( TS_UNIX, $feedLastmod ); $feedLastmodUnix = wfTimestamp( TS_UNIX, $feedLastmod ); @@ -77,6 +148,9 @@ class ChangesFeed { if( $feedAge < $wgFeedCacheTimeout || $feedLastmodUnix > $lastmodUnix) { wfDebug( "RC: loading feed from cache ($key; $feedLastmod; $lastmod)...\n" ); + if ( $feedLastmodUnix < $lastmodUnix ) { + $wgOut->setLastModified( $feedLastmod ); // bug 21916 + } return $messageMemc->get( $key ); } else { wfDebug( "RC: cached feed timestamp check failed ($feedLastmod; $lastmod)\n" ); @@ -86,10 +160,10 @@ class ChangesFeed { } /** - * Generate the feed items given a row from the database. - * @param $rows Database resource with recentchanges rows - * @param $feed Feed object - */ + * Generate the feed items given a row from the database. + * @param $rows DatabaseBase resource with recentchanges rows + * @param $feed Feed object + */ public static function generateFeed( $rows, &$feed ) { wfProfileIn( __METHOD__ ); @@ -100,6 +174,7 @@ class ChangesFeed { $n = 0; foreach( $rows as $obj ) { if( $n > 0 && + $obj->rc_type == RC_EDIT && $obj->rc_namespace >= 0 && $obj->rc_cur_id == $sorted[$n-1]->rc_cur_id && $obj->rc_user_text == $sorted[$n-1]->rc_user_text ) { @@ -112,16 +187,27 @@ class ChangesFeed { foreach( $sorted as $obj ) { $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title ); - $talkpage = $title->getTalkPage(); + $talkpage = MWNamespace::canTalk( $obj->rc_namespace ) ? $title->getTalkPage()->getFullUrl() : ''; // Skip items with deleted content (avoids partially complete/inconsistent output) if( $obj->rc_deleted ) continue; + + if ( $obj->rc_this_oldid ) { + $url = $title->getFullURL( + 'diff=' . $obj->rc_this_oldid . + '&oldid=' . $obj->rc_last_oldid + ); + } else { + // log entry or something like that. + $url = $title->getFullURL(); + } + $item = new FeedItem( $title->getPrefixedText(), FeedUtils::formatDiff( $obj ), - $obj->rc_this_oldid ? $title->getFullURL( 'diff=' . $obj->rc_this_oldid . '&oldid=prev' ) : $title->getFullURL(), + $url, $obj->rc_timestamp, - ($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text, - $talkpage->getFullURL() + ( $obj->rc_deleted & Revision::DELETED_USER ) ? wfMessage( 'rev-deleted-user' )->escaped() : $obj->rc_user_text, + $talkpage ); $feed->outItem( $item ); } @@ -129,4 +215,4 @@ class ChangesFeed { wfProfileOut( __METHOD__ ); } -} \ No newline at end of file +}