X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FFeed.php;h=92eec0830a94e315fd4262449354302e40ac75b9;hb=abcd62f59c21fe5d720cb43a11f152bc622a4936;hp=bc7747fe7297f6412e7744e0b2a94416ab210eca;hpb=ea0bd74a94444fc0bbf7f6c8637e84d4d70b68d6;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/Feed.php b/includes/Feed.php
index bc7747fe72..92eec0830a 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,15 @@ class FeedItem {
return $this->xmlEncode( $this->description );
}
+ /**
+ * Get the description of this item without any escaping
+ *
+ * @return string
+ */
+ public function getDescriptionUnescaped() {
+ return $this->description;
+ }
+
/**
* Get the language of this item
*
@@ -160,6 +187,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 +205,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 +232,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:
@@ -230,6 +292,13 @@ abstract class ChannelFeed extends FeedItem {
$wgOut->disable();
$mimetype = $this->contentType();
header( "Content-type: $mimetype; charset=UTF-8" );
+
+ // Set a sane filename
+ $exts = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer()
+ ->getExtensionsForType( $mimetype );
+ $ext = $exts ? strtok( $exts, ' ' ) : 'xml';
+ header( "Content-Disposition: inline; filename=\"feed.{$ext}\"" );
+
if ( $wgVaryOnXFP ) {
$wgOut->addVaryHeader( 'X-Forwarded-Proto' );
}
@@ -272,13 +341,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 ) );
+ }
}
/**
@@ -288,15 +359,17 @@ class RSSFeed extends ChannelFeed {
global $wgVersion;
$this->outXmlHeader();
- ?>
-
- 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 );
}
/**
@@ -304,28 +377,30 @@ class RSSFeed extends ChannelFeed {
* @param FeedItem $item Item to be output
*/
function outItem( $item ) {
- // @codingStandardsIgnoreStart Ignore long lines and formatting issues.
- ?>
- -
- 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() {
- ?>
-
-";
}
}
@@ -336,14 +411,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 ) );
+ }
}
/**
@@ -351,20 +428,20 @@ class AtomFeed extends ChannelFeed {
*/
function outHeader() {
global $wgVersion;
-
$this->outXmlHeader();
- // @codingStandardsIgnoreStart Ignore long lines and formatting issues.
- ?>
- getFeedId() ?>
- 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 );
}
/**
@@ -394,30 +471,24 @@ class AtomFeed extends ChannelFeed {
*/
function outItem( $item ) {
global $wgMimeType;
- // @codingStandardsIgnoreStart Ignore long lines and formatting issues.
- ?>
-
- getUniqueId(); ?>
- 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() {?>
- ";
}
}