MediaWiki r9005 - Code Review

Jump to: navigation, search
Repository:MediaWiki
Revision:r9004‎ | r9005 (on ViewVC)‎ | r9006 >
Date:21:37, 13 May 2005
Author:gabrielwicke
Status:old
Tags:
Comment:
* New in-page 'catnews' plugin, capable of diplaying multiple categories by date
Syntax:
<catnews>
Category1
Someothercat
</catnews>
* better caching, no db query for most views using a memcache timestamp
* ordering by date is now really kept across edits
Modified paths:

Diff [purge]

Index: trunk/extensions/catfeed/catfeed.php
@@ -34,58 +34,71 @@
3535
3636 global $IP;
3737 require_once( "$IP/includes/CategoryPage.php" );
 38+ require_once("Feed.php");
3839
3940 global $wgHooks;
4041
41 - $wgHooks['CategoryPageView'][] = 'viewCatRSS';
 42+ $wgHooks['CategoryPageView'][] = 'viewCatFeed';
 43+ global $wgParser;
 44+ $wgParser->setHook( "catnews", "viewCatNewslist" );
4245
43 - class CategoryFeed extends CategoryPage {
 46+
 47+ class CategoryByDate extends CategoryPage {
4448 /**
4549 * Feed for recently-added members of a category based on cl_timestamp
4650 * Uses bits of the recentchanges feeds (caching and formatting)
4751 * @package MediaWiki
4852 */
4953
50 - function CategoryFeed( &$CategoryPage ) {
51 - $this->mTitle = $CategoryPage->mTitle;
 54+ function CategoryByDate( &$title, $tarray = false ) {
 55+ global $wgRequest;
 56+ $this->mTitle = $title;
 57+ $this->mFeedFormat = $wgRequest->getVal( 'feed', '' );
 58+ $this->mTitleStrings = array();
 59+ if ( is_array($tarray) ) {
 60+ foreach($tarray as $title) {
 61+ $this->mTitleStrings[] = $title->getDBKey();
 62+ }
 63+ } else {
 64+ $this->mTitleStrings[] = $title->getDBKey();
 65+ }
5266 }
5367
5468 function view() {
55 - global $wgRequest;
56 - require_once("Feed.php");
57 - $this->mFeedFormat = $wgRequest->getVal( 'feed', '' );
58 - if ( $this->mFeedFormat == '') return true; # let CategoryPage::view continue, no feed requested
 69+ // cache handling in subclass
 70+ return $this->getData();
 71+ }
 72+ function getData() {
5973 $this->mMaxTimeStamp = 0;
 74+
6075 $limit = 50;
6176 $dbr =& wfGetDB( DB_SLAVE );
6277 $res = $dbr->select(
6378 array( 'cur', 'categorylinks' ),
6479 array( 'cur_title', 'cur_namespace', 'cur_text', 'cur_user_text', 'cl_sortkey', 'cl_timestamp' ),
6580 array( 'cl_from = cur_id',
66 - 'cl_to' => $this->mTitle->getDBKey(),
 81+ 'cl_to IN ("'.implode('","', $this->mTitleStrings).'")',
6782 'cur_is_redirect' => 0),
6883 $fname,
6984 array( 'ORDER BY' => 'cl_timestamp DESC, cl_sortkey ASC',
7085 'LIMIT' => $limit ));
7186 $rows = array();
72 - while( $row = $dbr->fetchObject ( $res ) ) {
73 - $rows[] = $row;
74 - if ( $row->cl_timestamp > $this->mMaxTimeStamp ) {
75 - $this->mMaxTimeStamp = $row->cl_timestamp;
76 - }
 87+ while( $row = $dbr->fetchObject ( $res ) ) {
 88+ $rows[] = $row;
 89+ if ( $row->cl_timestamp > $this->mMaxTimeStamp ) {
 90+ $this->mMaxTimeStamp = $row->cl_timestamp;
7791 }
78 - $this->categoryOutputFeed( &$rows, $limit );
79 - # stop CategoryPage::view from continuing
80 - return false;
 92+ }
 93+ return $this->formatRows( &$rows );
8194 }
8295
8396 # strip images, links, tags
84 - function formatSummary ( $row ) {
 97+ function formatSummary ( $text ) {
8598 global $wgContLang;
8699 $prefixes = array_keys($wgContLang->getLanguageNames());
87100 $prefixes[] = $wgContLang->getNsText(NS_CATEGORY);
88101 $imgprefix = $wgContLang->getNsText(NS_IMAGE);
89 - $text = "\n".$row->cur_text;
 102+ $text = "\n".$text;
90103
91104 $rules = array(
92105 "/\[\[(".implode('|',$prefixes)."):[^\]]*\]\]/i" => "", # interwiki links, cat links
@@ -115,87 +128,137 @@
116129 return htmlspecialchars( $shorttext.'...');
117130 }
118131
119 - function categoryOutputFeed( $rows, $limit ) {
120 - global $messageMemc, $wgDBname, $wgFeedCacheTimeout;
 132+ }
 133+
 134+ class CategoryByDateFeed extends CategoryByDate {
 135+
 136+ function view() {
 137+ global $wgRequest;
 138+ global $messageMemc, $wgDBname;
121139 global $wgFeedClasses, $wgTitle, $wgSitename, $wgContLanguageCode;
122140
123141 if( !isset( $wgFeedClasses[$this->mFeedFormat] ) ) {
124142 wfHttpError( 500, "Internal Server Error", "Unsupported feed type." );
125143 return false;
126144 }
127 -
128 - $timekey = "$wgDBname:catfeed:" . $this->mTitle->getDBKey() . ":timestamp";
129 - $key = "$wgDBname:catfeed:" . $this->mTitle->getDBKey() . ":$this->mFeedFormat:limit:$limit";
130 -
131145 $feedTitle = $this->mTitle->getPrefixedText() . ' - ' . $wgSitename;
132 - $feed = new $wgFeedClasses[$this->mFeedFormat](
 146+ $this->feed = new $wgFeedClasses[$this->mFeedFormat](
133147 $feedTitle,
134148 htmlspecialchars( wfMsgForContent( 'catfeedsummary' ) ),
135149 $wgTitle->getFullUrl() );
136150
137 - /**
138 - * Loading and parsing cur_text for all added pages is slow, so we cache it
139 - */
140 - $cachedFeed = false;
141 - if( $feedLastmod = $messageMemc->get( $timekey ) ) {
142 - /**
143 - * If the cached feed was rendered very recently, we may
144 - * go ahead and use it even if there have been edits made
145 - * since it was rendered. This keeps a swarm of requests
146 - * from being too bad on a super-frequently edited wiki.
147 - */
148 - if( time() - wfTimestamp( TS_UNIX, $feedLastmod )
149 - < $wgFeedCacheTimeout
150 - || wfTimestamp( TS_UNIX, $feedLastmod )
151 - > wfTimestamp( TS_UNIX, $this->mMaxTimeStamp ) ) {
152 - wfDebug( "CatFeed: loading feed from cache ($key; $feedLastmod; $this->mMaxTimeStamp)...\n" );
153 - $cachedFeed = $messageMemc->get( $key );
154 - } else {
155 - wfDebug( "CatFeed: cached feed timestamp check failed ($feedLastmod; $this->mMaxTimeStamp)\n" );
156 - }
157 - }
158 - if( is_string( $cachedFeed ) ) {
159 - wfDebug( "CatFeed: Outputting cached feed\n" );
160 - $feed->httpHeaders();
161 - echo $cachedFeed;
162 - } else {
163 - wfDebug( "CatFeed: rendering new feed and caching it\n" );
164 - ob_start();
165 - $this->catDoOutputFeed( $rows, $feed );
166 - $cachedFeed = ob_get_contents();
167 - ob_end_flush();
 151+ $timekey = "$wgDBname:catfeed:" . $this->mTitle->getDBKey() . ":$this->mFeedFormat:limit:$limit:timestamp";
 152+ $key = "$wgDBname:catfeed:" . $this->mTitle->getDBKey() . ":$this->mFeedFormat:limit:$limit";
 153+ $cachedFeed = false;
 154+ $adddeltimestamp = $wgDBname.':Category:'.$wgTitle->getDBkey().':adddeltimestamp';
 155+
 156+ $catLastAddDel = $messageMemc->get( $adddeltimestamp );
168157
169 - $expire = 3600 * 24; # One day
170 - $messageMemc->set( $key, $cachedFeed );
171 - $messageMemc->set( $timekey, wfTimestamp( TS_MW ), $expire );
172 - }
173 - return true;
 158+ if( $feedLastmod = $messageMemc->get( $timekey )
 159+ and $catLastAddDel <= $feedLastmod ) {
 160+ wfDebug( "CatFeed: loading feed from cache ($key; $feedLastmod; $catLastAddDel )...\n" );
 161+ $cachedFeed = $messageMemc->get( $key );
 162+ } else {
 163+ wfDebug( "CatFeed: cached feed timestamp check failed ($feedLastmod; $catLastAddDel) timekey: $timekey; adddel: $adddeltimestamp \n" );
 164+
 165+ }
 166+ if( is_string( $cachedFeed ) ) {
 167+ wfDebug( "CatFeed: Outputting cached feed\n" );
 168+ $this->feed->httpHeaders();
 169+ echo $cachedFeed;
 170+ } else {
 171+ wfDebug( "CatFeed: rendering new feed and caching it\n" );
 172+ ob_start();
 173+ $this->getData();
 174+ $cachedFeed = ob_get_contents();
 175+ ob_end_flush();
 176+
 177+ $expire = 3600 * 24; # One day
 178+ $messageMemc->set( $key, $cachedFeed );
 179+ $messageMemc->set( $timekey, $catLastAddDel , $expire );
 180+ }
 181+ return true;
174182 }
175183
176 - function catDoOutputFeed( $rows, &$feed ) {
 184+ function formatRows( $rows ) {
177185 global $wgSitename, $wgFeedClasses, $wgContLanguageCode;
178186
179 - $feed->outHeader();
 187+ $this->feed->outHeader();
180188 foreach( $rows as $row ) {
181189 $title = Title::makeTitle( $row->cur_namespace, $row->cur_title );
182190 $item = new FeedItem(
183191 $title->getPrefixedText(),
184 - $this->formatSummary( &$row ),
 192+ $this->formatSummary( $row->cur_text ),
185193 $title->getFullURL(),
186 - $row->lc_timestamp,
 194+ $row->cl_timestamp,
187195 $row->cur_user_text,
188196 '' #$talkpage->getFullURL()
189197 );
190 - $feed->outItem( $item );
 198+ $this->feed->outItem( $item );
191199 }
192 - $feed->outFooter();
 200+ $this->feed->outFooter();
193201 }
 202+
194203 }
195204
 205+ class CategoryByDateNewslist extends CategoryByDate {
 206+
 207+ function formatRows( $rows ) {
 208+ # format members of a category as 'news list' within a page
 209+ # useful for portals, probably wikinews etc
 210+ # todo: allow multiple categories to be merged ('or' in sql)
 211+ global $wgUser;
 212+ $skin = &$wgUser->getSkin();
 213+ $list = '';
 214+ $ts = $closedl = $date = $oldns = $oldtitle = '';
 215+ foreach( $rows as $row ) {
 216+ # check for duplicates, cheaper than in the db
 217+ if($row->cur_namespace != $oldns or $row->cur_title != $oldtitle) {
 218+ $oldns = $row->cur_namespace;
 219+ $oldtitle = $row->cur_title;
 220+ $title = Title::makeTitle( $row->cur_namespace, $row->cur_title );
 221+ $ts = $row->cl_timestamp;
 222+ $newdate = gmdate( 'D, d M Y', wfTimestamp( TS_UNIX, $ts ) );
 223+ if( $date != $newdate ) {
 224+ $date = $newdate;
 225+ $list .= "$closedl\n<h2> ".$date." </h2>\n<dl>";
 226+ $closedl = '</dl>';
 227+ }
 228+ $list .= '<dt>' . $skin->makeKnownLinkObj($title) .
 229+ ' <span style="font-size: 0.76em;font-weight:normal;">' .
 230+ gmdate( 'H:i:s \G\M\T', wfTimestamp( TS_UNIX, $ts ) ) . '</span></dt><dd> ' .
 231+ $this->formatSummary( $row->cur_text ).'</dd>';
 232+ }
 233+ }
 234+ return $list . $closedl;
 235+ }
 236+ }
 237+
196238 }
197239
198 -function viewCatRSS( &$CategoryPage ) {
199 - $catfeed = new CategoryFeed($CategoryPage);
200 - return $catfeed->view();
 240+function viewCatFeed( &$CategoryPage ) {
 241+ global $wgRequest;
 242+ $catfeed = new CategoryByDateFeed($CategoryPage->mTitle);
 243+ # nothing to do,CategoryPage::view continues
 244+ if(!$wgRequest->getBool('feed',false)) return true;
 245+
 246+ # else continue
 247+ $catfeed->view();
 248+ # stop CategoryPage::view from continuing
 249+ return false;
201250 }
 251+function viewCatNewslist( $input ) {
 252+ $text = '';
 253+ $iptitles = split("\n",trim($input));
 254+ $dbtitles = array();
 255+ foreach ( $iptitles as $title ) {
 256+ $dbtitles[] = Title::newFromUrl($title);
 257+ }
 258+ # search for 5 categories max for now
 259+ $dbtitles = array_slice($dbtitles, 0, 4);
 260+ $catnews = new CategoryByDateNewslist($dbtitles[0], $dbtitles);
 261+ $text .= $catnews->view();
 262+
 263+ return $text;
 264+}
202265 ?>

Status & tagging log

  • 15:03, 12 September 2011 Meno25 (Talk | contribs) changed the status of r9005 [removed: ok added: old]
  • 14:06, 1 July 2009 ^demon (Talk | contribs) changed the status of r9005 [removed: new added: ok]
Personal tools
Namespaces

Variants
Views
Actions
Navigation
Support
Download
Development
Communication
Toolbox