r62626 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r62625‎ | r62626 | r62627 >
Date:00:06, 17 February 2010
Author:juliano
Status:deferred
Tags:
Comment:
Implemented article comment feeds.
Modified paths:
  • /trunk/extensions/Wikilog/Wikilog.i18n.php (modified) (history)
  • /trunk/extensions/Wikilog/Wikilog.php (modified) (history)
  • /trunk/extensions/Wikilog/WikilogComment.php (modified) (history)
  • /trunk/extensions/Wikilog/WikilogCommentsPage.php (modified) (history)
  • /trunk/extensions/Wikilog/WikilogFeed.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Wikilog/WikilogFeed.php
@@ -598,3 +598,220 @@
599599 }
600600 }
601601 }
 602+
 603+/**
 604+ * Syndication feed generator for wikilog comments.
 605+ */
 606+class WikilogCommentFeed
 607+ extends WikilogFeed
 608+{
 609+ /**
 610+ * If displaying comments for a single article.
 611+ */
 612+ protected $mSingleItem = false;
 613+
 614+ /**
 615+ * WikilogCommentFeed constructor.
 616+ *
 617+ * @param $title Title Feed title and URL.
 618+ * @param $format string Feed format ('atom' or 'rss').
 619+ * @param $query WikilogCommentQuery Query parameters.
 620+ * @param $limit integer Number of items to generate.
 621+ */
 622+ public function __construct( Title $title, $format,
 623+ WikilogCommentQuery $query, $limit = false )
 624+ {
 625+ global $wgWikilogNumComments;
 626+
 627+ if ( !$limit ) $limit = $wgWikilogNumComments;
 628+ parent::__construct( $title, $format, $query, $limit );
 629+ }
 630+
 631+ public function getIndexField() {
 632+ return 'wlc_timestamp';
 633+ }
 634+
 635+ public function getFeedObject() {
 636+ if ( ( $item = $this->mQuery->getItem() ) ) {
 637+ return $this->getItemFeedObject( $item );
 638+ } else {
 639+ return $this->getSiteFeedObject();
 640+ }
 641+ }
 642+
 643+ /**
 644+ * Generates and populates a WlSyndicationFeed object for the site.
 645+ *
 646+ * @return WlSyndicationFeed object.
 647+ */
 648+ public function getSiteFeedObject() {
 649+ global $wgContLanguageCode, $wgWikilogFeedClasses, $wgFavicon, $wgLogo;
 650+
 651+ $title = wfMsgForContent( 'wikilog-feed-title',
 652+ wfMsgForContent( 'wikilog-specialwikilogcomments-title' ),
 653+ $wgContLanguageCode
 654+ );
 655+ $subtitle = wfMsgExt( 'wikilog-comment-feed-description', array( 'parse', 'content' ) );
 656+
 657+ $updated = $this->mDb->selectField( 'wikilog_comments',
 658+ 'MAX(wlc_updated)', false, __METHOD__
 659+ );
 660+ if ( !$updated ) $updated = wfTimestampNow();
 661+
 662+ $url = $this->mTitle->getFullUrl();
 663+
 664+ $feed = new $wgWikilogFeedClasses[$this->mFormat](
 665+ $url, $title, $updated, $url
 666+ );
 667+ $feed->setSubtitle( new WlTextConstruct( 'html', $subtitle ) );
 668+ if ( $wgFavicon !== false ) {
 669+ $feed->setIcon( wfExpandUrl( $wgFavicon ) );
 670+ }
 671+ if ( $this->mCopyright ) {
 672+ $feed->setRights( new WlTextConstruct( 'html', $this->mCopyright ) );
 673+ }
 674+ return $feed;
 675+ }
 676+
 677+ /**
 678+ * Generates and populates a WlSyndicationFeed object for the given
 679+ * wikilog article.
 680+ *
 681+ * @param $item WikilogItem Wikilog article that owns this feed.
 682+ * @return WlSyndicationFeed object, or NULL if not possible.
 683+ */
 684+ public function getItemFeedObject( WikilogItem $item ) {
 685+ global $wgContLanguageCode, $wgWikilogFeedClasses, $wgFavicon;
 686+
 687+ $title = wfMsgForContent( 'wikilog-feed-title',
 688+ wfMsgForContent( 'wikilog-title-comments', $item->mName ),
 689+ $wgContLanguageCode
 690+ );
 691+ $subtitle = wfMsgExt( 'wikilog-comment-feed-description', array( 'parse', 'content' ) );
 692+ $updated = $this->mDb->selectField( 'wikilog_comments',
 693+ 'MAX(wlc_updated)', array( 'wlc_post' => $item->mID ), __METHOD__
 694+ );
 695+ if ( !$updated ) $updated = wfTimestampNow();
 696+
 697+ $url = $this->mTitle->getFullUrl();
 698+
 699+ $feed = new $wgWikilogFeedClasses[$this->mFormat](
 700+ $url, $title, $updated, $url
 701+ );
 702+ $feed->setSubtitle( new WlTextConstruct( 'html', $subtitle ) );
 703+ if ( $wgFavicon !== false ) {
 704+ $feed->setIcon( wfExpandUrl( $wgFavicon ) );
 705+ }
 706+ if ( $this->mCopyright ) {
 707+ $feed->setRights( new WlTextConstruct( 'html', $this->mCopyright ) );
 708+ }
 709+ return $feed;
 710+ }
 711+
 712+ /**
 713+ * Generates and returns a single feed entry.
 714+ * @param $row The wikilog comment database entry.
 715+ * @return A new WlSyndicationEntry object.
 716+ */
 717+ function formatFeedEntry( $row ) {
 718+ global $wgMimeType;
 719+
 720+ # Create comment object.
 721+ $item = $this->mSingleItem ? $this->mSingleItem : WikilogItem::newFromRow( $row );
 722+ $comment = WikilogComment::newFromRow( $item, $row );
 723+
 724+ # Prepare some strings.
 725+ if ( $comment->mUserID ) {
 726+ $usertext = $comment->mUserText;
 727+ } else {
 728+ $usertext = wfMsgForContent( 'wikilog-comment-anonsig',
 729+ $comment->mUserText, ''/*talk*/, $comment->mAnonName
 730+ );
 731+ }
 732+ if ( $this->mSingleItem ) {
 733+ $title = wfMsgForContent( 'wikilog-comment-feed-title1',
 734+ $comment->mID, $usertext
 735+ );
 736+ } else {
 737+ $title = wfMsgForContent( 'wikilog-comment-feed-title2',
 738+ $comment->mID, $usertext, $comment->mItem->mName
 739+ );
 740+ }
 741+
 742+ # Create new syndication entry.
 743+ $entry = new WlSyndicationEntry(
 744+ self::makeEntryId( $comment ),
 745+ $title,
 746+ $comment->mUpdated,
 747+ $comment->getCommentArticleTitle()->getFullUrl()
 748+ );
 749+
 750+ # Comment text.
 751+ if ( $comment->mCommentRev ) {
 752+ list( $article, $parserOutput ) = WikilogUtils::parsedArticle( $comment->mCommentTitle, true );
 753+ $content = Sanitizer::removeHTMLcomments( $parserOutput->getText() );
 754+ if ( $content ) {
 755+ $entry->setContent( new WlTextConstruct( 'html', $content ) );
 756+ }
 757+ }
 758+
 759+ # Author.
 760+ $usertitle = Title::makeTitle( NS_USER, $comment->mUserText );
 761+ $useruri = $usertitle->exists() ? $usertitle->getFullUrl() : null;
 762+ $entry->addAuthor( $usertext, $useruri );
 763+
 764+ # Timestamp
 765+ $entry->setPublished( $comment->mTimestamp );
 766+
 767+ return $entry;
 768+ }
 769+
 770+ /**
 771+ * Performs the database query that returns the syndication feed entries
 772+ * and store the result wrapper in $this->mResult.
 773+ */
 774+ function doQuery() {
 775+ # If displaying comments for a single item, save the item.
 776+ # Otherwise, set query option to return items along with their
 777+ # comments.
 778+ if ( ( $item = $this->mQuery->getItem() ) ) {
 779+ $this->mSingleItem = $item;
 780+ } else {
 781+ $this->mQuery->setOption( 'include-item' );
 782+ }
 783+ return parent::doQuery();
 784+ }
 785+
 786+ /**
 787+ * Returns the keys for the timestamp and feed output in the object cache.
 788+ */
 789+ function getCacheKeys() {
 790+ if ( ( $item = $this->mQuery->getItem() ) ) {
 791+ $title = $item->mTitle;
 792+ } else {
 793+ $title = null;
 794+ }
 795+ $id = $title ? 'id:' . $title->getArticleId() : 'site';
 796+ $ft = 'show:' . $this->mQuery->getModStatus() .
 797+ ':limit:' . $this->mLimit;
 798+ return array(
 799+ wfMemcKey( 'wikilog', $this->mFormat, $id, 'timestamp' ),
 800+ wfMemcKey( 'wikilog', $this->mFormat, $id, $ft )
 801+ );
 802+ }
 803+
 804+ /**
 805+ * Creates an unique ID for a feed entry. Tries to use $wgTaggingEntity
 806+ * if possible in order to create an RFC 4151 tag, otherwise, we use the
 807+ * page URL.
 808+ */
 809+ public static function makeEntryId( WikilogComment $comment ) {
 810+ global $wgTaggingEntity;
 811+ if ( $wgTaggingEntity ) {
 812+ $qstr = wfArrayToCGI( array( 'wk' => wfWikiID(), 'id' => $comment->getID() ) );
 813+ return "tag:{$wgTaggingEntity}:/MediaWiki/Wikilog/comment?{$qstr}";
 814+ } else {
 815+ return $comment->getCommentArticleTitle()->getFullUrl();
 816+ }
 817+ }
 818+}
