Mercurial > hg > isophonics-drupal-site
comparison vendor/zendframework/zend-feed/src/Reader/Entry/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\Reader\Entry; | |
11 | |
12 use DateTime; | |
13 use DOMElement; | |
14 use DOMXPath; | |
15 use Zend\Feed\Reader; | |
16 use Zend\Feed\Reader\Exception; | |
17 | |
18 class Rss extends AbstractEntry implements EntryInterface | |
19 { | |
20 /** | |
21 * XPath query for RDF | |
22 * | |
23 * @var string | |
24 */ | |
25 protected $xpathQueryRdf = ''; | |
26 | |
27 /** | |
28 * XPath query for RSS | |
29 * | |
30 * @var string | |
31 */ | |
32 protected $xpathQueryRss = ''; | |
33 | |
34 /** | |
35 * Constructor | |
36 * | |
37 * @param DOMElement $entry | |
38 * @param string $entryKey | |
39 * @param string $type | |
40 */ | |
41 public function __construct(DOMElement $entry, $entryKey, $type = null) | |
42 { | |
43 parent::__construct($entry, $entryKey, $type); | |
44 $this->xpathQueryRss = '//item[' . ($this->entryKey+1) . ']'; | |
45 $this->xpathQueryRdf = '//rss:item[' . ($this->entryKey+1) . ']'; | |
46 | |
47 $manager = Reader\Reader::getExtensionManager(); | |
48 $extensions = [ | |
49 'DublinCore\Entry', | |
50 'Content\Entry', | |
51 'Atom\Entry', | |
52 'WellFormedWeb\Entry', | |
53 'Slash\Entry', | |
54 'Thread\Entry', | |
55 ]; | |
56 foreach ($extensions as $name) { | |
57 $extension = $manager->get($name); | |
58 $extension->setEntryElement($entry); | |
59 $extension->setEntryKey($entryKey); | |
60 $extension->setType($type); | |
61 $this->extensions[$name] = $extension; | |
62 } | |
63 } | |
64 | |
65 /** | |
66 * Get an author entry | |
67 * | |
68 * @param int $index | |
69 * @return string | |
70 */ | |
71 public function getAuthor($index = 0) | |
72 { | |
73 $authors = $this->getAuthors(); | |
74 | |
75 if (isset($authors[$index])) { | |
76 return $authors[$index]; | |
77 } | |
78 | |
79 return; | |
80 } | |
81 | |
82 /** | |
83 * Get an array with feed authors | |
84 * | |
85 * @return array | |
86 */ | |
87 public function getAuthors() | |
88 { | |
89 if (array_key_exists('authors', $this->data)) { | |
90 return $this->data['authors']; | |
91 } | |
92 | |
93 $authors = []; | |
94 $authorsDc = $this->getExtension('DublinCore')->getAuthors(); | |
95 if (!empty($authorsDc)) { | |
96 foreach ($authorsDc as $author) { | |
97 $authors[] = [ | |
98 'name' => $author['name'] | |
99 ]; | |
100 } | |
101 } | |
102 | |
103 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
104 && $this->getType() !== Reader\Reader::TYPE_RSS_090) { | |
105 $list = $this->xpath->query($this->xpathQueryRss . '//author'); | |
106 } else { | |
107 $list = $this->xpath->query($this->xpathQueryRdf . '//rss:author'); | |
108 } | |
109 if ($list->length) { | |
110 foreach ($list as $author) { | |
111 $string = trim($author->nodeValue); | |
112 $data = []; | |
113 // Pretty rough parsing - but it's a catchall | |
114 if (preg_match("/^.*@[^ ]*/", $string, $matches)) { | |
115 $data['email'] = trim($matches[0]); | |
116 if (preg_match("/\((.*)\)$/", $string, $matches)) { | |
117 $data['name'] = $matches[1]; | |
118 } | |
119 $authors[] = $data; | |
120 } | |
121 } | |
122 } | |
123 | |
124 if (count($authors) == 0) { | |
125 $authors = $this->getExtension('Atom')->getAuthors(); | |
126 } else { | |
127 $authors = new Reader\Collection\Author( | |
128 Reader\Reader::arrayUnique($authors) | |
129 ); | |
130 } | |
131 | |
132 if (count($authors) == 0) { | |
133 $authors = null; | |
134 } | |
135 | |
136 $this->data['authors'] = $authors; | |
137 | |
138 return $this->data['authors']; | |
139 } | |
140 | |
141 /** | |
142 * Get the entry content | |
143 * | |
144 * @return string | |
145 */ | |
146 public function getContent() | |
147 { | |
148 if (array_key_exists('content', $this->data)) { | |
149 return $this->data['content']; | |
150 } | |
151 | |
152 $content = $this->getExtension('Content')->getContent(); | |
153 | |
154 if (!$content) { | |
155 $content = $this->getDescription(); | |
156 } | |
157 | |
158 if (empty($content)) { | |
159 $content = $this->getExtension('Atom')->getContent(); | |
160 } | |
161 | |
162 $this->data['content'] = $content; | |
163 | |
164 return $this->data['content']; | |
165 } | |
166 | |
167 /** | |
168 * Get the entry's date of creation | |
169 * | |
170 * @return \DateTime | |
171 */ | |
172 public function getDateCreated() | |
173 { | |
174 return $this->getDateModified(); | |
175 } | |
176 | |
177 /** | |
178 * Get the entry's date of modification | |
179 * | |
180 * @throws Exception\RuntimeException | |
181 * @return \DateTime | |
182 */ | |
183 public function getDateModified() | |
184 { | |
185 if (array_key_exists('datemodified', $this->data)) { | |
186 return $this->data['datemodified']; | |
187 } | |
188 | |
189 $date = null; | |
190 | |
191 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
192 && $this->getType() !== Reader\Reader::TYPE_RSS_090 | |
193 ) { | |
194 $dateModified = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/pubDate)'); | |
195 if ($dateModified) { | |
196 $dateModifiedParsed = strtotime($dateModified); | |
197 if ($dateModifiedParsed) { | |
198 $date = new DateTime('@' . $dateModifiedParsed); | |
199 } else { | |
200 $dateStandards = [DateTime::RSS, DateTime::RFC822, | |
201 DateTime::RFC2822, null]; | |
202 foreach ($dateStandards as $standard) { | |
203 try { | |
204 $date = date_create_from_format($standard, $dateModified); | |
205 break; | |
206 } catch (\Exception $e) { | |
207 if ($standard === null) { | |
208 throw new Exception\RuntimeException( | |
209 'Could not load date due to unrecognised' | |
210 .' format (should follow RFC 822 or 2822):' | |
211 . $e->getMessage(), | |
212 0, $e | |
213 ); | |
214 } | |
215 } | |
216 } | |
217 } | |
218 } | |
219 } | |
220 | |
221 if (!$date) { | |
222 $date = $this->getExtension('DublinCore')->getDate(); | |
223 } | |
224 | |
225 if (!$date) { | |
226 $date = $this->getExtension('Atom')->getDateModified(); | |
227 } | |
228 | |
229 if (!$date) { | |
230 $date = null; | |
231 } | |
232 | |
233 $this->data['datemodified'] = $date; | |
234 | |
235 return $this->data['datemodified']; | |
236 } | |
237 | |
238 /** | |
239 * Get the entry description | |
240 * | |
241 * @return string | |
242 */ | |
243 public function getDescription() | |
244 { | |
245 if (array_key_exists('description', $this->data)) { | |
246 return $this->data['description']; | |
247 } | |
248 | |
249 $description = null; | |
250 | |
251 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
252 && $this->getType() !== Reader\Reader::TYPE_RSS_090 | |
253 ) { | |
254 $description = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/description)'); | |
255 } else { | |
256 $description = $this->xpath->evaluate('string(' . $this->xpathQueryRdf . '/rss:description)'); | |
257 } | |
258 | |
259 if (!$description) { | |
260 $description = $this->getExtension('DublinCore')->getDescription(); | |
261 } | |
262 | |
263 if (empty($description)) { | |
264 $description = $this->getExtension('Atom')->getDescription(); | |
265 } | |
266 | |
267 if (!$description) { | |
268 $description = null; | |
269 } | |
270 | |
271 $this->data['description'] = $description; | |
272 | |
273 return $this->data['description']; | |
274 } | |
275 | |
276 /** | |
277 * Get the entry enclosure | |
278 * @return string | |
279 */ | |
280 public function getEnclosure() | |
281 { | |
282 if (array_key_exists('enclosure', $this->data)) { | |
283 return $this->data['enclosure']; | |
284 } | |
285 | |
286 $enclosure = null; | |
287 | |
288 if ($this->getType() == Reader\Reader::TYPE_RSS_20) { | |
289 $nodeList = $this->xpath->query($this->xpathQueryRss . '/enclosure'); | |
290 | |
291 if ($nodeList->length > 0) { | |
292 $enclosure = new \stdClass(); | |
293 $enclosure->url = $nodeList->item(0)->getAttribute('url'); | |
294 $enclosure->length = $nodeList->item(0)->getAttribute('length'); | |
295 $enclosure->type = $nodeList->item(0)->getAttribute('type'); | |
296 } | |
297 } | |
298 | |
299 if (!$enclosure) { | |
300 $enclosure = $this->getExtension('Atom')->getEnclosure(); | |
301 } | |
302 | |
303 $this->data['enclosure'] = $enclosure; | |
304 | |
305 return $this->data['enclosure']; | |
306 } | |
307 | |
308 /** | |
309 * Get the entry ID | |
310 * | |
311 * @return string | |
312 */ | |
313 public function getId() | |
314 { | |
315 if (array_key_exists('id', $this->data)) { | |
316 return $this->data['id']; | |
317 } | |
318 | |
319 $id = null; | |
320 | |
321 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
322 && $this->getType() !== Reader\Reader::TYPE_RSS_090 | |
323 ) { | |
324 $id = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/guid)'); | |
325 } | |
326 | |
327 if (!$id) { | |
328 $id = $this->getExtension('DublinCore')->getId(); | |
329 } | |
330 | |
331 if (empty($id)) { | |
332 $id = $this->getExtension('Atom')->getId(); | |
333 } | |
334 | |
335 if (!$id) { | |
336 if ($this->getPermalink()) { | |
337 $id = $this->getPermalink(); | |
338 } elseif ($this->getTitle()) { | |
339 $id = $this->getTitle(); | |
340 } else { | |
341 $id = null; | |
342 } | |
343 } | |
344 | |
345 $this->data['id'] = $id; | |
346 | |
347 return $this->data['id']; | |
348 } | |
349 | |
350 /** | |
351 * Get a specific link | |
352 * | |
353 * @param int $index | |
354 * @return string | |
355 */ | |
356 public function getLink($index = 0) | |
357 { | |
358 if (!array_key_exists('links', $this->data)) { | |
359 $this->getLinks(); | |
360 } | |
361 | |
362 if (isset($this->data['links'][$index])) { | |
363 return $this->data['links'][$index]; | |
364 } | |
365 | |
366 return; | |
367 } | |
368 | |
369 /** | |
370 * Get all links | |
371 * | |
372 * @return array | |
373 */ | |
374 public function getLinks() | |
375 { | |
376 if (array_key_exists('links', $this->data)) { | |
377 return $this->data['links']; | |
378 } | |
379 | |
380 $links = []; | |
381 | |
382 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 && | |
383 $this->getType() !== Reader\Reader::TYPE_RSS_090) { | |
384 $list = $this->xpath->query($this->xpathQueryRss . '//link'); | |
385 } else { | |
386 $list = $this->xpath->query($this->xpathQueryRdf . '//rss:link'); | |
387 } | |
388 | |
389 if (!$list->length) { | |
390 $links = $this->getExtension('Atom')->getLinks(); | |
391 } else { | |
392 foreach ($list as $link) { | |
393 $links[] = $link->nodeValue; | |
394 } | |
395 } | |
396 | |
397 $this->data['links'] = $links; | |
398 | |
399 return $this->data['links']; | |
400 } | |
401 | |
402 /** | |
403 * Get all categories | |
404 * | |
405 * @return Reader\Collection\Category | |
406 */ | |
407 public function getCategories() | |
408 { | |
409 if (array_key_exists('categories', $this->data)) { | |
410 return $this->data['categories']; | |
411 } | |
412 | |
413 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 && | |
414 $this->getType() !== Reader\Reader::TYPE_RSS_090) { | |
415 $list = $this->xpath->query($this->xpathQueryRss . '//category'); | |
416 } else { | |
417 $list = $this->xpath->query($this->xpathQueryRdf . '//rss:category'); | |
418 } | |
419 | |
420 if ($list->length) { | |
421 $categoryCollection = new Reader\Collection\Category; | |
422 foreach ($list as $category) { | |
423 $categoryCollection[] = [ | |
424 'term' => $category->nodeValue, | |
425 'scheme' => $category->getAttribute('domain'), | |
426 'label' => $category->nodeValue, | |
427 ]; | |
428 } | |
429 } else { | |
430 $categoryCollection = $this->getExtension('DublinCore')->getCategories(); | |
431 } | |
432 | |
433 if (count($categoryCollection) == 0) { | |
434 $categoryCollection = $this->getExtension('Atom')->getCategories(); | |
435 } | |
436 | |
437 $this->data['categories'] = $categoryCollection; | |
438 | |
439 return $this->data['categories']; | |
440 } | |
441 | |
442 /** | |
443 * Get a permalink to the entry | |
444 * | |
445 * @return string | |
446 */ | |
447 public function getPermalink() | |
448 { | |
449 return $this->getLink(0); | |
450 } | |
451 | |
452 /** | |
453 * Get the entry title | |
454 * | |
455 * @return string | |
456 */ | |
457 public function getTitle() | |
458 { | |
459 if (array_key_exists('title', $this->data)) { | |
460 return $this->data['title']; | |
461 } | |
462 | |
463 $title = null; | |
464 | |
465 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
466 && $this->getType() !== Reader\Reader::TYPE_RSS_090 | |
467 ) { | |
468 $title = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/title)'); | |
469 } else { | |
470 $title = $this->xpath->evaluate('string(' . $this->xpathQueryRdf . '/rss:title)'); | |
471 } | |
472 | |
473 if (!$title) { | |
474 $title = $this->getExtension('DublinCore')->getTitle(); | |
475 } | |
476 | |
477 if (!$title) { | |
478 $title = $this->getExtension('Atom')->getTitle(); | |
479 } | |
480 | |
481 if (!$title) { | |
482 $title = null; | |
483 } | |
484 | |
485 $this->data['title'] = $title; | |
486 | |
487 return $this->data['title']; | |
488 } | |
489 | |
490 /** | |
491 * Get the number of comments/replies for current entry | |
492 * | |
493 * @return string|null | |
494 */ | |
495 public function getCommentCount() | |
496 { | |
497 if (array_key_exists('commentcount', $this->data)) { | |
498 return $this->data['commentcount']; | |
499 } | |
500 | |
501 $commentcount = $this->getExtension('Slash')->getCommentCount(); | |
502 | |
503 if (!$commentcount) { | |
504 $commentcount = $this->getExtension('Thread')->getCommentCount(); | |
505 } | |
506 | |
507 if (!$commentcount) { | |
508 $commentcount = $this->getExtension('Atom')->getCommentCount(); | |
509 } | |
510 | |
511 if (!$commentcount) { | |
512 $commentcount = null; | |
513 } | |
514 | |
515 $this->data['commentcount'] = $commentcount; | |
516 | |
517 return $this->data['commentcount']; | |
518 } | |
519 | |
520 /** | |
521 * Returns a URI pointing to the HTML page where comments can be made on this entry | |
522 * | |
523 * @return string | |
524 */ | |
525 public function getCommentLink() | |
526 { | |
527 if (array_key_exists('commentlink', $this->data)) { | |
528 return $this->data['commentlink']; | |
529 } | |
530 | |
531 $commentlink = null; | |
532 | |
533 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 | |
534 && $this->getType() !== Reader\Reader::TYPE_RSS_090 | |
535 ) { | |
536 $commentlink = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/comments)'); | |
537 } | |
538 | |
539 if (!$commentlink) { | |
540 $commentlink = $this->getExtension('Atom')->getCommentLink(); | |
541 } | |
542 | |
543 if (!$commentlink) { | |
544 $commentlink = null; | |
545 } | |
546 | |
547 $this->data['commentlink'] = $commentlink; | |
548 | |
549 return $this->data['commentlink']; | |
550 } | |
551 | |
552 /** | |
553 * Returns a URI pointing to a feed of all comments for this entry | |
554 * | |
555 * @return string | |
556 */ | |
557 public function getCommentFeedLink() | |
558 { | |
559 if (array_key_exists('commentfeedlink', $this->data)) { | |
560 return $this->data['commentfeedlink']; | |
561 } | |
562 | |
563 $commentfeedlink = $this->getExtension('WellFormedWeb')->getCommentFeedLink(); | |
564 | |
565 if (!$commentfeedlink) { | |
566 $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rss'); | |
567 } | |
568 | |
569 if (!$commentfeedlink) { | |
570 $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rdf'); | |
571 } | |
572 | |
573 if (!$commentfeedlink) { | |
574 $commentfeedlink = null; | |
575 } | |
576 | |
577 $this->data['commentfeedlink'] = $commentfeedlink; | |
578 | |
579 return $this->data['commentfeedlink']; | |
580 } | |
581 | |
582 /** | |
583 * Set the XPath query (incl. on all Extensions) | |
584 * | |
585 * @param DOMXPath $xpath | |
586 * @return void | |
587 */ | |
588 public function setXpath(DOMXPath $xpath) | |
589 { | |
590 parent::setXpath($xpath); | |
591 foreach ($this->extensions as $extension) { | |
592 $extension->setXpath($this->xpath); | |
593 } | |
594 } | |
595 } |