2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2016-06-15 06:03:16 +02:00
|
|
|
|
|
|
|
use SilverStripe\ORM\SS_List;
|
|
|
|
use SilverStripe\ORM\ArrayList;
|
|
|
|
use SilverStripe\ORM\FieldType\DBField;
|
2016-06-03 10:34:59 +02:00
|
|
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2007-09-16 17:56:15 +02:00
|
|
|
/**
|
|
|
|
* RSSFeed class
|
|
|
|
*
|
|
|
|
* This class is used to create an RSS feed.
|
2008-03-03 00:24:10 +01:00
|
|
|
* @todo Improve documentation
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-02-25 03:10:37 +01:00
|
|
|
* @subpackage integration
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
class RSSFeed extends ViewableData {
|
2012-07-01 11:25:57 +02:00
|
|
|
|
2008-02-25 03:10:37 +01:00
|
|
|
/**
|
|
|
|
* Casting information for this object's methods.
|
|
|
|
* Let's us use $Title.XML in templates
|
|
|
|
*/
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $casting = array(
|
2008-02-25 03:10:37 +01:00
|
|
|
"Title" => "Varchar",
|
|
|
|
"Description" => "Varchar",
|
2015-11-01 23:33:04 +01:00
|
|
|
"Link" => "Varchar",
|
2008-02-25 03:10:37 +01:00
|
|
|
);
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Holds the feed entries
|
|
|
|
*
|
2011-10-26 08:09:04 +02:00
|
|
|
* @var SS_List
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $entries;
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
/**
|
2008-02-25 03:10:37 +01:00
|
|
|
* Name of the author field of feed entries
|
2007-09-16 17:56:15 +02:00
|
|
|
*
|
|
|
|
* @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;
|
|
|
|
|
2012-07-01 11:25:57 +02:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $template = 'RSSFeed';
|
|
|
|
|
2007-09-16 17:56:15 +02:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
2011-10-26 08:09:04 +02:00
|
|
|
* @param SS_List $entries RSS feed entries
|
2007-09-16 17:56:15 +02:00
|
|
|
* @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
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function __construct(SS_List $entries, $link, $title,
|
2012-12-08 12:20:20 +01:00
|
|
|
$description = null, $titleField = "Title",
|
|
|
|
$descriptionField = "Content", $authorField = null,
|
|
|
|
$lastModified = null, $etag = null) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->entries = $entries;
|
|
|
|
$this->link = $link;
|
|
|
|
$this->description = $description;
|
|
|
|
$this->title = $title;
|
2007-09-16 17:56:15 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->titleField = $titleField;
|
|
|
|
$this->descriptionField = $descriptionField;
|
|
|
|
$this->authorField = $authorField;
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
$this->lastModified = $lastModified;
|
|
|
|
$this->etag = $etag;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-09-18 05:02:19 +02:00
|
|
|
parent::__construct();
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Include an link to the feed
|
|
|
|
*
|
|
|
|
* @param string $url URL of the feed
|
|
|
|
* @param string $title Title to show
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public static function linkToFeed($url, $title = null) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$title = Convert::raw2xml($title);
|
2007-09-16 17:56:15 +02:00
|
|
|
Requirements::insertHeadTags(
|
|
|
|
'<link rel="alternate" type="application/rss+xml" title="' . $title .
|
|
|
|
'" href="' . $url . '" />');
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the RSS feed entries
|
|
|
|
*
|
2011-10-26 08:09:04 +02:00
|
|
|
* @return SS_List Returns the {@link RSSFeed_Entry} objects.
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Entries() {
|
2011-05-05 12:40:24 +02:00
|
|
|
$output = new ArrayList();
|
2012-07-31 10:38:12 +02:00
|
|
|
|
2007-10-26 07:28:05 +02:00
|
|
|
if(isset($this->entries)) {
|
|
|
|
foreach($this->entries as $entry) {
|
2012-09-26 23:34:00 +02:00
|
|
|
$output->push(
|
2016-01-22 19:29:44 +01:00
|
|
|
RSSFeed_Entry::create($entry, $this->titleField, $this->descriptionField, $this->authorField));
|
2014-08-15 08:53:05 +02:00
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the title of thisfeed
|
|
|
|
*
|
|
|
|
* @return string Returns the title of the feed.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Title() {
|
2007-09-16 18:00:07 +02:00
|
|
|
return $this->title;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the URL of this feed
|
|
|
|
*
|
2009-10-11 02:07:16 +02:00
|
|
|
* @param string $action
|
2007-09-16 17:56:15 +02:00
|
|
|
* @return string Returns the URL of the feed.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Link($action = null) {
|
2009-10-11 02:07:16 +02:00
|
|
|
return Controller::join_links(Director::absoluteURL($this->link), $action);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the description of this feed
|
|
|
|
*
|
|
|
|
* @return string Returns the description of the feed.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Description() {
|
2007-09-16 18:00:07 +02:00
|
|
|
return $this->description;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
2016-01-22 19:29:44 +01:00
|
|
|
* Output the feed to the browser.
|
|
|
|
*
|
|
|
|
* TODO: Pass $response object to ->outputToBrowser() to loosen dependence on global state for easier testing/prototyping so dev can inject custom SS_HTTPResponse instance.
|
|
|
|
*
|
2016-06-03 10:34:59 +02:00
|
|
|
* @return DBHTMLText
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-07-31 10:38:12 +02:00
|
|
|
public function outputToBrowser() {
|
2013-03-21 19:48:54 +01:00
|
|
|
$prevState = Config::inst()->get('SSViewer', 'source_file_comments');
|
|
|
|
Config::inst()->update('SSViewer', 'source_file_comments', false);
|
2012-07-31 10:38:12 +02:00
|
|
|
|
2013-02-05 17:11:28 +01:00
|
|
|
$response = Controller::curr()->getResponse();
|
|
|
|
|
2007-09-16 17:56:15 +02:00
|
|
|
if(is_int($this->lastModified)) {
|
|
|
|
HTTP::register_modification_timestamp($this->lastModified);
|
2013-02-05 17:11:28 +01:00
|
|
|
$response->addHeader("Last-Modified", gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT');
|
2007-09-16 17:56:15 +02:00
|
|
|
}
|
|
|
|
if(!empty($this->etag)) {
|
|
|
|
HTTP::register_etag($this->etag);
|
|
|
|
}
|
|
|
|
|
2012-07-31 10:38:12 +02:00
|
|
|
if(!headers_sent()) {
|
|
|
|
HTTP::add_cache_headers();
|
2014-08-29 10:04:44 +02:00
|
|
|
$response->addHeader("Content-Type", "application/rss+xml; charset=utf-8");
|
2012-07-31 10:38:12 +02:00
|
|
|
}
|
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
Config::inst()->update('SSViewer', 'source_file_comments', $prevState);
|
2012-07-31 10:38:12 +02:00
|
|
|
|
|
|
|
return $this->renderWith($this->getTemplate());
|
2008-03-21 06:58:50 +01:00
|
|
|
}
|
2012-07-01 11:25:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the name of the template to use. Actual template will be resolved
|
|
|
|
* via the standard template inclusion process.
|
|
|
|
*
|
|
|
|
* @param string
|
|
|
|
*/
|
|
|
|
public function setTemplate($template) {
|
|
|
|
$this->template = $template;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the name of the template to use.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getTemplate() {
|
|
|
|
return $this->template;
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
2007-09-16 17:56:15 +02:00
|
|
|
/**
|
|
|
|
* RSSFeed_Entry class
|
|
|
|
*
|
|
|
|
* This class is used for entries of an RSS feed.
|
|
|
|
*
|
|
|
|
* @see RSSFeed
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-02-25 03:10:37 +01:00
|
|
|
* @subpackage integration
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
class RSSFeed_Entry extends ViewableData {
|
2007-09-16 17:56:15 +02:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
/**
|
2008-02-25 03:10:37 +01:00
|
|
|
* Name of the author field of feed entries
|
2007-09-16 17:56:15 +02:00
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $authorField;
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Create a new RSSFeed entry.
|
2016-06-03 10:34:59 +02:00
|
|
|
* @param ViewableData $entry
|
|
|
|
* @param string $titleField
|
|
|
|
* @param string $descriptionField
|
|
|
|
* @param string $authorField
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2016-06-03 10:34:59 +02:00
|
|
|
public function __construct($entry, $titleField, $descriptionField, $authorField) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->failover = $entry;
|
|
|
|
$this->titleField = $titleField;
|
|
|
|
$this->descriptionField = $descriptionField;
|
|
|
|
$this->authorField = $authorField;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-09-18 05:02:19 +02:00
|
|
|
parent::__construct();
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the description of this entry
|
|
|
|
*
|
2016-06-03 10:51:02 +02:00
|
|
|
* @return DBField Returns the description of the entry.
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Title() {
|
2016-06-03 10:51:02 +02:00
|
|
|
return $this->rssField($this->titleField);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the description of this entry
|
|
|
|
*
|
2016-06-03 10:51:02 +02:00
|
|
|
* @return DBField Returns the description of the entry.
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Description() {
|
2016-06-17 08:49:23 +02:00
|
|
|
$description = $this->rssField($this->descriptionField);
|
|
|
|
|
|
|
|
// HTML fields need links re-written
|
|
|
|
if($description instanceof DBHTMLText) {
|
|
|
|
return $description->obj('AbsoluteLinks');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $description;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the author of this entry
|
|
|
|
*
|
2016-06-03 10:51:02 +02:00
|
|
|
* @return DBField Returns the author of the entry.
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function Author() {
|
2016-06-03 10:51:02 +02:00
|
|
|
return $this->rssField($this->authorField);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2007-09-16 17:56:15 +02:00
|
|
|
|
2008-03-21 06:58:50 +01:00
|
|
|
/**
|
2016-06-03 10:51:02 +02:00
|
|
|
* Return the safely casted field
|
|
|
|
*
|
|
|
|
* @param string $fieldName Name of field
|
|
|
|
* @return DBField
|
2008-03-21 06:58:50 +01:00
|
|
|
*/
|
2016-06-03 10:51:02 +02:00
|
|
|
public function rssField($fieldName) {
|
2008-03-21 06:58:50 +01:00
|
|
|
if($fieldName) {
|
2016-06-03 10:51:02 +02:00
|
|
|
return $this->failover->obj($fieldName);
|
2008-03-21 06:58:50 +01:00
|
|
|
}
|
2016-06-03 10:51:02 +02:00
|
|
|
return null;
|
2008-03-21 06:58:50 +01:00
|
|
|
}
|
|
|
|
|
2007-09-16 17:56:15 +02:00
|
|
|
/**
|
|
|
|
* Get a link to this entry
|
|
|
|
*
|
|
|
|
* @return string Returns the URL of this entry
|
2016-06-03 10:34:59 +02:00
|
|
|
* @throws BadMethodCallException
|
2007-09-16 17:56:15 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function AbsoluteLink() {
|
2012-09-26 23:34:00 +02:00
|
|
|
if($this->failover->hasMethod('AbsoluteLink')) {
|
|
|
|
return $this->failover->AbsoluteLink();
|
|
|
|
} else if($this->failover->hasMethod('Link')) {
|
|
|
|
return Director::absoluteURL($this->failover->Link());
|
|
|
|
}
|
2016-06-03 10:34:59 +02:00
|
|
|
|
|
|
|
throw new BadMethodCallException(
|
|
|
|
$this->failover->class .
|
|
|
|
" object has neither an AbsoluteLink nor a Link method." .
|
|
|
|
" Can't put a link in the RSS feed", E_USER_WARNING
|
|
|
|
);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
}
|