Mercurial > hg > isophonics-drupal-site
comparison vendor/zendframework/zend-feed/src/Writer/Renderer/Feed/Rss.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 /** | |
3 * Zend Framework (http://framework.zend.com/) | |
4 * | |
5 * @link http://github.com/zendframework/zf2 for the canonical source repository | |
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) | |
7 * @license http://framework.zend.com/license/new-bsd New BSD License | |
8 */ | |
9 | |
10 namespace Zend\Feed\Writer\Renderer\Feed; | |
11 | |
12 use DateTime; | |
13 use DOMDocument; | |
14 use DOMElement; | |
15 use Zend\Feed\Uri; | |
16 use Zend\Feed\Writer; | |
17 use Zend\Feed\Writer\Renderer; | |
18 use Zend\Feed\Writer\Version; | |
19 | |
20 /** | |
21 */ | |
22 class Rss extends Renderer\AbstractRenderer implements Renderer\RendererInterface | |
23 { | |
24 /** | |
25 * Constructor | |
26 * | |
27 * @param Writer\Feed $container | |
28 */ | |
29 public function __construct(Writer\Feed $container) | |
30 { | |
31 parent::__construct($container); | |
32 } | |
33 | |
34 /** | |
35 * Render RSS feed | |
36 * | |
37 * @return self | |
38 */ | |
39 public function render() | |
40 { | |
41 $this->dom = new DOMDocument('1.0', $this->container->getEncoding()); | |
42 $this->dom->formatOutput = true; | |
43 $this->dom->substituteEntities = false; | |
44 $rss = $this->dom->createElement('rss'); | |
45 $this->setRootElement($rss); | |
46 $rss->setAttribute('version', '2.0'); | |
47 | |
48 $channel = $this->dom->createElement('channel'); | |
49 $rss->appendChild($channel); | |
50 $this->dom->appendChild($rss); | |
51 $this->_setLanguage($this->dom, $channel); | |
52 $this->_setBaseUrl($this->dom, $channel); | |
53 $this->_setTitle($this->dom, $channel); | |
54 $this->_setDescription($this->dom, $channel); | |
55 $this->_setImage($this->dom, $channel); | |
56 $this->_setDateCreated($this->dom, $channel); | |
57 $this->_setDateModified($this->dom, $channel); | |
58 $this->_setLastBuildDate($this->dom, $channel); | |
59 $this->_setGenerator($this->dom, $channel); | |
60 $this->_setLink($this->dom, $channel); | |
61 $this->_setAuthors($this->dom, $channel); | |
62 $this->_setCopyright($this->dom, $channel); | |
63 $this->_setCategories($this->dom, $channel); | |
64 | |
65 foreach ($this->extensions as $ext) { | |
66 $ext->setType($this->getType()); | |
67 $ext->setRootElement($this->getRootElement()); | |
68 $ext->setDOMDocument($this->getDOMDocument(), $channel); | |
69 $ext->render(); | |
70 } | |
71 | |
72 foreach ($this->container as $entry) { | |
73 if ($this->getDataContainer()->getEncoding()) { | |
74 $entry->setEncoding($this->getDataContainer()->getEncoding()); | |
75 } | |
76 if ($entry instanceof Writer\Entry) { | |
77 $renderer = new Renderer\Entry\Rss($entry); | |
78 } else { | |
79 continue; | |
80 } | |
81 if ($this->ignoreExceptions === true) { | |
82 $renderer->ignoreExceptions(); | |
83 } | |
84 $renderer->setType($this->getType()); | |
85 $renderer->setRootElement($this->dom->documentElement); | |
86 $renderer->render(); | |
87 $element = $renderer->getElement(); | |
88 $deep = version_compare(PHP_VERSION, '7', 'ge') ? 1 : true; | |
89 $imported = $this->dom->importNode($element, $deep); | |
90 $channel->appendChild($imported); | |
91 } | |
92 return $this; | |
93 } | |
94 | |
95 /** | |
96 * Set feed language | |
97 * | |
98 * @param DOMDocument $dom | |
99 * @param DOMElement $root | |
100 * @return void | |
101 */ | |
102 protected function _setLanguage(DOMDocument $dom, DOMElement $root) | |
103 { | |
104 $lang = $this->getDataContainer()->getLanguage(); | |
105 if (!$lang) { | |
106 return; | |
107 } | |
108 $language = $dom->createElement('language'); | |
109 $root->appendChild($language); | |
110 $language->nodeValue = $lang; | |
111 } | |
112 | |
113 /** | |
114 * Set feed title | |
115 * | |
116 * @param DOMDocument $dom | |
117 * @param DOMElement $root | |
118 * @return void | |
119 * @throws Writer\Exception\InvalidArgumentException | |
120 */ | |
121 protected function _setTitle(DOMDocument $dom, DOMElement $root) | |
122 { | |
123 if (!$this->getDataContainer()->getTitle()) { | |
124 $message = 'RSS 2.0 feed elements MUST contain exactly one' | |
125 . ' title element but a title has not been set'; | |
126 $exception = new Writer\Exception\InvalidArgumentException($message); | |
127 if (!$this->ignoreExceptions) { | |
128 throw $exception; | |
129 } else { | |
130 $this->exceptions[] = $exception; | |
131 return; | |
132 } | |
133 } | |
134 | |
135 $title = $dom->createElement('title'); | |
136 $root->appendChild($title); | |
137 $text = $dom->createTextNode($this->getDataContainer()->getTitle()); | |
138 $title->appendChild($text); | |
139 } | |
140 | |
141 /** | |
142 * Set feed description | |
143 * | |
144 * @param DOMDocument $dom | |
145 * @param DOMElement $root | |
146 * @return void | |
147 * @throws Writer\Exception\InvalidArgumentException | |
148 */ | |
149 protected function _setDescription(DOMDocument $dom, DOMElement $root) | |
150 { | |
151 if (!$this->getDataContainer()->getDescription()) { | |
152 $message = 'RSS 2.0 feed elements MUST contain exactly one' | |
153 . ' description element but one has not been set'; | |
154 $exception = new Writer\Exception\InvalidArgumentException($message); | |
155 if (!$this->ignoreExceptions) { | |
156 throw $exception; | |
157 } else { | |
158 $this->exceptions[] = $exception; | |
159 return; | |
160 } | |
161 } | |
162 $subtitle = $dom->createElement('description'); | |
163 $root->appendChild($subtitle); | |
164 $text = $dom->createTextNode($this->getDataContainer()->getDescription()); | |
165 $subtitle->appendChild($text); | |
166 } | |
167 | |
168 /** | |
169 * Set date feed was last modified | |
170 * | |
171 * @param DOMDocument $dom | |
172 * @param DOMElement $root | |
173 * @return void | |
174 */ | |
175 protected function _setDateModified(DOMDocument $dom, DOMElement $root) | |
176 { | |
177 if (!$this->getDataContainer()->getDateModified()) { | |
178 return; | |
179 } | |
180 | |
181 $updated = $dom->createElement('pubDate'); | |
182 $root->appendChild($updated); | |
183 $text = $dom->createTextNode( | |
184 $this->getDataContainer()->getDateModified()->format(DateTime::RSS) | |
185 ); | |
186 $updated->appendChild($text); | |
187 } | |
188 | |
189 /** | |
190 * Set feed generator string | |
191 * | |
192 * @param DOMDocument $dom | |
193 * @param DOMElement $root | |
194 * @return void | |
195 */ | |
196 protected function _setGenerator(DOMDocument $dom, DOMElement $root) | |
197 { | |
198 if (!$this->getDataContainer()->getGenerator()) { | |
199 $this->getDataContainer()->setGenerator( | |
200 'Zend_Feed_Writer', | |
201 Version::VERSION, | |
202 'http://framework.zend.com' | |
203 ); | |
204 } | |
205 | |
206 $gdata = $this->getDataContainer()->getGenerator(); | |
207 $generator = $dom->createElement('generator'); | |
208 $root->appendChild($generator); | |
209 $name = $gdata['name']; | |
210 if (array_key_exists('version', $gdata)) { | |
211 $name .= ' ' . $gdata['version']; | |
212 } | |
213 if (array_key_exists('uri', $gdata)) { | |
214 $name .= ' (' . $gdata['uri'] . ')'; | |
215 } | |
216 $text = $dom->createTextNode($name); | |
217 $generator->appendChild($text); | |
218 } | |
219 | |
220 /** | |
221 * Set link to feed | |
222 * | |
223 * @param DOMDocument $dom | |
224 * @param DOMElement $root | |
225 * @return void | |
226 * @throws Writer\Exception\InvalidArgumentException | |
227 */ | |
228 protected function _setLink(DOMDocument $dom, DOMElement $root) | |
229 { | |
230 $value = $this->getDataContainer()->getLink(); | |
231 if (!$value) { | |
232 $message = 'RSS 2.0 feed elements MUST contain exactly one' | |
233 . ' link element but one has not been set'; | |
234 $exception = new Writer\Exception\InvalidArgumentException($message); | |
235 if (!$this->ignoreExceptions) { | |
236 throw $exception; | |
237 } else { | |
238 $this->exceptions[] = $exception; | |
239 return; | |
240 } | |
241 } | |
242 $link = $dom->createElement('link'); | |
243 $root->appendChild($link); | |
244 $text = $dom->createTextNode($value); | |
245 $link->appendChild($text); | |
246 if (!Uri::factory($value)->isValid()) { | |
247 $link->setAttribute('isPermaLink', 'false'); | |
248 } | |
249 } | |
250 | |
251 /** | |
252 * Set feed authors | |
253 * | |
254 * @param DOMDocument $dom | |
255 * @param DOMElement $root | |
256 * @return void | |
257 */ | |
258 protected function _setAuthors(DOMDocument $dom, DOMElement $root) | |
259 { | |
260 $authors = $this->getDataContainer()->getAuthors(); | |
261 if (!$authors || empty($authors)) { | |
262 return; | |
263 } | |
264 foreach ($authors as $data) { | |
265 $author = $this->dom->createElement('author'); | |
266 $name = $data['name']; | |
267 if (array_key_exists('email', $data)) { | |
268 $name = $data['email'] . ' (' . $data['name'] . ')'; | |
269 } | |
270 $text = $dom->createTextNode($name); | |
271 $author->appendChild($text); | |
272 $root->appendChild($author); | |
273 } | |
274 } | |
275 | |
276 /** | |
277 * Set feed copyright | |
278 * | |
279 * @param DOMDocument $dom | |
280 * @param DOMElement $root | |
281 * @return void | |
282 */ | |
283 protected function _setCopyright(DOMDocument $dom, DOMElement $root) | |
284 { | |
285 $copyright = $this->getDataContainer()->getCopyright(); | |
286 if (!$copyright) { | |
287 return; | |
288 } | |
289 $copy = $dom->createElement('copyright'); | |
290 $root->appendChild($copy); | |
291 $text = $dom->createTextNode($copyright); | |
292 $copy->appendChild($text); | |
293 } | |
294 | |
295 /** | |
296 * Set feed channel image | |
297 * | |
298 * @param DOMDocument $dom | |
299 * @param DOMElement $root | |
300 * @return void | |
301 * @throws Writer\Exception\InvalidArgumentException | |
302 */ | |
303 protected function _setImage(DOMDocument $dom, DOMElement $root) | |
304 { | |
305 $image = $this->getDataContainer()->getImage(); | |
306 if (!$image) { | |
307 return; | |
308 } | |
309 | |
310 if (!isset($image['title']) || empty($image['title']) | |
311 || !is_string($image['title']) | |
312 ) { | |
313 $message = 'RSS 2.0 feed images must include a title'; | |
314 $exception = new Writer\Exception\InvalidArgumentException($message); | |
315 if (!$this->ignoreExceptions) { | |
316 throw $exception; | |
317 } else { | |
318 $this->exceptions[] = $exception; | |
319 return; | |
320 } | |
321 } | |
322 | |
323 if (empty($image['link']) || !is_string($image['link']) | |
324 || !Uri::factory($image['link'])->isValid() | |
325 ) { | |
326 $message = 'Invalid parameter: parameter \'link\'' | |
327 . ' must be a non-empty string and valid URI/IRI'; | |
328 $exception = new Writer\Exception\InvalidArgumentException($message); | |
329 if (!$this->ignoreExceptions) { | |
330 throw $exception; | |
331 } else { | |
332 $this->exceptions[] = $exception; | |
333 return; | |
334 } | |
335 } | |
336 | |
337 $img = $dom->createElement('image'); | |
338 $root->appendChild($img); | |
339 | |
340 $url = $dom->createElement('url'); | |
341 $text = $dom->createTextNode($image['uri']); | |
342 $url->appendChild($text); | |
343 | |
344 $title = $dom->createElement('title'); | |
345 $text = $dom->createTextNode($image['title']); | |
346 $title->appendChild($text); | |
347 | |
348 $link = $dom->createElement('link'); | |
349 $text = $dom->createTextNode($image['link']); | |
350 $link->appendChild($text); | |
351 | |
352 $img->appendChild($url); | |
353 $img->appendChild($title); | |
354 $img->appendChild($link); | |
355 | |
356 if (isset($image['height'])) { | |
357 if (!ctype_digit((string) $image['height']) || $image['height'] > 400) { | |
358 $message = 'Invalid parameter: parameter \'height\'' | |
359 . ' must be an integer not exceeding 400'; | |
360 $exception = new Writer\Exception\InvalidArgumentException($message); | |
361 if (!$this->ignoreExceptions) { | |
362 throw $exception; | |
363 } else { | |
364 $this->exceptions[] = $exception; | |
365 return; | |
366 } | |
367 } | |
368 $height = $dom->createElement('height'); | |
369 $text = $dom->createTextNode($image['height']); | |
370 $height->appendChild($text); | |
371 $img->appendChild($height); | |
372 } | |
373 if (isset($image['width'])) { | |
374 if (!ctype_digit((string) $image['width']) || $image['width'] > 144) { | |
375 $message = 'Invalid parameter: parameter \'width\'' | |
376 . ' must be an integer not exceeding 144'; | |
377 $exception = new Writer\Exception\InvalidArgumentException($message); | |
378 if (!$this->ignoreExceptions) { | |
379 throw $exception; | |
380 } else { | |
381 $this->exceptions[] = $exception; | |
382 return; | |
383 } | |
384 } | |
385 $width = $dom->createElement('width'); | |
386 $text = $dom->createTextNode($image['width']); | |
387 $width->appendChild($text); | |
388 $img->appendChild($width); | |
389 } | |
390 if (isset($image['description'])) { | |
391 if (empty($image['description']) || !is_string($image['description'])) { | |
392 $message = 'Invalid parameter: parameter \'description\'' | |
393 . ' must be a non-empty string'; | |
394 $exception = new Writer\Exception\InvalidArgumentException($message); | |
395 if (!$this->ignoreExceptions) { | |
396 throw $exception; | |
397 } else { | |
398 $this->exceptions[] = $exception; | |
399 return; | |
400 } | |
401 } | |
402 $desc = $dom->createElement('description'); | |
403 $text = $dom->createTextNode($image['description']); | |
404 $desc->appendChild($text); | |
405 $img->appendChild($desc); | |
406 } | |
407 } | |
408 | |
409 /** | |
410 * Set date feed was created | |
411 * | |
412 * @param DOMDocument $dom | |
413 * @param DOMElement $root | |
414 * @return void | |
415 */ | |
416 protected function _setDateCreated(DOMDocument $dom, DOMElement $root) | |
417 { | |
418 if (!$this->getDataContainer()->getDateCreated()) { | |
419 return; | |
420 } | |
421 if (!$this->getDataContainer()->getDateModified()) { | |
422 $this->getDataContainer()->setDateModified( | |
423 $this->getDataContainer()->getDateCreated() | |
424 ); | |
425 } | |
426 } | |
427 | |
428 /** | |
429 * Set date feed last build date | |
430 * | |
431 * @param DOMDocument $dom | |
432 * @param DOMElement $root | |
433 * @return void | |
434 */ | |
435 protected function _setLastBuildDate(DOMDocument $dom, DOMElement $root) | |
436 { | |
437 if (!$this->getDataContainer()->getLastBuildDate()) { | |
438 return; | |
439 } | |
440 | |
441 $lastBuildDate = $dom->createElement('lastBuildDate'); | |
442 $root->appendChild($lastBuildDate); | |
443 $text = $dom->createTextNode( | |
444 $this->getDataContainer()->getLastBuildDate()->format(DateTime::RSS) | |
445 ); | |
446 $lastBuildDate->appendChild($text); | |
447 } | |
448 | |
449 /** | |
450 * Set base URL to feed links | |
451 * | |
452 * @param DOMDocument $dom | |
453 * @param DOMElement $root | |
454 * @return void | |
455 */ | |
456 protected function _setBaseUrl(DOMDocument $dom, DOMElement $root) | |
457 { | |
458 $baseUrl = $this->getDataContainer()->getBaseUrl(); | |
459 if (!$baseUrl) { | |
460 return; | |
461 } | |
462 $root->setAttribute('xml:base', $baseUrl); | |
463 } | |
464 | |
465 /** | |
466 * Set feed categories | |
467 * | |
468 * @param DOMDocument $dom | |
469 * @param DOMElement $root | |
470 * @return void | |
471 */ | |
472 protected function _setCategories(DOMDocument $dom, DOMElement $root) | |
473 { | |
474 $categories = $this->getDataContainer()->getCategories(); | |
475 if (!$categories) { | |
476 return; | |
477 } | |
478 foreach ($categories as $cat) { | |
479 $category = $dom->createElement('category'); | |
480 if (isset($cat['scheme'])) { | |
481 $category->setAttribute('domain', $cat['scheme']); | |
482 } | |
483 $text = $dom->createTextNode($cat['term']); | |
484 $category->appendChild($text); | |
485 $root->appendChild($category); | |
486 } | |
487 } | |
488 } |