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;
|
Chris@0
|
11
|
Chris@0
|
12 use ArrayObject;
|
Chris@0
|
13 use DOMNodeList;
|
Chris@0
|
14 use Zend\Feed\Uri;
|
Chris@0
|
15
|
Chris@0
|
16 class FeedSet extends ArrayObject
|
Chris@0
|
17 {
|
Chris@0
|
18 public $rss = null;
|
Chris@0
|
19
|
Chris@0
|
20 public $rdf = null;
|
Chris@0
|
21
|
Chris@0
|
22 public $atom = null;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * Import a DOMNodeList from any document containing a set of links
|
Chris@0
|
26 * for alternate versions of a document, which will normally refer to
|
Chris@0
|
27 * RSS/RDF/Atom feeds for the current document.
|
Chris@0
|
28 *
|
Chris@0
|
29 * All such links are stored internally, however the first instance of
|
Chris@0
|
30 * each RSS, RDF or Atom type has its URI stored as a public property
|
Chris@0
|
31 * as a shortcut where the use case is simply to get a quick feed ref.
|
Chris@0
|
32 *
|
Chris@0
|
33 * Note that feeds are not loaded at this point, but will be lazy
|
Chris@0
|
34 * loaded automatically when each links 'feed' array key is accessed.
|
Chris@0
|
35 *
|
Chris@0
|
36 * @param DOMNodeList $links
|
Chris@0
|
37 * @param string $uri
|
Chris@0
|
38 * @return void
|
Chris@0
|
39 */
|
Chris@0
|
40 public function addLinks(DOMNodeList $links, $uri)
|
Chris@0
|
41 {
|
Chris@0
|
42 foreach ($links as $link) {
|
Chris@0
|
43 if (strtolower($link->getAttribute('rel')) !== 'alternate'
|
Chris@0
|
44 || !$link->getAttribute('type') || !$link->getAttribute('href')) {
|
Chris@0
|
45 continue;
|
Chris@0
|
46 }
|
Chris@0
|
47 if (!isset($this->rss) && $link->getAttribute('type') == 'application/rss+xml') {
|
Chris@0
|
48 $this->rss = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
|
Chris@0
|
49 } elseif (!isset($this->atom) && $link->getAttribute('type') == 'application/atom+xml') {
|
Chris@0
|
50 $this->atom = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
|
Chris@0
|
51 } elseif (!isset($this->rdf) && $link->getAttribute('type') == 'application/rdf+xml') {
|
Chris@0
|
52 $this->rdf = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
|
Chris@0
|
53 }
|
Chris@0
|
54 $this[] = new static([
|
Chris@0
|
55 'rel' => 'alternate',
|
Chris@0
|
56 'type' => $link->getAttribute('type'),
|
Chris@0
|
57 'href' => $this->absolutiseUri(trim($link->getAttribute('href')), $uri),
|
Chris@0
|
58 ]);
|
Chris@0
|
59 }
|
Chris@0
|
60 }
|
Chris@0
|
61
|
Chris@0
|
62 /**
|
Chris@0
|
63 * Attempt to turn a relative URI into an absolute URI
|
Chris@0
|
64 */
|
Chris@0
|
65 protected function absolutiseUri($link, $uri = null)
|
Chris@0
|
66 {
|
Chris@0
|
67 $linkUri = Uri::factory($link);
|
Chris@0
|
68 if (!$linkUri->isAbsolute() or !$linkUri->isValid()) {
|
Chris@0
|
69 if ($uri !== null) {
|
Chris@0
|
70 $uri = Uri::factory($uri);
|
Chris@0
|
71
|
Chris@0
|
72 if ($link[0] !== '/') {
|
Chris@0
|
73 $link = $uri->getPath() . '/' . $link;
|
Chris@0
|
74 }
|
Chris@0
|
75
|
Chris@0
|
76 $link = sprintf(
|
Chris@0
|
77 '%s://%s/%s',
|
Chris@0
|
78 ($uri->getScheme() ?: 'http'),
|
Chris@0
|
79 $uri->getHost(),
|
Chris@0
|
80 $this->canonicalizePath($link)
|
Chris@0
|
81 );
|
Chris@0
|
82
|
Chris@0
|
83 if (!Uri::factory($link)->isValid()) {
|
Chris@0
|
84 $link = null;
|
Chris@0
|
85 }
|
Chris@0
|
86 }
|
Chris@0
|
87 }
|
Chris@0
|
88 return $link;
|
Chris@0
|
89 }
|
Chris@0
|
90
|
Chris@0
|
91 /**
|
Chris@0
|
92 * Canonicalize relative path
|
Chris@0
|
93 */
|
Chris@0
|
94 protected function canonicalizePath($path)
|
Chris@0
|
95 {
|
Chris@0
|
96 $parts = array_filter(explode('/', $path));
|
Chris@0
|
97 $absolutes = [];
|
Chris@0
|
98 foreach ($parts as $part) {
|
Chris@0
|
99 if ('.' == $part) {
|
Chris@0
|
100 continue;
|
Chris@0
|
101 }
|
Chris@0
|
102 if ('..' == $part) {
|
Chris@0
|
103 array_pop($absolutes);
|
Chris@0
|
104 } else {
|
Chris@0
|
105 $absolutes[] = $part;
|
Chris@0
|
106 }
|
Chris@0
|
107 }
|
Chris@0
|
108 return implode('/', $absolutes);
|
Chris@0
|
109 }
|
Chris@0
|
110
|
Chris@0
|
111 /**
|
Chris@0
|
112 * Supports lazy loading of feeds using Reader::import() but
|
Chris@0
|
113 * delegates any other operations to the parent class.
|
Chris@0
|
114 *
|
Chris@0
|
115 * @param string $offset
|
Chris@0
|
116 * @return mixed
|
Chris@0
|
117 */
|
Chris@0
|
118 public function offsetGet($offset)
|
Chris@0
|
119 {
|
Chris@0
|
120 if ($offset == 'feed' && !$this->offsetExists('feed')) {
|
Chris@0
|
121 if (!$this->offsetExists('href')) {
|
Chris@0
|
122 return;
|
Chris@0
|
123 }
|
Chris@0
|
124 $feed = Reader::import($this->offsetGet('href'));
|
Chris@0
|
125 $this->offsetSet('feed', $feed);
|
Chris@0
|
126 return $feed;
|
Chris@0
|
127 }
|
Chris@0
|
128 return parent::offsetGet($offset);
|
Chris@0
|
129 }
|
Chris@0
|
130 }
|