Completed
Push — master ( 10f429...3b71b7 )
by Ingo
11:44
created

RSSFeed::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 9
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
use SilverStripe\ORM\SS_List;
4
use SilverStripe\ORM\ArrayList;
5
use SilverStripe\ORM\FieldType\DBField;
6
use SilverStripe\ORM\FieldType\DBHTMLText;
7
8
/**
9
 * RSSFeed class
10
 *
11
 * This class is used to create an RSS feed.
12
 * @todo Improve documentation
13
 * @package framework
14
 * @subpackage integration
15
 */
16
class RSSFeed extends ViewableData {
17
18
	/**
19
	 * Casting information for this object's methods.
20
	 * Let's us use $Title.XML in templates
21
	 */
22
	private static $casting = array(
23
		"Title" => "Varchar",
24
		"Description" => "Varchar",
25
		"Link" => "Varchar",
26
	);
27
28
	/**
29
	 * Holds the feed entries
30
	 *
31
	 * @var SS_List
32
	 */
33
	protected $entries;
34
35
	/**
36
	 * Title of the feed
37
	 *
38
	 * @var string
39
	 */
40
	protected $title;
41
42
	/**
43
	 * Description of the feed
44
	 *
45
	 * @var string
46
	 */
47
	protected $description;
48
49
	/**
50
	 * Link to the feed
51
	 *
52
	 * @var string
53
	 */
54
	protected $link;
55
56
	/**
57
	 * Name of the title field of feed entries
58
	 *
59
	 * @var string
60
	 */
61
	protected $titleField;
62
63
	/**
64
	 * Name of the description field of feed entries
65
	 *
66
	 * @var string
67
	 */
68
	protected $descriptionField;
69
70
	/**
71
	 * Name of the author field of feed entries
72
	 *
73
	 * @var string
74
	 */
75
	protected $authorField;
76
77
	/**
78
	 * Last modification of the RSS feed
79
	 *
80
	 * @var int Unix timestamp of the last modification
81
	 */
82
	protected $lastModified;
83
84
	/**
85
	 * ETag for the RSS feed (used for client-site caching)
86
	 *
87
	 * @var string The value for the HTTP ETag header.
88
	 */
89
	protected $etag;
90
91
	/**
92
	 * Custom template
93
	 *
94
	 * @var string
95
	 */
96
	protected $template = null;
97
98
	/**
99
	 * Constructor
100
	 *
101
	 * @param SS_List $entries RSS feed entries
102
	 * @param string $link Link to the feed
103
	 * @param string $title Title of the feed
104
	 * @param string $description Description of the field
105
	 * @param string $titleField Name of the field that should be used for the
106
	 *                           titles for the feed entries
107
	 * @param string $descriptionField Name of the field that should be used
108
	 *                                 for the description for the feed
109
	 *                                 entries
110
	 * @param string $authorField Name of the field that should be used for
111
	 *                            the author for the feed entries
112
	 * @param int $lastModified Unix timestamp of the latest modification
113
	 *                          (latest posting)
114
	 * @param string $etag The ETag is an unique identifier that is changed
115
	 *                         every time the representation does
116
	 */
117
	public function __construct(SS_List $entries, $link, $title,
118
											$description = null, $titleField = "Title",
119
											$descriptionField = "Content", $authorField = null,
120
											$lastModified = null, $etag = null) {
121
		$this->entries = $entries;
122
		$this->link = $link;
123
		$this->description = $description;
124
		$this->title = $title;
125
126
		$this->titleField = $titleField;
127
		$this->descriptionField = $descriptionField;
128
		$this->authorField = $authorField;
129
130
		$this->lastModified = $lastModified;
131
		$this->etag = $etag;
132
133
		parent::__construct();
134
	}
135
136
	/**
137
	 * Include an link to the feed
138
	 *
139
	 * @param string $url URL of the feed
140
	 * @param string $title Title to show
141
	 */
142
	public static function linkToFeed($url, $title = null) {
143
		$title = Convert::raw2xml($title);
144
		Requirements::insertHeadTags(
145
			'<link rel="alternate" type="application/rss+xml" title="' . $title .
146
			'" href="' . $url . '" />');
147
	}
148
149
	/**
150
	 * Get the RSS feed entries
151
	 *
152
	 * @return SS_List Returns the {@link RSSFeed_Entry} objects.
153
	 */
154
	public function Entries() {
155
		$output = new ArrayList();
156
157
		if(isset($this->entries)) {
158
			foreach($this->entries as $entry) {
159
				$output->push(
160
					RSSFeed_Entry::create($entry, $this->titleField, $this->descriptionField, $this->authorField));
161
			}
162
		}
163
		return $output;
164
	}
165
166
	/**
167
	 * Get the title of thisfeed
168
	 *
169
	 * @return string Returns the title of the feed.
170
	 */
171
	public function Title() {
172
		return $this->title;
173
	}
174
175
	/**
176
	 * Get the URL of this feed
177
	 *
178
	 * @param string $action
179
	 * @return string Returns the URL of the feed.
180
	 */
181
	public function Link($action = null) {
182
		return Controller::join_links(Director::absoluteURL($this->link), $action);
183
	}
184
185
	/**
186
	 * Get the description of this feed
187
	 *
188
	 * @return string Returns the description of the feed.
189
	 */
190
	public function Description() {
191
		return $this->description;
192
	}
193
194
	/**
195
	 * Output the feed to the browser.
196
	 *
197
	 * TODO: Pass $response object to ->outputToBrowser() to loosen dependence on global state for easier testing/prototyping so dev can inject custom SS_HTTPResponse instance.
198
	 *
199
	 * @return DBHTMLText
200
	 */
201
	public function outputToBrowser() {
202
		$prevState = Config::inst()->get('SSViewer', 'source_file_comments');
203
		Config::inst()->update('SSViewer', 'source_file_comments', false);
204
205
		$response = Controller::curr()->getResponse();
206
207
		if(is_int($this->lastModified)) {
208
			HTTP::register_modification_timestamp($this->lastModified);
209
			$response->addHeader("Last-Modified", gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT');
210
		}
211
		if(!empty($this->etag)) {
212
			HTTP::register_etag($this->etag);
213
		}
214
215
		if(!headers_sent()) {
216
			HTTP::add_cache_headers();
217
			$response->addHeader("Content-Type", "application/rss+xml; charset=utf-8");
218
		}
219
220
		Config::inst()->update('SSViewer', 'source_file_comments', $prevState);
221
222
		return $this->renderWith($this->getTemplates());
223
	}
224
225
	/**
226
	 * Set the name of the template to use. Actual template will be resolved
227
	 * via the standard template inclusion process.
228
	 *
229
	 * @param string
230
	 */
231
	public function setTemplate($template) {
232
		$this->template = $template;
233
	}
234
235
	/**
236
	 * Returns the name of the template to use.
237
	 *
238
	 * @return string
239
	 */
240
	public function getTemplate() {
241
		return $this->template;
242
	}
243
244
	/**
245
	 * Returns the ordered list of preferred templates for rendering this object.
246
	 * Will prioritise any custom template first, and then templates based on class hiearchy next.
247
	 *
248
	 * @return array
249
	 */
250
	public function getTemplates() {
251
		$templates = SSViewer::get_templates_by_class(get_class($this), '', __CLASS__);
252
		// Prefer any custom template
253
		if($this->getTemplate()) {
254
			array_unshift($templates, $this->getTemplate());
255
		}
256
		return $templates;
257
	}
258
}
259
260
/**
261
 * RSSFeed_Entry class
262
 *
263
 * This class is used for entries of an RSS feed.
264
 *
265
 * @see RSSFeed
266
 * @package framework
267
 * @subpackage integration
268
 */
269
class RSSFeed_Entry extends ViewableData {
270
	/**
271
	 * The object that represents the item, it contains all the data.
272
	 *
273
	 * @var mixed
274
	 */
275
	protected $failover;
276
277
	/**
278
	 * Name of the title field of feed entries
279
	 *
280
	 * @var string
281
	 */
282
	protected $titleField;
283
284
	/**
285
	 * Name of the description field of feed entries
286
	 *
287
	 * @var string
288
	 */
289
	protected $descriptionField;
290
291
	/**
292
	 * Name of the author field of feed entries
293
	 *
294
	 * @var string
295
	 */
296
	protected $authorField;
297
298
	/**
299
	 * Create a new RSSFeed entry.
300
	 * @param ViewableData $entry
301
	 * @param string $titleField
302
	 * @param string $descriptionField
303
	 * @param string $authorField
304
	 */
305
	public function __construct($entry, $titleField, $descriptionField, $authorField) {
306
		$this->failover = $entry;
307
		$this->titleField = $titleField;
308
		$this->descriptionField = $descriptionField;
309
		$this->authorField = $authorField;
310
311
		parent::__construct();
312
	}
313
314
	/**
315
	 * Get the description of this entry
316
	 *
317
	 * @return DBField Returns the description of the entry.
318
	 */
319
	public function Title() {
320
		return $this->rssField($this->titleField);
321
	}
322
323
	/**
324
	 * Get the description of this entry
325
	 *
326
	 * @return DBField Returns the description of the entry.
327
	 */
328
	public function Description() {
329
		$description = $this->rssField($this->descriptionField);
330
331
		// HTML fields need links re-written
332
		if($description instanceof DBHTMLText) {
333
			return $description->obj('AbsoluteLinks');
334
		}
335
336
		return $description;
337
	}
338
339
	/**
340
	 * Get the author of this entry
341
	 *
342
	 * @return DBField Returns the author of the entry.
343
	 */
344
	public function Author() {
345
		return $this->rssField($this->authorField);
346
	}
347
348
	/**
349
	 * Return the safely casted field
350
	 *
351
	 * @param string $fieldName Name of field
352
	 * @return DBField
353
	 */
354
	public function rssField($fieldName) {
355
		if($fieldName) {
356
			return $this->failover->obj($fieldName);
357
		}
358
		return null;
359
	}
360
361
	/**
362
	 * Get a link to this entry
363
	 *
364
	 * @return string Returns the URL of this entry
365
	 * @throws BadMethodCallException
366
	 */
367
	public function AbsoluteLink() {
368
		if($this->failover->hasMethod('AbsoluteLink')) {
369
			return $this->failover->AbsoluteLink();
370
		} else if($this->failover->hasMethod('Link')) {
371
			return Director::absoluteURL($this->failover->Link());
372
		}
373
374
		throw new BadMethodCallException(
375
			$this->failover->class .
376
			" object has neither an AbsoluteLink nor a Link method." .
377
			" Can't put a link in the RSS feed", E_USER_WARNING
378
		);
379
	}
380
}
381