Version: current

      1 <?php
      2 /**
      3  * RSSFeed class
      4  *
      5  * This class is used to create an RSS feed.
      6  * @todo Improve documentation
      7  * @package sapphire
      8  * @subpackage integration
      9  */
     10 class RSSFeed extends ViewableData {
     11     /**
     12      * Casting information for this object's methods.
     13      * Let's us use $Title.XML in templates
     14      */
     15     public static $casting = array(
     16         "Title" => "Varchar",
     17         "Description" => "Varchar",
     18     );
     19
     20     /**
     21      * Holds the feed entries
     22      *
     23      * @var DataObjectSet
     24      */
     25     protected $entries;
     26
     27     /**
     28      * Title of the feed
     29      *
     30      * @var string
     31      */
     32     protected $title;
     33
     34     /**
     35      * Description of the feed
     36      *
     37      * @var string
     38      */
     39     protected $description;
     40
     41     /**
     42      * Link to the feed
     43      *
     44      * @var string
     45      */
     46     protected $link;
     47
     48     /**
     49      * Name of the title field of feed entries
     50      *
     51      * @var string
     52      */
     53     protected $titleField;
     54
     55     /**
     56      * Name of the description field of feed entries
     57      *
     58      * @var string
     59      */
     60     protected $descriptionField;
     61
     62     /**
     63      * Name of the author field of feed entries
     64      *
     65      * @var string
     66      */
     67     protected $authorField;
     68
     69     /**
     70      * Last modification of the RSS feed
     71      *
     72      * @var int Unix timestamp of the last modification
     73      */
     74     protected $lastModified;
     75
     76     /**
     77      * ETag for the RSS feed (used for client-site caching)
     78      *
     79      * @var string The value for the HTTP ETag header.
     80      */
     81     protected $etag;
     82
     83     /**
     84      * Constructor
     85      *
     86      * @param DataObjectSet $entries RSS feed entries
     87      * @param string $link Link to the feed
     88      * @param string $title Title of the feed
     89      * @param string $description Description of the field
     90      * @param string $titleField Name of the field that should be used for the
     91      *                           titles for the feed entries
     92      * @param string $descriptionField Name of the field that should be used
     93      *                                 for the description for the feed
     94      *                                 entries
     95      * @param string $authorField Name of the field that should be used for
     96      *                            the author for the feed entries
     97      * @param int $lastModified Unix timestamp of the latest modification
     98      *                          (latest posting)
     99      * @param string $etag The ETag is an unique identifier that is changed
    100      *                         every time the representation does
    101      */
    102     function __construct(DataObjectSet $entries, $link, $title,
    103                                              $description = null, $titleField = "Title",
    104                                              $descriptionField = "Content", $authorField = null,
    105                                              $lastModified = null, $etag = null) {
    106         $this->entries = $entries;
    107         $this->link = $link;
    108         $this->description = $description;
    109         $this->title = $title;
    110
    111         $this->titleField = $titleField;
    112         $this->descriptionField = $descriptionField;
    113         $this->authorField = $authorField;
    114
    115         $this->lastModified = $lastModified;
    116         $this->etag = $etag;
    117
    118         parent::__construct();
    119     }
    120
    121     /**
    122      * Include an link to the feed
    123      *
    124      * @param string $url URL of the feed
    125      * @param string $title Title to show
    126      */
    127     static function linkToFeed($url, $title = null) {
    128         $title = Convert::raw2xml($title);
    129         Requirements::insertHeadTags(
    130             '<link rel="alternate" type="application/rss+xml" title="' . $title .
    131             '" href="' . $url . '" />');
    132     }
    133
    134     /**
    135      * Get the RSS feed entries
    136      *
    137      * @return DataObjectSet Returns the {@link RSSFeed_Entry} objects.
    138      */
    139     function Entries() {
    140         $output = new DataObjectSet();
    141         if(isset($this->entries)) {
    142             foreach($this->entries as $entry) {
    143                 $output->push(new RSSFeed_Entry($entry, $this->titleField, $this->descriptionField, $this->authorField));
    144             }
    145         }
    146         return $output;
    147     }
    148
    149     /**
    150      * Get the title of thisfeed
    151      *
    152      * @return string Returns the title of the feed.
    153      */
    154     function Title() {
    155         return $this->title;
    156     }
    157
    158     /**
    159      * Get the URL of this feed
    160      *
    161      * @param string $action
    162      * @return string Returns the URL of the feed.
    163      */
    164     function Link($action = null) {
    165         return Controller::join_links(Director::absoluteURL($this->link), $action);
    166     }
    167
    168     /**
    169      * Get the description of this feed
    170      *
    171      * @return string Returns the description of the feed.
    172      */
    173     function Description() {
    174         return $this->description;
    175     }
    176
    177     /**
    178      * Output the feed to the browser
    179      */
    180     function outputToBrowser() {
    181         if(is_int($this->lastModified)) {
    182             HTTP::register_modification_timestamp($this->lastModified);
    183             header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT');
    184         }
    185         if(!empty($this->etag)) {
    186             HTTP::register_etag($this->etag);
    187         }
    188
    189         $body = $this->feedContent();
    190         HTTP::add_cache_headers();
    191         header("Content-type: text/xml");
    192         echo $body;
    193     }
    194
    195     /**
    196      * Return the content of the RSS feed
    197      */
    198     function feedContent() {
    199         SSViewer::set_source_file_comments(false);
    200         return str_replace('&nbsp;', '&#160;', $this->renderWith('RSSFeed'));
    201     }
    202 }
    203
    204 /**
    205  * RSSFeed_Entry class
    206  *
    207  * This class is used for entries of an RSS feed.
    208  *
    209  * @see RSSFeed
    210  * @package sapphire
    211  * @subpackage integration
    212  */
    213 class RSSFeed_Entry extends ViewableData {
    214     /**
    215      * The object that represents the item, it contains all the data.
    216      *
    217      * @var mixed
    218      */
    219     protected $failover;
    220
    221     /**
    222      * Name of the title field of feed entries
    223      *
    224      * @var string
    225      */
    226     protected $titleField;
    227
    228     /**
    229      * Name of the description field of feed entries
    230      *
    231      * @var string
    232      */
    233     protected $descriptionField;
    234
    235     /**
    236      * Name of the author field of feed entries
    237      *
    238      * @var string
    239      */
    240     protected $authorField;
    241
    242     /**
    243      * Create a new RSSFeed entry.
    244      */
    245     function __construct($entry, $titleField, $descriptionField,
    246                                              $authorField) {
    247         $this->failover = $entry;
    248         $this->titleField = $titleField;
    249         $this->descriptionField = $descriptionField;
    250         $this->authorField = $authorField;
    251
    252         parent::__construct();
    253     }
    254
    255     /**
    256      * Get the description of this entry
    257      *
    258      * @return string Returns the description of the entry.
    259      */
    260     function Title() {
    261         return $this->rssField($this->titleField, 'Varchar');
    262     }
    263
    264     /**
    265      * Get the description of this entry
    266      *
    267      * @return string Returns the description of the entry.
    268      */
    269     function Description() {
    270         return $this->rssField($this->descriptionField, 'Text');
    271     }
    272
    273     /**
    274      * Get the author of this entry
    275      *
    276      * @return string Returns the author of the entry.
    277      */
    278     function Author() {
    279         if($this->authorField) return $this->failover->obj($this->authorField);
    280     }
    281
    282     /**
    283      * Return the named field as an obj() call from $this->failover.
    284      * Default to the given class if there's no casting information.
    285      */
    286     function rssField($fieldName, $defaultClass = 'Varchar') {
    287         if($fieldName) {
    288             if($this->failover->castingHelper($fieldName)) {
    289                 $value = $this->failover->$fieldName;
    290                 $obj = $this->failover->obj($fieldName);
    291                 $obj->setValue($value);
    292                 return $obj;
    293             } else {
    294                 $obj = new $defaultClass($fieldName);
    295                 $obj->setValue($this->failover->XML_val($fieldName));
    296                 return $obj;
    297             }
    298         }
    299     }
    300
    301     /**
    302      * Get a link to this entry
    303      *
    304      * @return string Returns the URL of this entry
    305      */
    306     function AbsoluteLink() {
    307         if($this->failover->hasMethod('AbsoluteLink')) return $this->failover->AbsoluteLink();
    308         else if($this->failover->hasMethod('Link')) return Director::absoluteURL($this->failover->Link());
    309         else user_error($this->failover->class . " object has either an AbsoluteLink nor a Link method.  Can't put a link in the RSS feed", E_USER_WARNING);
    310     }
    311 }
    312 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -