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