Index: trunk/extensions/Wikilog/Wikilog.php
@@ -89,6 +89,7 @@
9090 // WikilogFeed.php
9191 'WikilogFeed' => $dir . 'WikilogFeed.php',
9292 'WikilogItemFeed' => $dir . 'WikilogFeed.php',
 93+ 'WikilogCommentFeed' => $dir . 'WikilogFeed.php',
9394
9495 // WikilogQuery.php
9596 'WikilogQuery' => $dir . 'WikilogQuery.php',
Index: trunk/extensions/Wikilog/WikilogCommentsPage.php
@@ -120,6 +120,18 @@
121121 return parent::view();
122122 }
123123
 124+ # Create our query object.
 125+ $query = new WikilogCommentQuery( $this->mItem );
 126+
 127+ if ( ( $feedFormat = $wgRequest->getVal( 'feed' ) ) ) {
 128+ # RSS or Atom feed requested. Ignore all other options.
 129+ global $wgWikilogNumComments;
 130+ $query->setModStatus( WikilogCommentQuery::MS_ACCEPTED );
 131+ $feed = new WikilogCommentFeed( $this->mTitle, $feedFormat, $query,
 132+ $wgRequest->getInt( 'limit', $wgWikilogNumComments ) );
 133+ return $feed->execute();
 134+ }
 135+
