MediaWiki
REL1_19
|
00001 <?php 00002 00008 class ChangesFeed { 00009 public $format, $type, $titleMsg, $descMsg; 00010 00017 public function __construct( $format, $type ) { 00018 $this->format = $format; 00019 $this->type = $type; 00020 } 00021 00030 public function getFeedObject( $title, $description, $url ) { 00031 global $wgSitename, $wgLanguageCode, $wgFeedClasses; 00032 00033 if ( !isset( $wgFeedClasses[$this->format] ) ) { 00034 return false; 00035 } 00036 00037 if( !array_key_exists( $this->format, $wgFeedClasses ) ) { 00038 // falling back to atom 00039 $this->format = 'atom'; 00040 } 00041 00042 $feedTitle = "$wgSitename - {$title} [$wgLanguageCode]"; 00043 return new $wgFeedClasses[$this->format]( 00044 $feedTitle, htmlspecialchars( $description ), $url ); 00045 } 00046 00056 public function execute( $feed, $rows, $lastmod, $opts ) { 00057 global $wgLang, $wgRenderHashAppend; 00058 00059 if ( !FeedUtils::checkFeedOutput( $this->format ) ) { 00060 return; 00061 } 00062 00063 $optionsHash = md5( serialize( $opts->getAllValues() ) ) . $wgRenderHashAppend; 00064 $timekey = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash, 'timestamp' ); 00065 $key = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash ); 00066 00067 FeedUtils::checkPurge( $timekey, $key ); 00068 00074 $cachedFeed = $this->loadFromCache( $lastmod, $timekey, $key ); 00075 if( is_string( $cachedFeed ) ) { 00076 wfDebug( "RC: Outputting cached feed\n" ); 00077 $feed->httpHeaders(); 00078 echo $cachedFeed; 00079 } else { 00080 wfDebug( "RC: rendering new feed and caching it\n" ); 00081 ob_start(); 00082 self::generateFeed( $rows, $feed ); 00083 $cachedFeed = ob_get_contents(); 00084 ob_end_flush(); 00085 $this->saveToCache( $cachedFeed, $timekey, $key ); 00086 } 00087 return true; 00088 } 00089 00097 public function saveToCache( $feed, $timekey, $key ) { 00098 global $messageMemc; 00099 $expire = 3600 * 24; # One day 00100 $messageMemc->set( $key, $feed, $expire ); 00101 $messageMemc->set( $timekey, wfTimestamp( TS_MW ), $expire ); 00102 } 00103 00112 public function loadFromCache( $lastmod, $timekey, $key ) { 00113 global $wgFeedCacheTimeout, $wgOut, $messageMemc; 00114 00115 $feedLastmod = $messageMemc->get( $timekey ); 00116 00117 if( ( $wgFeedCacheTimeout > 0 ) && $feedLastmod ) { 00125 $feedAge = time() - wfTimestamp( TS_UNIX, $feedLastmod ); 00126 $feedLastmodUnix = wfTimestamp( TS_UNIX, $feedLastmod ); 00127 $lastmodUnix = wfTimestamp( TS_UNIX, $lastmod ); 00128 00129 if( $feedAge < $wgFeedCacheTimeout || $feedLastmodUnix > $lastmodUnix) { 00130 wfDebug( "RC: loading feed from cache ($key; $feedLastmod; $lastmod)...\n" ); 00131 if ( $feedLastmodUnix < $lastmodUnix ) { 00132 $wgOut->setLastModified( $feedLastmod ); // bug 21916 00133 } 00134 return $messageMemc->get( $key ); 00135 } else { 00136 wfDebug( "RC: cached feed timestamp check failed ($feedLastmod; $lastmod)\n" ); 00137 } 00138 } 00139 return false; 00140 } 00141 00147 public static function generateFeed( $rows, &$feed ) { 00148 wfProfileIn( __METHOD__ ); 00149 00150 $feed->outHeader(); 00151 00152 # Merge adjacent edits by one user 00153 $sorted = array(); 00154 $n = 0; 00155 foreach( $rows as $obj ) { 00156 if( $n > 0 && 00157 $obj->rc_type == RC_EDIT && 00158 $obj->rc_namespace >= 0 && 00159 $obj->rc_cur_id == $sorted[$n-1]->rc_cur_id && 00160 $obj->rc_user_text == $sorted[$n-1]->rc_user_text ) { 00161 $sorted[$n-1]->rc_last_oldid = $obj->rc_last_oldid; 00162 } else { 00163 $sorted[$n] = $obj; 00164 $n++; 00165 } 00166 } 00167 00168 foreach( $sorted as $obj ) { 00169 $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title ); 00170 $talkpage = MWNamespace::canTalk( $obj->rc_namespace ) ? $title->getTalkPage()->getFullUrl() : ''; 00171 // Skip items with deleted content (avoids partially complete/inconsistent output) 00172 if( $obj->rc_deleted ) continue; 00173 00174 if ( $obj->rc_this_oldid ) { 00175 $url = $title->getFullURL( 00176 'diff=' . $obj->rc_this_oldid . 00177 '&oldid=' . $obj->rc_last_oldid 00178 ); 00179 } else { 00180 // log entry or something like that. 00181 $url = $title->getFullURL(); 00182 } 00183 00184 $item = new FeedItem( 00185 $title->getPrefixedText(), 00186 FeedUtils::formatDiff( $obj ), 00187 $url, 00188 $obj->rc_timestamp, 00189 ($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text, 00190 $talkpage 00191 ); 00192 $feed->outItem( $item ); 00193 } 00194 $feed->outFooter(); 00195 wfProfileOut( __METHOD__ ); 00196 } 00197 00198 }