X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2FFeed.php;h=0e715df2ff3c6b73129687f468e4df3fdaa7df76;hp=35f2ce94385383952a80ef1bd93c8c9605a35899;hb=46fa949b8b5e10b1843d4ea2930679a0d3999025;hpb=c16af68fb62948dd8079a7fa49b7c12b9a748121 diff --git a/includes/Feed.php b/includes/Feed.php index 35f2ce9438..0e715df2ff 100644 --- a/includes/Feed.php +++ b/includes/Feed.php @@ -84,13 +84,23 @@ class FeedItem { } /** - * Get the unique id of this item - * + * Get the unique id of this item; already xml-encoded + * @return string + */ + public function getUniqueID() { + $id = $this->getUniqueIDUnescaped(); + if ( $id ) { + return $this->xmlEncode( $id ); + } + } + + /** + * Get the unique id of this item, without any escaping * @return string */ - public function getUniqueId() { + public function getUniqueIdUnescaped() { if ( $this->uniqueId ) { - return $this->xmlEncode( wfExpandUrl( $this->uniqueId, PROTO_CURRENT ) ); + return wfExpandUrl( $this->uniqueId, PROTO_CURRENT ); } } @@ -123,6 +133,14 @@ class FeedItem { return $this->xmlEncode( $this->url ); } + /** Get the URL of this item without any escaping + * + * @return string + */ + public function getUrlUnescaped() { + return $this->url; + } + /** * Get the description of this item; already xml-encoded * @@ -132,6 +150,14 @@ class FeedItem { return $this->xmlEncode( $this->description ); } + /** + * Get the description of this item without any escaping + * + */ + public function getDescriptionUnescaped() { + return $this->description; + } + /** * Get the language of this item * @@ -160,6 +186,15 @@ class FeedItem { return $this->xmlEncode( $this->author ); } + /** + * Get the author of this item without any escaping + * + * @return string + */ + public function getAuthorUnescaped() { + return $this->author; + } + /** * Get the comment of this item; already xml-encoded * @@ -169,6 +204,15 @@ class FeedItem { return $this->xmlEncode( $this->comments ); } + /** + * Get the comment of this item without any escaping + * + * @return string + */ + public function getCommentsUnescaped() { + return $this->comments; + } + /** * Quickie hack... strip out wikilinks to more legible form from the comment. * @@ -187,6 +231,23 @@ class FeedItem { * @ingroup Feed */ abstract class ChannelFeed extends FeedItem { + + /** @var TemplateParser */ + protected $templateParser; + + /** + * @param string|Title $title Feed's title + * @param string $description + * @param string $url URL uniquely designating the feed. + * @param string $date Feed's date + * @param string $author Author's user name + * @param string $comments + */ + function __construct( $title, $description, $url, $date = '', $author = '', $comments = '' ) { + parent::__construct( $title, $description, $url, $date, $author, $comments ); + $this->templateParser = new TemplateParser(); + } + /** * Generate Header of the feed * @par Example: @@ -279,13 +340,15 @@ abstract class ChannelFeed extends FeedItem { class RSSFeed extends ChannelFeed { /** - * Format a date given a timestamp + * Format a date given a timestamp. If a timestamp is not given, nothing is returned * - * @param int $ts Timestamp - * @return string Date string + * @param int|null $ts Timestamp + * @return string|null Date string */ function formatTime( $ts ) { - return gmdate( 'D, d M Y H:i:s \G\M\T', wfTimestamp( TS_UNIX, $ts ) ); + if ( $ts ) { + return gmdate( 'D, d M Y H:i:s \G\M\T', wfTimestamp( TS_UNIX, $ts ) ); + } } /** @@ -295,15 +358,17 @@ class RSSFeed extends ChannelFeed { global $wgVersion; $this->outXmlHeader(); - ?> - - <?php print $this->getTitle() ?> - getUrl(), PROTO_CURRENT ) ?> - getDescription() ?> - getLanguage() ?> - MediaWiki - formatTime( wfTimestampNow() ) ?> - $this->getTitle(), + 'url' => $this->xmlEncode( wfExpandUrl( $this->getUrlUnescaped(), PROTO_CURRENT ) ), + 'description' => $this->getDescription(), + 'language' => $this->xmlEncode( $this->getLanguage() ), + 'version' => $this->xmlEncode( $wgVersion ), + 'timestamp' => $this->xmlEncode( $this->formatTime( wfTimestampNow() ) ) + ]; + print $this->templateParser->processTemplate( 'RSSHeader', $templateParams ); } /** @@ -311,28 +376,30 @@ class RSSFeed extends ChannelFeed { * @param FeedItem $item Item to be output */ function outItem( $item ) { - // @codingStandardsIgnoreStart Ignore long lines and formatting issues. - ?> - - <?php print $item->getTitle(); ?> - getUrl(), PROTO_CURRENT ); ?> - rssIsPermalink ) { print ' isPermaLink="false"'; } ?>>getUniqueId(); ?> - getDescription() ?> - getDate() ) { ?>formatTime( $item->getDate() ); ?> - getAuthor() ) { ?>getAuthor(); ?> - getComments() ) { ?>getComments(), PROTO_CURRENT ); ?> - - $item->getTitle(), + "url" => $this->xmlEncode( wfExpandUrl( $item->getUrlUnescaped(), PROTO_CURRENT ) ), + "permalink" => $item->rssIsPermalink, + "uniqueID" => $item->getUniqueId(), + "description" => $item->getDescription(), + "date" => $this->xmlEncode( $this->formatTime( $item->getDate() ) ), + "author" => $item->getAuthor() + ]; + $comments = $item->getCommentsUnescaped(); + if ( $comments ) { + $commentsEscaped = $this->xmlEncode( wfExpandUrl( $comments, PROTO_CURRENT ) ); + $templateParams["comments"] = $commentsEscaped; + } + print $this->templateParser->processTemplate( 'RSSItem', $templateParams ); } /** * Output an RSS 2.0 footer */ function outFooter() { - ?> - -"; } } @@ -343,14 +410,16 @@ class RSSFeed extends ChannelFeed { */ class AtomFeed extends ChannelFeed { /** - * Format a date given timestamp. + * Format a date given timestamp, if one is given. * - * @param string|int $timestamp - * @return string + * @param string|int|null $timestamp + * @return string|null */ function formatTime( $timestamp ) { - // need to use RFC 822 time format at least for rss2.0 - return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $timestamp ) ); + if ( $timestamp ) { + // need to use RFC 822 time format at least for rss2.0 + return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $timestamp ) ); + } } /** @@ -358,20 +427,20 @@ class AtomFeed extends ChannelFeed { */ function outHeader() { global $wgVersion; - $this->outXmlHeader(); - // @codingStandardsIgnoreStart Ignore long lines and formatting issues. - ?> - getFeedId() ?> - <?php print $this->getTitle() ?> - - - formatTime( wfTimestampNow() ) ?>Z - getDescription() ?> - MediaWiki - - $this->xmlEncode( $this->getLanguage() ), + 'feedID' => $this->getFeedID(), + 'title' => $this->getTitle(), + 'url' => $this->xmlEncode( wfExpandUrl( $this->getUrlUnescaped(), PROTO_CURRENT ) ), + 'selfUrl' => $this->getSelfUrl(), + 'timestamp' => $this->xmlEncode( $this->formatTime( wfTimestampNow() ) ), + 'description' => $this->getDescription(), + 'version' => $this->xmlEncode( $wgVersion ), + ]; + print $this->templateParser->processTemplate( 'AtomHeader', $templateParams ); } /** @@ -401,30 +470,24 @@ class AtomFeed extends ChannelFeed { */ function outItem( $item ) { global $wgMimeType; - // @codingStandardsIgnoreStart Ignore long lines and formatting issues. - ?> - - getUniqueId(); ?> - <?php print $item->getTitle(); ?> - - getDate() ) { ?> - formatTime( $item->getDate() ); ?>Z - - - getDescription() ?> - getAuthor() ) { ?>getAuthor(); ?> - - -getComments() ) { ?>getComments() ?> - */ + // Manually escaping rather than letting Mustache do it because Mustache + // uses htmlentities, which does not work with XML + $templateParams = [ + "uniqueID" => $item->getUniqueId(), + "title" => $item->getTitle(), + "mimeType" => $this->xmlEncode( $wgMimeType ), + "url" => $this->xmlEncode( wfExpandUrl( $item->getUrlUnescaped(), PROTO_CURRENT ) ), + "date" => $this->xmlEncode( $this->formatTime( $item->getDate() ) ), + "description" => $item->getDescription(), + "author" => $item->getAuthor() + ]; + print $this->templateParser->processTemplate( 'AtomItem', $templateParams ); } /** * Outputs the footer for Atom 1.0 feed (basically '\'). */ - function outFooter() {?> - "; } }