124136 if ( $this->mSingleComment ) {
125137 # Single comment view, show comment followed by its replies.
126138 $params = $this->mFormatter->getCommentMsgParams( $this->mSingleComment );
@@ -153,20 +165,21 @@
154166 $wgOut->setSubtitle( wfMsg( 'wikilog-backlink', $link ) );
155167
156168 # Retrieve comments (or replies) from database and display them.
157 - $this->viewComments();
 169+ $this->viewComments( $query );
 170+
 171+ # Add feed links.
 172+ $wgOut->setSyndicated();
158173 }
159174
160175 /**
161176 * Wikilog comments view. Retrieve comments from database and display
162177 * them in threads.
163178 */
164 - protected function viewComments() {
 179+ protected function viewComments( WikilogCommentQuery $query ) {
165180 global $wgOut, $wgRequest;
166181
167182 # Prepare query and pager objects.
168183 $replyTo = $wgRequest->getInt( 'wlParent' );
169 - $query = new WikilogCommentQuery();
170 - $query->setItem( $this->mItem );
171184 $pager = new WikilogCommentThreadPager( $query, $this->mFormatter );
172185
173186 # Different behavior when displaying a single comment.
Index: trunk/extensions/Wikilog/Wikilog.i18n.php
@@ -118,6 +118,9 @@
119119 # Atom and RSS feeds
120120 'wikilog-feed-title' => '{{SITENAME}} - $1 [$2]', # $1 = title, $2 = content language
121121 'wikilog-feed-description' => 'Read the most recent posts in this feed.',
 122+ 'wikilog-comment-feed-title1' => 'Comment by $2 (#$1)',
 123+ 'wikilog-comment-feed-title2' => 'Comment by $2 to $3 (#$1)',
 124+ 'wikilog-comment-feed-description' => 'Read the most recent comments in this feed.',
122125
123126 # Item and comments page titles
124127 'wikilog-title-item-full' => '$1 - $2', # $1 = article title, $2 wikilog title
@@ -310,6 +313,13 @@
311314 * $2 is the wikilog title',
312315 'wikilog-title-comments' => 'Parameters:
313316 * $1 is a page title',
 317+ 'wikilog-comment-feed-title1' => 'Parameters:
 318+* $1 is a comment number (to make unique titles for different comments)
 319+* $2 is the commenter name',
 320+ 'wikilog-comment-feed-title2' => 'Parameters:
 321+* $1 is a comment number (to make unique titles for different comments)
 322+* $2 is the commenter name
 323+* $3 is the title of the article the comment was posted to',
314324 'wikilog-error-msg' => 'Parameters:
315325 * $1 is an error message',
316326 'wikilog-invalid-param' => 'Parameters:
Index: trunk/extensions/Wikilog/WikilogComment.php
@@ -703,8 +703,7 @@
704704 );
705705 } else {
706706 $authorPlain = htmlspecialchars( $comment->mAnonName );
707 - $authorFmt = wfMsgExt( 'wikilog-comment-anonsig',
708 - array( 'content', 'parseinline', 'replaceafter' ),
 707+ $authorFmt = wfMsgForContent( 'wikilog-comment-anonsig',
709708 Xml::wrapClass( $this->mSkin->userLink( $comment->mUserID, $comment->mUserText ), 'wl-comment-author' ),
710709 $this->mSkin->userTalkLink( $comment->mUserID, $comment->mUserText ),
711710 htmlspecialchars( $comment->mAnonName )

Status & tagging log