Index: trunk/phase3/includes/SpecialRecentchanges.php |
— | — | @@ -614,27 +614,41 @@ |
615 | 615 | * Format a diff for the newsfeed |
616 | 616 | */ |
617 | 617 | function rcFormatDiff( $row ) { |
618 | | - global $wgFeedDiffCutoff, $wgContLang; |
| 618 | + $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title ); |
| 619 | + return rcFormatDiffRow( $titleObj, |
| 620 | + $row->rc_last_oldid, $row->rc_this_oldid, |
| 621 | + $row->rc_timestamp, |
| 622 | + $row->rc_comment ); |
| 623 | +} |
| 624 | + |
| 625 | +function rcFormatDiffRow( $title, $oldid, $newid, $timestamp, $comment ) { |
| 626 | + global $wgFeedDiffCutoff, $wgContLang, $wgUser; |
619 | 627 | $fname = 'rcFormatDiff'; |
620 | 628 | wfProfileIn( $fname ); |
621 | 629 | |
622 | 630 | require_once( 'DifferenceEngine.php' ); |
623 | | - $completeText = '<p>' . htmlspecialchars( $row->rc_comment ) . "</p>\n"; |
| 631 | + $skin = $wgUser->getSkin(); |
| 632 | + $completeText = '<p>' . $skin->formatComment( $comment ) . "</p>\n"; |
624 | 633 | |
625 | | - if( $row->rc_namespace >= 0 ) { |
626 | | - if( $row->rc_last_oldid ) { |
| 634 | + if( $title->getNamespace() >= 0 ) { |
| 635 | + if( $oldid ) { |
627 | 636 | wfProfileIn( "$fname-dodiff" ); |
628 | 637 | |
629 | | - $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title ); |
630 | | - $de = new DifferenceEngine( $titleObj, $row->rc_last_oldid, $row->rc_this_oldid ); |
631 | | - $diffText = $de->getDiff( wfMsg( 'revisionasof', $wgContLang->timeanddate( $row->rc_timestamp ) ), |
632 | | - wfMsg( 'currentrev' ) ); |
| 638 | + $de = new DifferenceEngine( $title, $oldid, $newid ); |
| 639 | + #$diffText = $de->getDiff( wfMsg( 'revisionasof', |
| 640 | + # $wgContLang->timeanddate( $timestamp ) ), |
| 641 | + # wfMsg( 'currentrev' ) ); |
| 642 | + $diffText = $de->getDiff( |
| 643 | + wfMsg( 'previousrevision' ), // hack |
| 644 | + wfMsg( 'revisionasof', |
| 645 | + $wgContLang->timeanddate( $timestamp ) ) ); |
| 646 | + |
633 | 647 | |
634 | 648 | if ( strlen( $diffText ) > $wgFeedDiffCutoff ) { |
635 | 649 | // Omit large diffs |
636 | | - $diffLink = $titleObj->escapeFullUrl( |
637 | | - 'diff=' . $row->rc_this_oldid . |
638 | | - '&oldid=' . $row->rc_last_oldid ); |
| 650 | + $diffLink = $title->escapeFullUrl( |
| 651 | + 'diff=' . $newid . |
| 652 | + '&oldid=' . $oldid ); |
639 | 653 | $diffText = '<a href="' . |
640 | 654 | $diffLink . |
641 | 655 | '">' . |
— | — | @@ -642,7 +656,7 @@ |
643 | 657 | '</a>'; |
644 | 658 | } elseif ( $diffText === false ) { |
645 | 659 | // Error in diff engine, probably a missing revision |
646 | | - $diffText = "<p>Can't load revision $row->rc_this_oldid</p>"; |
| 660 | + $diffText = "<p>Can't load revision $newid</p>"; |
647 | 661 | } else { |
648 | 662 | // Diff output fine, clean up any illegal UTF-8 |
649 | 663 | $diffText = UtfNormal::cleanUp( $diffText ); |
— | — | @@ -650,7 +664,7 @@ |
651 | 665 | } |
652 | 666 | wfProfileOut( "$fname-dodiff" ); |
653 | 667 | } else { |
654 | | - $rev = Revision::newFromId( $row->rc_this_oldid ); |
| 668 | + $rev = Revision::newFromId( $newid ); |
655 | 669 | if( is_null( $rev ) ) { |
656 | 670 | $newtext = ''; |
657 | 671 | } else { |
Index: trunk/phase3/includes/PageHistory.php |
— | — | @@ -71,7 +71,14 @@ |
72 | 72 | $wgOut->setArticleFlag( false ); |
73 | 73 | $wgOut->setArticleRelated( true ); |
74 | 74 | $wgOut->setRobotpolicy( 'noindex,nofollow' ); |
| 75 | + $wgOut->setSyndicated( true ); |
75 | 76 | |
| 77 | + $feedType = $wgRequest->getVal( 'feed' ); |
| 78 | + if( $feedType ) { |
| 79 | + wfProfileOut( $fname ); |
| 80 | + return $this->feed( $feedType ); |
| 81 | + } |
| 82 | + |
76 | 83 | /* |
77 | 84 | * Fail if article doesn't exist. |
78 | 85 | */ |
— | — | @@ -562,8 +569,93 @@ |
563 | 570 | $this->mTitle, $text, |
564 | 571 | wfArrayToCGI( $query, array( 'action' => 'history' ))); |
565 | 572 | } |
| 573 | + |
| 574 | + |
| 575 | + /** |
| 576 | + * Output a subscription feed listing recent edits to this page. |
| 577 | + * @param string $type |
| 578 | + */ |
| 579 | + function feed( $type ) { |
| 580 | + require_once 'Feed.php'; |
| 581 | + require_once 'SpecialRecentchanges.php'; |
| 582 | + |
| 583 | + global $wgFeedClasses; |
| 584 | + if( !isset( $wgFeedClasses[$type] ) ) { |
| 585 | + global $wgOut; |
| 586 | + $wgOut->addWikiText( wfMsg( 'feed-invalid' ) ); |
| 587 | + return; |
| 588 | + } |
| 589 | + |
| 590 | + $feed = new $wgFeedClasses[$type]( |
| 591 | + $this->mTitle->getPrefixedText() . ' - ' . wfMsg( 'revhistory' ), |
| 592 | + 'Revision history for this page on the wiki', |
| 593 | + $this->mTitle->getFullUrl( 'action=history' ) ); |
566 | 594 | |
| 595 | + $items = $this->fetchRevisions(10, 0, DIR_NEXT); |
| 596 | + $feed->outHeader(); |
| 597 | + if( $items ) { |
| 598 | + foreach( $items as $row ) { |
| 599 | + $feed->outItem( $this->feedItem( $row ) ); |
| 600 | + } |
| 601 | + } else { |
| 602 | + $feed->outItem( $this->feedEmpty() ); |
| 603 | + } |
| 604 | + $feed->outFooter(); |
| 605 | + } |
| 606 | + |
| 607 | + function feedEmpty() { |
| 608 | + global $wgOut; |
| 609 | + return new FeedItem( |
| 610 | + wfMsgForContent( 'nohistory' ), |
| 611 | + $wgOut->parse( wfMsgForContent( 'history-feed-empty' ) ), |
| 612 | + $this->mTitle->getFullUrl(), |
| 613 | + wfTimestamp( TS_MW ), |
| 614 | + '', |
| 615 | + $this->mTitle->getTalkPage()->getFullUrl() ); |
| 616 | + } |
| 617 | + |
| 618 | + /** |
| 619 | + * Generate a FeedItem object from a given revision table row |
| 620 | + * Borrows Recent Changes' feed generation functions for formatting; |
| 621 | + * includes a diff to the previous revision (if any). |
| 622 | + * |
| 623 | + * @param $row |
| 624 | + * @return FeedItem |
| 625 | + */ |
| 626 | + function feedItem( $row ) { |
| 627 | + $rev = new Revision( $row ); |
| 628 | + $text = rcFormatDiffRow( $this->mTitle, |
| 629 | + $this->mTitle->getPreviousRevisionID( $rev->getId() ), |
| 630 | + $rev->getId(), |
| 631 | + $rev->getTimestamp(), |
| 632 | + $rev->getComment() ); |
| 633 | + |
| 634 | + if( $rev->getComment() == '' ) { |
| 635 | + global $wgContLang; |
| 636 | + $title = wfMsgForContent( 'history-feed-item-nocomment', |
| 637 | + $rev->getUserText(), |
| 638 | + $wgContLang->timeanddate( $rev->getTimestamp() ) ); |
| 639 | + } else { |
| 640 | + $title = $rev->getUserText() . ": " . $this->stripComment( $rev->getComment() ); |
| 641 | + } |
567 | 642 | |
| 643 | + return new FeedItem( |
| 644 | + $title, |
| 645 | + $text, |
| 646 | + $this->mTitle->getFullUrl( 'diff=' . $rev->getId() . '&oldid=prev' ), |
| 647 | + $rev->getTimestamp(), |
| 648 | + $rev->getUserText(), |
| 649 | + $this->mTitle->getTalkPage()->getFullUrl() ); |
| 650 | + } |
| 651 | + |
| 652 | + /** |
| 653 | + * Quickie hack... strip out wikilinks to more legible form from the comment. |
| 654 | + */ |
| 655 | + function stripComment( $text ) { |
| 656 | + return preg_replace( '/\[\[([^]]*\|)?([^]]+)\]\]/', '\2', $text ); |
| 657 | + } |
| 658 | + |
| 659 | + |
568 | 660 | } |
569 | 661 | |
570 | 662 | ?> |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -367,6 +367,9 @@ |
368 | 368 | allow the including parser to do it. |
369 | 369 | * Fix {{int:}} to use content language, so it won't break caches and links |
370 | 370 | tables and randomly include data from the wrong language. |
| 371 | +* (bug 472) Syndication feeds for the last few edits of page history |
| 372 | +* Format edit comments in Recent Changes feed |
| 373 | +* Switch incorrectly ordered column headers on Recent Changes feed diffs |
371 | 374 | |
372 | 375 | |
373 | 376 | == Compatibility == |
Index: trunk/phase3/languages/Messages.php |
— | — | @@ -251,6 +251,7 @@ |
252 | 252 | 'viewdeleted' => 'View $1?', |
253 | 253 | 'restorelink' => '{{PLURAL:$1|one deleted edit|$1 deleted edits}}', |
254 | 254 | 'feedlinks' => 'Feed:', |
| 255 | +'feed-invalid' => 'Invalid subscription feed type.', |
255 | 256 | 'sitenotice' => '-', # the equivalent to wgSiteNotice |
256 | 257 | 'anonnotice' => '-', |
257 | 258 | |
— | — | @@ -589,6 +590,11 @@ |
590 | 591 | #'rev-delundel' => 'del/undel', |
591 | 592 | 'rev-delundel' => 'show/hide', |
592 | 593 | |
| 594 | +'history-feed-item-nocomment' => '$1 at $2', # user at time |
| 595 | +'history-feed-empty' => 'The requested page doesn\'t exist. |
| 596 | +It may have been deleted from the wiki, or renamed. |
| 597 | +Try [[Special:Search|searching on the wiki]] for relevant new pages.', |
| 598 | + |
593 | 599 | # Revision deletion |
594 | 600 | # |
595 | 601 | 'revisiondelete' => 'Delete/undelete revisions', |