mlanthaler: Added support for conditional GETs for RSS feeds (added support for ETag an Last-Modified headers).

(merged from branches/gsoc)


git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@42105 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2007-09-16 15:56:15 +00:00
parent cc03b293ad
commit 98486e0450

View File

@ -1,11 +1,99 @@
<?php <?php
/**
* RSSFeed class
*
* This class is used to create an RSS feed.
*/
class RSSFeed extends ViewableData { class RSSFeed extends ViewableData {
protected $entries;
protected $title, $description, $link;
protected $titleField, $descriptionField, $authorField;
function __construct(DataObjectSet $entries, $link, $title, $description = null, $titleField = "Title", $descriptionField = "Content", $authorField = null) { /**
* Holds the feed entries
*
* @var DataObjectSet
*/
protected $entries;
/**
* Title of the feed
*
* @var string
*/
protected $title;
/**
* Description of the feed
*
* @var string
*/
protected $description;
/**
* Link to the feed
*
* @var string
*/
protected $link;
/**
* Name of the title field of feed entries
*
* @var string
*/
protected $titleField;
/**
* Name of the description field of feed entries
*
* @var string
*/
protected $descriptionField;
/**
Name of the author field of feed entries
*
* @var string
*/
protected $authorField;
/**
* Last modification of the RSS feed
*
* @var int Unix timestamp of the last modification
*/
protected $lastModified;
/**
* ETag for the RSS feed (used for client-site caching)
*
* @var string The value for the HTTP ETag header.
*/
protected $etag;
/**
* Constructor
*
* @param DataObjectSet $entries RSS feed entries
* @param string $link Link to the feed
* @param string $title Title of the feed
* @param string $description Description of the field
* @param string $titleField Name of the field that should be used for the
* titles for the feed entries
* @param string $descriptionField Name of the field that should be used
* for the description for the feed
* entries
* @param string $authorField Name of the field that should be used for
* the author for the feed entries
* @param int $lastModified Unix timestamp of the latest modification
* (latest posting)
* @param string $etag The ETag is an unique identifier that is changed
* every time the representation does
*/
function __construct(DataObjectSet $entries, $link, $title,
$description = null, $titleField = "Title",
$descriptionField = "Content", $authorField = null,
$lastModified = null, $etag = null) {
$this->entries = $entries; $this->entries = $entries;
$this->link = $link; $this->link = $link;
$this->description = $description; $this->description = $description;
@ -14,13 +102,31 @@ class RSSFeed extends ViewableData {
$this->titleField = $titleField; $this->titleField = $titleField;
$this->descriptionField = $descriptionField; $this->descriptionField = $descriptionField;
$this->authorField = $authorField; $this->authorField = $authorField;
$this->lastModified = $lastModified;
$this->etag = $etag;
} }
/**
* Include an link to the feed
*
* @param string $url URL of the feed
* @param string $title Title to show
*/
static function linkToFeed($url, $title = null) { static function linkToFeed($url, $title = null) {
$title = Convert::raw2xml($title); $title = Convert::raw2xml($title);
Requirements::insertHeadTags("<link rel=\"alternate\" type=\"application/rss+xml\" title=\"$title\" href=\"$url\" />"); Requirements::insertHeadTags(
'<link rel="alternate" type="application/rss+xml" title="' . $title .
'" href="' . $url . '" />');
} }
/**
* Get the RSS feed entries
*
* @return DataObjectSet Returns the {@link RSSFeed_Entry} objects.
*/
function Entries() { function Entries() {
$output = new DataObjectSet(); $output = new DataObjectSet();
foreach($this->entries as $entry) { foreach($this->entries as $entry) {
@ -29,52 +135,150 @@ class RSSFeed extends ViewableData {
return $output; return $output;
} }
/**
* Get the title of thisfeed
*
* @return string Returns the title of the feed.
*/
function Title() { function Title() {
return $this->title; return Convert::raw2xml($this->title);
} }
/**
* Get the URL of this feed
*
* @return string Returns the URL of the feed.
*/
function Link() { function Link() {
return Director::absoluteURL($this->link); return Director::absoluteURL($this->link);
} }
/**
* Get the description of this feed
*
* @return string Returns the description of the feed.
*/
function Description() { function Description() {
return $this->description; return Convert::raw2xml($this->description);
} }
/**
* Output the feed to the browser
*/
function outputToBrowser() { function outputToBrowser() {
if(is_int($this->lastModified)) {
HTTP::register_modification_timestamp($this->lastModified);
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT');
}
if(!empty($this->etag)) {
HTTP::register_etag($this->etag);
}
$body = str_replace('&nbsp;', '&#160;', $this->renderWith('RSSFeed'));
HTTP::add_cache_headers($body);
header("Content-type: text/xml"); header("Content-type: text/xml");
echo str_replace('&nbsp;', '&#160;', $this->renderWith('RSSFeed')); echo $body;
}
} }
}
/**
* RSSFeed_Entry class
*
* This class is used for entries of an RSS feed.
*
* @see RSSFeed
*/
class RSSFeed_Entry extends ViewableData { class RSSFeed_Entry extends ViewableData {
protected $titleField, $descriptionField, $authorField;
/**
* The object that represents the item, it contains all the data.
*
* @var mixed
*/
protected $failover;
/**
* Name of the title field of feed entries
*
* @var string
*/
protected $titleField;
/**
* Name of the description field of feed entries
*
* @var string
*/
protected $descriptionField;
/**
Name of the author field of feed entries
*
* @var string
*/
protected $authorField;
/** /**
* Create a new RSSFeed entry. * Create a new RSSFeed entry.
*/ */
function __construct($entry, $titleField, $descriptionField, $authorField) { function __construct($entry, $titleField, $descriptionField,
$authorField) {
$this->failover = $entry; $this->failover = $entry;
$this->titleField = $titleField; $this->titleField = $titleField;
$this->descriptionField = $descriptionField; $this->descriptionField = $descriptionField;
$this->authorField = $authorField; $this->authorField = $authorField;
} }
/**
* Get the description of this entry
*
* @return string Returns the description of the entry.
*/
function Title() { function Title() {
if($this->titleField) if($this->titleField)
return $this->failover->obj($this->titleField); return $this->failover->obj($this->titleField);
} }
/**
* Get the description of this entry
*
* @return string Returns the description of the entry.
*/
function Description() { function Description() {
if($this->descriptionField) if($this->descriptionField)
return $this->failover->obj($this->descriptionField); return $this->failover->obj($this->descriptionField);
} }
/**
* Get the author of this entry
*
* @return string Returns the author of the entry.
*/
function Author() { function Author() {
if($this->authorField) if($this->authorField)
return $this->failover->obj($this->authorField); return $this->failover->obj($this->authorField);
} }
/**
* Get a link to this entry
*
* @return string Returns the URL of this entry
*/
function AbsoluteLink() { function AbsoluteLink() {
return $this->failover->AbsoluteLink(); return $this->failover->AbsoluteLink();
} }
} }
?> ?>