-
Notifications
You must be signed in to change notification settings - Fork 821
/
RSSFeed.php
executable file
·305 lines (275 loc) · 6.86 KB
/
RSSFeed.php
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
<?php
/**
* RSSFeed class
*
* This class is used to create an RSS feed.
* @todo Improve documentation
* @package sapphire
* @subpackage integration
*/
class RSSFeed extends ViewableData {
/**
* Casting information for this object's methods.
* Let's us use $Title.XML in templates
*/
public static $casting = array(
"Title" => "Varchar",
"Description" => "Varchar",
);
/**
* 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->link = $link;
$this->description = $description;
$this->title = $title;
$this->titleField = $titleField;
$this->descriptionField = $descriptionField;
$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) {
$title = Convert::raw2xml($title);
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() {
$output = new DataObjectSet();
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.
*/
function Title() {
return $this->title;
}
/**
* Get the URL of this feed
*
* @return string Returns the URL of the feed.
*/
function Link() {
return Director::absoluteURL($this->link);
}
/**
* Get the description of this feed
*
* @return string Returns the description of the feed.
*/
function Description() {
return $this->description;
}
/**
* Output the feed to the browser
*/
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 = $this->feedContent();
HTTP::add_cache_headers();
header("Content-type: text/xml");
echo $body;
}
/**
* Return the content of the RSS feed
*/
function feedContent() {
SSViewer::set_source_file_comments(false);
return str_replace(' ', ' ', $this->renderWith('RSSFeed'));
}
}
/**
* RSSFeed_Entry class
*
* This class is used for entries of an RSS feed.
*
* @see RSSFeed
* @package sapphire
* @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.
*/
function __construct($entry, $titleField, $descriptionField,
$authorField) {
$this->failover = $entry;
$this->titleField = $titleField;
$this->descriptionField = $descriptionField;
$this->authorField = $authorField;
}
/**
* Get the description of this entry
*
* @return string Returns the description of the entry.
*/
function Title() {
return $this->rssField($this->titleField, 'Varchar');
}
/**
* Get the description of this entry
*
* @return string Returns the description of the entry.
*/
function Description() {
return $this->rssField($this->descriptionField, 'Text');
}
/**
* Get the author of this entry
*
* @return string Returns the author of the entry.
*/
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.
*/
function rssField($fieldName, $defaultClass = 'Varchar') {
if($fieldName) {
if($this->failover->castingHelperPair($fieldName)) {
return $this->failover->obj($fieldName);
} 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
*/
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 either an AbsoluteLink nor a Link method. Can't put a link in the RSS feed", E_USER_WARNING);
}
}
?>