Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Zend Framework (http://framework.zend.com/)
|
Chris@0
|
4 *
|
Chris@0
|
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
|
Chris@0
|
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
Chris@0
|
7 * @license http://framework.zend.com/license/new-bsd New BSD License
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 namespace Zend\Feed\Reader\Feed;
|
Chris@0
|
11
|
Chris@0
|
12 use DateTime;
|
Chris@0
|
13 use DOMDocument;
|
Chris@0
|
14 use Zend\Feed\Reader;
|
Chris@0
|
15 use Zend\Feed\Reader\Collection;
|
Chris@0
|
16 use Zend\Feed\Reader\Exception;
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 */
|
Chris@0
|
20 class Rss extends AbstractFeed
|
Chris@0
|
21 {
|
Chris@0
|
22 /**
|
Chris@0
|
23 * Constructor
|
Chris@0
|
24 *
|
Chris@0
|
25 * @param DOMDocument $dom
|
Chris@0
|
26 * @param string $type
|
Chris@0
|
27 */
|
Chris@0
|
28 public function __construct(DOMDocument $dom, $type = null)
|
Chris@0
|
29 {
|
Chris@0
|
30 parent::__construct($dom, $type);
|
Chris@0
|
31
|
Chris@0
|
32 $manager = Reader\Reader::getExtensionManager();
|
Chris@0
|
33
|
Chris@0
|
34 $feed = $manager->get('DublinCore\Feed');
|
Chris@0
|
35 $feed->setDomDocument($dom);
|
Chris@0
|
36 $feed->setType($this->data['type']);
|
Chris@0
|
37 $feed->setXpath($this->xpath);
|
Chris@0
|
38 $this->extensions['DublinCore\Feed'] = $feed;
|
Chris@0
|
39
|
Chris@0
|
40 $feed = $manager->get('Atom\Feed');
|
Chris@0
|
41 $feed->setDomDocument($dom);
|
Chris@0
|
42 $feed->setType($this->data['type']);
|
Chris@0
|
43 $feed->setXpath($this->xpath);
|
Chris@0
|
44 $this->extensions['Atom\Feed'] = $feed;
|
Chris@0
|
45
|
Chris@0
|
46 if ($this->getType() !== Reader\Reader::TYPE_RSS_10
|
Chris@0
|
47 && $this->getType() !== Reader\Reader::TYPE_RSS_090
|
Chris@0
|
48 ) {
|
Chris@0
|
49 $xpathPrefix = '/rss/channel';
|
Chris@0
|
50 } else {
|
Chris@0
|
51 $xpathPrefix = '/rdf:RDF/rss:channel';
|
Chris@0
|
52 }
|
Chris@0
|
53 foreach ($this->extensions as $extension) {
|
Chris@0
|
54 $extension->setXpathPrefix($xpathPrefix);
|
Chris@0
|
55 }
|
Chris@0
|
56 }
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * Get a single author
|
Chris@0
|
60 *
|
Chris@0
|
61 * @param int $index
|
Chris@0
|
62 * @return string|null
|
Chris@0
|
63 */
|
Chris@0
|
64 public function getAuthor($index = 0)
|
Chris@0
|
65 {
|
Chris@0
|
66 $authors = $this->getAuthors();
|
Chris@0
|
67
|
Chris@0
|
68 if (isset($authors[$index])) {
|
Chris@0
|
69 return $authors[$index];
|
Chris@0
|
70 }
|
Chris@0
|
71
|
Chris@0
|
72 return;
|
Chris@0
|
73 }
|
Chris@0
|
74
|
Chris@0
|
75 /**
|
Chris@0
|
76 * Get an array with feed authors
|
Chris@0
|
77 *
|
Chris@0
|
78 * @return array
|
Chris@0
|
79 */
|
Chris@0
|
80 public function getAuthors()
|
Chris@0
|
81 {
|
Chris@0
|
82 if (array_key_exists('authors', $this->data)) {
|
Chris@0
|
83 return $this->data['authors'];
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 $authors = [];
|
Chris@0
|
87 $authorsDc = $this->getExtension('DublinCore')->getAuthors();
|
Chris@12
|
88 if (! empty($authorsDc)) {
|
Chris@0
|
89 foreach ($authorsDc as $author) {
|
Chris@0
|
90 $authors[] = [
|
Chris@0
|
91 'name' => $author['name']
|
Chris@0
|
92 ];
|
Chris@0
|
93 }
|
Chris@0
|
94 }
|
Chris@0
|
95
|
Chris@0
|
96 /**
|
Chris@0
|
97 * Technically RSS doesn't specific author element use at the feed level
|
Chris@0
|
98 * but it's supported on a "just in case" basis.
|
Chris@0
|
99 */
|
Chris@0
|
100 if ($this->getType() !== Reader\Reader::TYPE_RSS_10
|
Chris@0
|
101 && $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
102 $list = $this->xpath->query('//author');
|
Chris@0
|
103 } else {
|
Chris@0
|
104 $list = $this->xpath->query('//rss:author');
|
Chris@0
|
105 }
|
Chris@0
|
106 if ($list->length) {
|
Chris@0
|
107 foreach ($list as $author) {
|
Chris@0
|
108 $string = trim($author->nodeValue);
|
Chris@0
|
109 $data = [];
|
Chris@0
|
110 // Pretty rough parsing - but it's a catchall
|
Chris@0
|
111 if (preg_match("/^.*@[^ ]*/", $string, $matches)) {
|
Chris@0
|
112 $data['email'] = trim($matches[0]);
|
Chris@0
|
113 if (preg_match("/\((.*)\)$/", $string, $matches)) {
|
Chris@0
|
114 $data['name'] = $matches[1];
|
Chris@0
|
115 }
|
Chris@0
|
116 $authors[] = $data;
|
Chris@0
|
117 }
|
Chris@0
|
118 }
|
Chris@0
|
119 }
|
Chris@0
|
120
|
Chris@0
|
121 if (count($authors) == 0) {
|
Chris@0
|
122 $authors = $this->getExtension('Atom')->getAuthors();
|
Chris@0
|
123 } else {
|
Chris@0
|
124 $authors = new Reader\Collection\Author(
|
Chris@0
|
125 Reader\Reader::arrayUnique($authors)
|
Chris@0
|
126 );
|
Chris@0
|
127 }
|
Chris@0
|
128
|
Chris@0
|
129 if (count($authors) == 0) {
|
Chris@0
|
130 $authors = null;
|
Chris@0
|
131 }
|
Chris@0
|
132
|
Chris@0
|
133 $this->data['authors'] = $authors;
|
Chris@0
|
134
|
Chris@0
|
135 return $this->data['authors'];
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@0
|
138 /**
|
Chris@0
|
139 * Get the copyright entry
|
Chris@0
|
140 *
|
Chris@0
|
141 * @return string|null
|
Chris@0
|
142 */
|
Chris@0
|
143 public function getCopyright()
|
Chris@0
|
144 {
|
Chris@0
|
145 if (array_key_exists('copyright', $this->data)) {
|
Chris@0
|
146 return $this->data['copyright'];
|
Chris@0
|
147 }
|
Chris@0
|
148
|
Chris@0
|
149 $copyright = null;
|
Chris@0
|
150
|
Chris@0
|
151 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
152 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
153 $copyright = $this->xpath->evaluate('string(/rss/channel/copyright)');
|
Chris@0
|
154 }
|
Chris@0
|
155
|
Chris@12
|
156 if (! $copyright && $this->getExtension('DublinCore') !== null) {
|
Chris@0
|
157 $copyright = $this->getExtension('DublinCore')->getCopyright();
|
Chris@0
|
158 }
|
Chris@0
|
159
|
Chris@0
|
160 if (empty($copyright)) {
|
Chris@0
|
161 $copyright = $this->getExtension('Atom')->getCopyright();
|
Chris@0
|
162 }
|
Chris@0
|
163
|
Chris@12
|
164 if (! $copyright) {
|
Chris@0
|
165 $copyright = null;
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168 $this->data['copyright'] = $copyright;
|
Chris@0
|
169
|
Chris@0
|
170 return $this->data['copyright'];
|
Chris@0
|
171 }
|
Chris@0
|
172
|
Chris@0
|
173 /**
|
Chris@0
|
174 * Get the feed creation date
|
Chris@0
|
175 *
|
Chris@12
|
176 * @return DateTime|null
|
Chris@0
|
177 */
|
Chris@0
|
178 public function getDateCreated()
|
Chris@0
|
179 {
|
Chris@0
|
180 return $this->getDateModified();
|
Chris@0
|
181 }
|
Chris@0
|
182
|
Chris@0
|
183 /**
|
Chris@0
|
184 * Get the feed modification date
|
Chris@0
|
185 *
|
Chris@0
|
186 * @return DateTime
|
Chris@0
|
187 * @throws Exception\RuntimeException
|
Chris@0
|
188 */
|
Chris@0
|
189 public function getDateModified()
|
Chris@0
|
190 {
|
Chris@0
|
191 if (array_key_exists('datemodified', $this->data)) {
|
Chris@0
|
192 return $this->data['datemodified'];
|
Chris@0
|
193 }
|
Chris@0
|
194
|
Chris@0
|
195 $date = null;
|
Chris@0
|
196
|
Chris@0
|
197 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
198 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
199 $dateModified = $this->xpath->evaluate('string(/rss/channel/pubDate)');
|
Chris@12
|
200 if (! $dateModified) {
|
Chris@0
|
201 $dateModified = $this->xpath->evaluate('string(/rss/channel/lastBuildDate)');
|
Chris@0
|
202 }
|
Chris@0
|
203 if ($dateModified) {
|
Chris@0
|
204 $dateModifiedParsed = strtotime($dateModified);
|
Chris@0
|
205 if ($dateModifiedParsed) {
|
Chris@0
|
206 $date = new DateTime('@' . $dateModifiedParsed);
|
Chris@0
|
207 } else {
|
Chris@0
|
208 $dateStandards = [DateTime::RSS, DateTime::RFC822,
|
Chris@0
|
209 DateTime::RFC2822, null];
|
Chris@0
|
210 foreach ($dateStandards as $standard) {
|
Chris@0
|
211 try {
|
Chris@0
|
212 $date = DateTime::createFromFormat($standard, $dateModified);
|
Chris@0
|
213 break;
|
Chris@0
|
214 } catch (\Exception $e) {
|
Chris@0
|
215 if ($standard === null) {
|
Chris@0
|
216 throw new Exception\RuntimeException(
|
Chris@0
|
217 'Could not load date due to unrecognised'
|
Chris@0
|
218 .' format (should follow RFC 822 or 2822):'
|
Chris@0
|
219 . $e->getMessage(),
|
Chris@12
|
220 0,
|
Chris@12
|
221 $e
|
Chris@0
|
222 );
|
Chris@0
|
223 }
|
Chris@0
|
224 }
|
Chris@0
|
225 }
|
Chris@0
|
226 }
|
Chris@0
|
227 }
|
Chris@0
|
228 }
|
Chris@0
|
229
|
Chris@12
|
230 if (! $date) {
|
Chris@0
|
231 $date = $this->getExtension('DublinCore')->getDate();
|
Chris@0
|
232 }
|
Chris@0
|
233
|
Chris@12
|
234 if (! $date) {
|
Chris@0
|
235 $date = $this->getExtension('Atom')->getDateModified();
|
Chris@0
|
236 }
|
Chris@0
|
237
|
Chris@12
|
238 if (! $date) {
|
Chris@0
|
239 $date = null;
|
Chris@0
|
240 }
|
Chris@0
|
241
|
Chris@0
|
242 $this->data['datemodified'] = $date;
|
Chris@0
|
243
|
Chris@0
|
244 return $this->data['datemodified'];
|
Chris@0
|
245 }
|
Chris@0
|
246
|
Chris@0
|
247 /**
|
Chris@0
|
248 * Get the feed lastBuild date
|
Chris@0
|
249 *
|
Chris@0
|
250 * @throws Exception\RuntimeException
|
Chris@0
|
251 * @return DateTime
|
Chris@0
|
252 */
|
Chris@0
|
253 public function getLastBuildDate()
|
Chris@0
|
254 {
|
Chris@0
|
255 if (array_key_exists('lastBuildDate', $this->data)) {
|
Chris@0
|
256 return $this->data['lastBuildDate'];
|
Chris@0
|
257 }
|
Chris@0
|
258
|
Chris@0
|
259 $date = null;
|
Chris@0
|
260
|
Chris@0
|
261 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
262 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
263 $lastBuildDate = $this->xpath->evaluate('string(/rss/channel/lastBuildDate)');
|
Chris@0
|
264 if ($lastBuildDate) {
|
Chris@0
|
265 $lastBuildDateParsed = strtotime($lastBuildDate);
|
Chris@0
|
266 if ($lastBuildDateParsed) {
|
Chris@0
|
267 $date = new DateTime('@' . $lastBuildDateParsed);
|
Chris@0
|
268 } else {
|
Chris@0
|
269 $dateStandards = [DateTime::RSS, DateTime::RFC822,
|
Chris@0
|
270 DateTime::RFC2822, null];
|
Chris@0
|
271 foreach ($dateStandards as $standard) {
|
Chris@0
|
272 try {
|
Chris@0
|
273 $date = DateTime::createFromFormat($standard, $lastBuildDateParsed);
|
Chris@0
|
274 break;
|
Chris@0
|
275 } catch (\Exception $e) {
|
Chris@0
|
276 if ($standard === null) {
|
Chris@0
|
277 throw new Exception\RuntimeException(
|
Chris@0
|
278 'Could not load date due to unrecognised'
|
Chris@0
|
279 .' format (should follow RFC 822 or 2822):'
|
Chris@0
|
280 . $e->getMessage(),
|
Chris@12
|
281 0,
|
Chris@12
|
282 $e
|
Chris@0
|
283 );
|
Chris@0
|
284 }
|
Chris@0
|
285 }
|
Chris@0
|
286 }
|
Chris@0
|
287 }
|
Chris@0
|
288 }
|
Chris@0
|
289 }
|
Chris@0
|
290
|
Chris@12
|
291 if (! $date) {
|
Chris@0
|
292 $date = null;
|
Chris@0
|
293 }
|
Chris@0
|
294
|
Chris@0
|
295 $this->data['lastBuildDate'] = $date;
|
Chris@0
|
296
|
Chris@0
|
297 return $this->data['lastBuildDate'];
|
Chris@0
|
298 }
|
Chris@0
|
299
|
Chris@0
|
300 /**
|
Chris@0
|
301 * Get the feed description
|
Chris@0
|
302 *
|
Chris@0
|
303 * @return string|null
|
Chris@0
|
304 */
|
Chris@0
|
305 public function getDescription()
|
Chris@0
|
306 {
|
Chris@0
|
307 if (array_key_exists('description', $this->data)) {
|
Chris@0
|
308 return $this->data['description'];
|
Chris@0
|
309 }
|
Chris@0
|
310
|
Chris@0
|
311 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
312 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
313 $description = $this->xpath->evaluate('string(/rss/channel/description)');
|
Chris@0
|
314 } else {
|
Chris@0
|
315 $description = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:description)');
|
Chris@0
|
316 }
|
Chris@0
|
317
|
Chris@12
|
318 if (! $description && $this->getExtension('DublinCore') !== null) {
|
Chris@0
|
319 $description = $this->getExtension('DublinCore')->getDescription();
|
Chris@0
|
320 }
|
Chris@0
|
321
|
Chris@0
|
322 if (empty($description)) {
|
Chris@0
|
323 $description = $this->getExtension('Atom')->getDescription();
|
Chris@0
|
324 }
|
Chris@0
|
325
|
Chris@12
|
326 if (! $description) {
|
Chris@0
|
327 $description = null;
|
Chris@0
|
328 }
|
Chris@0
|
329
|
Chris@0
|
330 $this->data['description'] = $description;
|
Chris@0
|
331
|
Chris@0
|
332 return $this->data['description'];
|
Chris@0
|
333 }
|
Chris@0
|
334
|
Chris@0
|
335 /**
|
Chris@0
|
336 * Get the feed ID
|
Chris@0
|
337 *
|
Chris@0
|
338 * @return string|null
|
Chris@0
|
339 */
|
Chris@0
|
340 public function getId()
|
Chris@0
|
341 {
|
Chris@0
|
342 if (array_key_exists('id', $this->data)) {
|
Chris@0
|
343 return $this->data['id'];
|
Chris@0
|
344 }
|
Chris@0
|
345
|
Chris@0
|
346 $id = null;
|
Chris@0
|
347
|
Chris@0
|
348 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
349 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
350 $id = $this->xpath->evaluate('string(/rss/channel/guid)');
|
Chris@0
|
351 }
|
Chris@0
|
352
|
Chris@12
|
353 if (! $id && $this->getExtension('DublinCore') !== null) {
|
Chris@0
|
354 $id = $this->getExtension('DublinCore')->getId();
|
Chris@0
|
355 }
|
Chris@0
|
356
|
Chris@0
|
357 if (empty($id)) {
|
Chris@0
|
358 $id = $this->getExtension('Atom')->getId();
|
Chris@0
|
359 }
|
Chris@0
|
360
|
Chris@12
|
361 if (! $id) {
|
Chris@0
|
362 if ($this->getLink()) {
|
Chris@0
|
363 $id = $this->getLink();
|
Chris@0
|
364 } elseif ($this->getTitle()) {
|
Chris@0
|
365 $id = $this->getTitle();
|
Chris@0
|
366 } else {
|
Chris@0
|
367 $id = null;
|
Chris@0
|
368 }
|
Chris@0
|
369 }
|
Chris@0
|
370
|
Chris@0
|
371 $this->data['id'] = $id;
|
Chris@0
|
372
|
Chris@0
|
373 return $this->data['id'];
|
Chris@0
|
374 }
|
Chris@0
|
375
|
Chris@0
|
376 /**
|
Chris@0
|
377 * Get the feed image data
|
Chris@0
|
378 *
|
Chris@0
|
379 * @return array|null
|
Chris@0
|
380 */
|
Chris@0
|
381 public function getImage()
|
Chris@0
|
382 {
|
Chris@0
|
383 if (array_key_exists('image', $this->data)) {
|
Chris@0
|
384 return $this->data['image'];
|
Chris@0
|
385 }
|
Chris@0
|
386
|
Chris@0
|
387 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
388 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
389 $list = $this->xpath->query('/rss/channel/image');
|
Chris@0
|
390 $prefix = '/rss/channel/image[1]';
|
Chris@0
|
391 } else {
|
Chris@0
|
392 $list = $this->xpath->query('/rdf:RDF/rss:channel/rss:image');
|
Chris@0
|
393 $prefix = '/rdf:RDF/rss:channel/rss:image[1]';
|
Chris@0
|
394 }
|
Chris@0
|
395 if ($list->length > 0) {
|
Chris@0
|
396 $image = [];
|
Chris@0
|
397 $value = $this->xpath->evaluate('string(' . $prefix . '/url)');
|
Chris@0
|
398 if ($value) {
|
Chris@0
|
399 $image['uri'] = $value;
|
Chris@0
|
400 }
|
Chris@0
|
401 $value = $this->xpath->evaluate('string(' . $prefix . '/link)');
|
Chris@0
|
402 if ($value) {
|
Chris@0
|
403 $image['link'] = $value;
|
Chris@0
|
404 }
|
Chris@0
|
405 $value = $this->xpath->evaluate('string(' . $prefix . '/title)');
|
Chris@0
|
406 if ($value) {
|
Chris@0
|
407 $image['title'] = $value;
|
Chris@0
|
408 }
|
Chris@0
|
409 $value = $this->xpath->evaluate('string(' . $prefix . '/height)');
|
Chris@0
|
410 if ($value) {
|
Chris@0
|
411 $image['height'] = $value;
|
Chris@0
|
412 }
|
Chris@0
|
413 $value = $this->xpath->evaluate('string(' . $prefix . '/width)');
|
Chris@0
|
414 if ($value) {
|
Chris@0
|
415 $image['width'] = $value;
|
Chris@0
|
416 }
|
Chris@0
|
417 $value = $this->xpath->evaluate('string(' . $prefix . '/description)');
|
Chris@0
|
418 if ($value) {
|
Chris@0
|
419 $image['description'] = $value;
|
Chris@0
|
420 }
|
Chris@0
|
421 } else {
|
Chris@0
|
422 $image = null;
|
Chris@0
|
423 }
|
Chris@0
|
424
|
Chris@0
|
425 $this->data['image'] = $image;
|
Chris@0
|
426
|
Chris@0
|
427 return $this->data['image'];
|
Chris@0
|
428 }
|
Chris@0
|
429
|
Chris@0
|
430 /**
|
Chris@0
|
431 * Get the feed language
|
Chris@0
|
432 *
|
Chris@0
|
433 * @return string|null
|
Chris@0
|
434 */
|
Chris@0
|
435 public function getLanguage()
|
Chris@0
|
436 {
|
Chris@0
|
437 if (array_key_exists('language', $this->data)) {
|
Chris@0
|
438 return $this->data['language'];
|
Chris@0
|
439 }
|
Chris@0
|
440
|
Chris@0
|
441 $language = null;
|
Chris@0
|
442
|
Chris@0
|
443 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
444 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
445 $language = $this->xpath->evaluate('string(/rss/channel/language)');
|
Chris@0
|
446 }
|
Chris@0
|
447
|
Chris@12
|
448 if (! $language && $this->getExtension('DublinCore') !== null) {
|
Chris@0
|
449 $language = $this->getExtension('DublinCore')->getLanguage();
|
Chris@0
|
450 }
|
Chris@0
|
451
|
Chris@0
|
452 if (empty($language)) {
|
Chris@0
|
453 $language = $this->getExtension('Atom')->getLanguage();
|
Chris@0
|
454 }
|
Chris@0
|
455
|
Chris@12
|
456 if (! $language) {
|
Chris@0
|
457 $language = $this->xpath->evaluate('string(//@xml:lang[1])');
|
Chris@0
|
458 }
|
Chris@0
|
459
|
Chris@12
|
460 if (! $language) {
|
Chris@0
|
461 $language = null;
|
Chris@0
|
462 }
|
Chris@0
|
463
|
Chris@0
|
464 $this->data['language'] = $language;
|
Chris@0
|
465
|
Chris@0
|
466 return $this->data['language'];
|
Chris@0
|
467 }
|
Chris@0
|
468
|
Chris@0
|
469 /**
|
Chris@0
|
470 * Get a link to the feed
|
Chris@0
|
471 *
|
Chris@0
|
472 * @return string|null
|
Chris@0
|
473 */
|
Chris@0
|
474 public function getLink()
|
Chris@0
|
475 {
|
Chris@0
|
476 if (array_key_exists('link', $this->data)) {
|
Chris@0
|
477 return $this->data['link'];
|
Chris@0
|
478 }
|
Chris@0
|
479
|
Chris@0
|
480 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
481 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
482 $link = $this->xpath->evaluate('string(/rss/channel/link)');
|
Chris@0
|
483 } else {
|
Chris@0
|
484 $link = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:link)');
|
Chris@0
|
485 }
|
Chris@0
|
486
|
Chris@0
|
487 if (empty($link)) {
|
Chris@0
|
488 $link = $this->getExtension('Atom')->getLink();
|
Chris@0
|
489 }
|
Chris@0
|
490
|
Chris@12
|
491 if (! $link) {
|
Chris@0
|
492 $link = null;
|
Chris@0
|
493 }
|
Chris@0
|
494
|
Chris@0
|
495 $this->data['link'] = $link;
|
Chris@0
|
496
|
Chris@0
|
497 return $this->data['link'];
|
Chris@0
|
498 }
|
Chris@0
|
499
|
Chris@0
|
500 /**
|
Chris@0
|
501 * Get a link to the feed XML
|
Chris@0
|
502 *
|
Chris@0
|
503 * @return string|null
|
Chris@0
|
504 */
|
Chris@0
|
505 public function getFeedLink()
|
Chris@0
|
506 {
|
Chris@0
|
507 if (array_key_exists('feedlink', $this->data)) {
|
Chris@0
|
508 return $this->data['feedlink'];
|
Chris@0
|
509 }
|
Chris@0
|
510
|
Chris@0
|
511 $link = $this->getExtension('Atom')->getFeedLink();
|
Chris@0
|
512
|
Chris@0
|
513 if ($link === null || empty($link)) {
|
Chris@0
|
514 $link = $this->getOriginalSourceUri();
|
Chris@0
|
515 }
|
Chris@0
|
516
|
Chris@0
|
517 $this->data['feedlink'] = $link;
|
Chris@0
|
518
|
Chris@0
|
519 return $this->data['feedlink'];
|
Chris@0
|
520 }
|
Chris@0
|
521
|
Chris@0
|
522 /**
|
Chris@0
|
523 * Get the feed generator entry
|
Chris@0
|
524 *
|
Chris@0
|
525 * @return string|null
|
Chris@0
|
526 */
|
Chris@0
|
527 public function getGenerator()
|
Chris@0
|
528 {
|
Chris@0
|
529 if (array_key_exists('generator', $this->data)) {
|
Chris@0
|
530 return $this->data['generator'];
|
Chris@0
|
531 }
|
Chris@0
|
532
|
Chris@0
|
533 $generator = null;
|
Chris@0
|
534
|
Chris@0
|
535 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
536 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
537 $generator = $this->xpath->evaluate('string(/rss/channel/generator)');
|
Chris@0
|
538 }
|
Chris@0
|
539
|
Chris@12
|
540 if (! $generator) {
|
Chris@0
|
541 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
542 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
543 $generator = $this->xpath->evaluate('string(/rss/channel/atom:generator)');
|
Chris@0
|
544 } else {
|
Chris@0
|
545 $generator = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/atom:generator)');
|
Chris@0
|
546 }
|
Chris@0
|
547 }
|
Chris@0
|
548
|
Chris@0
|
549 if (empty($generator)) {
|
Chris@0
|
550 $generator = $this->getExtension('Atom')->getGenerator();
|
Chris@0
|
551 }
|
Chris@0
|
552
|
Chris@12
|
553 if (! $generator) {
|
Chris@0
|
554 $generator = null;
|
Chris@0
|
555 }
|
Chris@0
|
556
|
Chris@0
|
557 $this->data['generator'] = $generator;
|
Chris@0
|
558
|
Chris@0
|
559 return $this->data['generator'];
|
Chris@0
|
560 }
|
Chris@0
|
561
|
Chris@0
|
562 /**
|
Chris@0
|
563 * Get the feed title
|
Chris@0
|
564 *
|
Chris@0
|
565 * @return string|null
|
Chris@0
|
566 */
|
Chris@0
|
567 public function getTitle()
|
Chris@0
|
568 {
|
Chris@0
|
569 if (array_key_exists('title', $this->data)) {
|
Chris@0
|
570 return $this->data['title'];
|
Chris@0
|
571 }
|
Chris@0
|
572
|
Chris@0
|
573 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
574 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
575 $title = $this->xpath->evaluate('string(/rss/channel/title)');
|
Chris@0
|
576 } else {
|
Chris@0
|
577 $title = $this->xpath->evaluate('string(/rdf:RDF/rss:channel/rss:title)');
|
Chris@0
|
578 }
|
Chris@0
|
579
|
Chris@12
|
580 if (! $title && $this->getExtension('DublinCore') !== null) {
|
Chris@0
|
581 $title = $this->getExtension('DublinCore')->getTitle();
|
Chris@0
|
582 }
|
Chris@0
|
583
|
Chris@12
|
584 if (! $title) {
|
Chris@0
|
585 $title = $this->getExtension('Atom')->getTitle();
|
Chris@0
|
586 }
|
Chris@0
|
587
|
Chris@12
|
588 if (! $title) {
|
Chris@0
|
589 $title = null;
|
Chris@0
|
590 }
|
Chris@0
|
591
|
Chris@0
|
592 $this->data['title'] = $title;
|
Chris@0
|
593
|
Chris@0
|
594 return $this->data['title'];
|
Chris@0
|
595 }
|
Chris@0
|
596
|
Chris@0
|
597 /**
|
Chris@0
|
598 * Get an array of any supported Pusubhubbub endpoints
|
Chris@0
|
599 *
|
Chris@0
|
600 * @return array|null
|
Chris@0
|
601 */
|
Chris@0
|
602 public function getHubs()
|
Chris@0
|
603 {
|
Chris@0
|
604 if (array_key_exists('hubs', $this->data)) {
|
Chris@0
|
605 return $this->data['hubs'];
|
Chris@0
|
606 }
|
Chris@0
|
607
|
Chris@0
|
608 $hubs = $this->getExtension('Atom')->getHubs();
|
Chris@0
|
609
|
Chris@0
|
610 if (empty($hubs)) {
|
Chris@0
|
611 $hubs = null;
|
Chris@0
|
612 } else {
|
Chris@0
|
613 $hubs = array_unique($hubs);
|
Chris@0
|
614 }
|
Chris@0
|
615
|
Chris@0
|
616 $this->data['hubs'] = $hubs;
|
Chris@0
|
617
|
Chris@0
|
618 return $this->data['hubs'];
|
Chris@0
|
619 }
|
Chris@0
|
620
|
Chris@0
|
621 /**
|
Chris@0
|
622 * Get all categories
|
Chris@0
|
623 *
|
Chris@0
|
624 * @return Reader\Collection\Category
|
Chris@0
|
625 */
|
Chris@0
|
626 public function getCategories()
|
Chris@0
|
627 {
|
Chris@0
|
628 if (array_key_exists('categories', $this->data)) {
|
Chris@0
|
629 return $this->data['categories'];
|
Chris@0
|
630 }
|
Chris@0
|
631
|
Chris@0
|
632 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 &&
|
Chris@0
|
633 $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
634 $list = $this->xpath->query('/rss/channel//category');
|
Chris@0
|
635 } else {
|
Chris@0
|
636 $list = $this->xpath->query('/rdf:RDF/rss:channel//rss:category');
|
Chris@0
|
637 }
|
Chris@0
|
638
|
Chris@0
|
639 if ($list->length) {
|
Chris@0
|
640 $categoryCollection = new Collection\Category;
|
Chris@0
|
641 foreach ($list as $category) {
|
Chris@0
|
642 $categoryCollection[] = [
|
Chris@0
|
643 'term' => $category->nodeValue,
|
Chris@0
|
644 'scheme' => $category->getAttribute('domain'),
|
Chris@0
|
645 'label' => $category->nodeValue,
|
Chris@0
|
646 ];
|
Chris@0
|
647 }
|
Chris@0
|
648 } else {
|
Chris@0
|
649 $categoryCollection = $this->getExtension('DublinCore')->getCategories();
|
Chris@0
|
650 }
|
Chris@0
|
651
|
Chris@0
|
652 if (count($categoryCollection) == 0) {
|
Chris@0
|
653 $categoryCollection = $this->getExtension('Atom')->getCategories();
|
Chris@0
|
654 }
|
Chris@0
|
655
|
Chris@0
|
656 $this->data['categories'] = $categoryCollection;
|
Chris@0
|
657
|
Chris@0
|
658 return $this->data['categories'];
|
Chris@0
|
659 }
|
Chris@0
|
660
|
Chris@0
|
661 /**
|
Chris@0
|
662 * Read all entries to the internal entries array
|
Chris@0
|
663 *
|
Chris@0
|
664 */
|
Chris@0
|
665 protected function indexEntries()
|
Chris@0
|
666 {
|
Chris@0
|
667 if ($this->getType() !== Reader\Reader::TYPE_RSS_10 && $this->getType() !== Reader\Reader::TYPE_RSS_090) {
|
Chris@0
|
668 $entries = $this->xpath->evaluate('//item');
|
Chris@0
|
669 } else {
|
Chris@0
|
670 $entries = $this->xpath->evaluate('//rss:item');
|
Chris@0
|
671 }
|
Chris@0
|
672
|
Chris@0
|
673 foreach ($entries as $index => $entry) {
|
Chris@0
|
674 $this->entries[$index] = $entry;
|
Chris@0
|
675 }
|
Chris@0
|
676 }
|
Chris@0
|
677
|
Chris@0
|
678 /**
|
Chris@0
|
679 * Register the default namespaces for the current feed format
|
Chris@0
|
680 *
|
Chris@0
|
681 */
|
Chris@0
|
682 protected function registerNamespaces()
|
Chris@0
|
683 {
|
Chris@0
|
684 switch ($this->data['type']) {
|
Chris@0
|
685 case Reader\Reader::TYPE_RSS_10:
|
Chris@0
|
686 $this->xpath->registerNamespace('rdf', Reader\Reader::NAMESPACE_RDF);
|
Chris@0
|
687 $this->xpath->registerNamespace('rss', Reader\Reader::NAMESPACE_RSS_10);
|
Chris@0
|
688 break;
|
Chris@0
|
689
|
Chris@0
|
690 case Reader\Reader::TYPE_RSS_090:
|
Chris@0
|
691 $this->xpath->registerNamespace('rdf', Reader\Reader::NAMESPACE_RDF);
|
Chris@0
|
692 $this->xpath->registerNamespace('rss', Reader\Reader::NAMESPACE_RSS_090);
|
Chris@0
|
693 break;
|
Chris@0
|
694 }
|
Chris@0
|
695 }
|
Chris@0
|
696 }
|