Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / zendframework / zend-feed / src / Reader / FeedSet.php
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;
11
12 use ArrayObject;
13 use DOMNodeList;
14 use Zend\Feed\Uri;
15
16 class FeedSet extends ArrayObject
17 {
18     public $rss = null;
19
20     public $rdf = null;
21
22     public $atom = null;
23
24     /**
25      * Import a DOMNodeList from any document containing a set of links
26      * for alternate versions of a document, which will normally refer to
27      * RSS/RDF/Atom feeds for the current document.
28      *
29      * All such links are stored internally, however the first instance of
30      * each RSS, RDF or Atom type has its URI stored as a public property
31      * as a shortcut where the use case is simply to get a quick feed ref.
32      *
33      * Note that feeds are not loaded at this point, but will be lazy
34      * loaded automatically when each links 'feed' array key is accessed.
35      *
36      * @param DOMNodeList $links
37      * @param string $uri
38      * @return void
39      */
40     public function addLinks(DOMNodeList $links, $uri)
41     {
42         foreach ($links as $link) {
43             if (strtolower($link->getAttribute('rel')) !== 'alternate'
44                 || ! $link->getAttribute('type') || ! $link->getAttribute('href')) {
45                 continue;
46             }
47             if (! isset($this->rss) && $link->getAttribute('type') == 'application/rss+xml') {
48                 $this->rss = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
49             } elseif (! isset($this->atom) && $link->getAttribute('type') == 'application/atom+xml') {
50                 $this->atom = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
51             } elseif (! isset($this->rdf) && $link->getAttribute('type') == 'application/rdf+xml') {
52                 $this->rdf = $this->absolutiseUri(trim($link->getAttribute('href')), $uri);
53             }
54             $this[] = new static([
55                 'rel' => 'alternate',
56                 'type' => $link->getAttribute('type'),
57                 'href' => $this->absolutiseUri(trim($link->getAttribute('href')), $uri),
58                 'title' => $link->getAttribute('title'),
59             ]);
60         }
61     }
62
63     /**
64      *  Attempt to turn a relative URI into an absolute URI
65      *
66      *  @param string $link
67      *  @param string $uri OPTIONAL
68      *  @return string|null absolutised link or null if invalid
69      */
70     protected function absolutiseUri($link, $uri = null)
71     {
72         $linkUri = Uri::factory($link);
73         if ($linkUri->isAbsolute()) {
74             // invalid absolute link can not be recovered
75             return $linkUri->isValid() ? $link : null;
76         }
77
78         $scheme = 'http';
79         if ($uri !== null) {
80             $uri = Uri::factory($uri);
81             $scheme = $uri->getScheme() ?: $scheme;
82         }
83
84         if ($linkUri->getHost()) {
85             $link = $this->resolveSchemeRelativeUri($link, $scheme);
86         } elseif ($uri !== null) {
87             $link = $this->resolveRelativeUri($link, $scheme, $uri->getHost(), $uri->getPath());
88         }
89
90         if (! Uri::factory($link)->isValid()) {
91             return null;
92         }
93
94         return $link;
95     }
96
97     /**
98      * Resolves scheme relative link to absolute
99      *
100      * @param string $link
101      * @param string $scheme
102      * @return string
103      */
104     private function resolveSchemeRelativeUri($link, $scheme)
105     {
106         $link = ltrim($link, '/');
107         return sprintf('%s://%s', $scheme, $link);
108     }
109
110     /**
111      *  Resolves relative link to absolute
112      *
113      *  @param string $link
114      *  @param string $scheme
115      *  @param string $host
116      *  @param string $uriPath
117      *  @return string
118      */
119     private function resolveRelativeUri($link, $scheme, $host, $uriPath)
120     {
121         if ($link[0] !== '/') {
122             $link = $uriPath . '/' . $link;
123         }
124         return sprintf(
125             '%s://%s/%s',
126             $scheme,
127             $host,
128             $this->canonicalizePath($link)
129         );
130     }
131
132     /**
133      *  Canonicalize relative path
134      */
135     protected function canonicalizePath($path)
136     {
137         $parts = array_filter(explode('/', $path));
138         $absolutes = [];
139         foreach ($parts as $part) {
140             if ('.' == $part) {
141                 continue;
142             }
143             if ('..' == $part) {
144                 array_pop($absolutes);
145             } else {
146                 $absolutes[] = $part;
147             }
148         }
149         return implode('/', $absolutes);
150     }
151
152     /**
153      * Supports lazy loading of feeds using Reader::import() but
154      * delegates any other operations to the parent class.
155      *
156      * @param string $offset
157      * @return mixed
158      */
159     public function offsetGet($offset)
160     {
161         if ($offset == 'feed' && ! $this->offsetExists('feed')) {
162             if (! $this->offsetExists('href')) {
163                 return;
164             }
165             $feed = Reader::import($this->offsetGet('href'));
166             $this->offsetSet('feed', $feed);
167             return $feed;
168         }
169         return parent::offsetGet($offset);
170     }
171 }