Security update for Core, with self-updated composer
[yaffs-website] / vendor / zendframework / zend-feed / src / Reader / Feed / AbstractFeed.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\Feed;
11
12 use DOMDocument;
13 use DOMElement;
14 use DOMXPath;
15 use Zend\Feed\Reader;
16 use Zend\Feed\Reader\Exception;
17
18 /**
19 */
20 abstract class AbstractFeed implements FeedInterface
21 {
22     /**
23      * Parsed feed data
24      *
25      * @var array
26      */
27     protected $data = [];
28
29     /**
30      * Parsed feed data in the shape of a DOMDocument
31      *
32      * @var DOMDocument
33      */
34     protected $domDocument = null;
35
36     /**
37      * An array of parsed feed entries
38      *
39      * @var array
40      */
41     protected $entries = [];
42
43     /**
44      * A pointer for the iterator to keep track of the entries array
45      *
46      * @var int
47      */
48     protected $entriesKey = 0;
49
50     /**
51      * The base XPath query used to retrieve feed data
52      *
53      * @var DOMXPath
54      */
55     protected $xpath = null;
56
57     /**
58      * Array of loaded extensions
59      *
60      * @var array
61      */
62     protected $extensions = [];
63
64     /**
65      * Original Source URI (set if imported from a URI)
66      *
67      * @var string
68      */
69     protected $originalSourceUri = null;
70
71     /**
72      * Constructor
73      *
74      * @param DOMDocument $domDocument The DOM object for the feed's XML
75      * @param string $type Feed type
76      */
77     public function __construct(DOMDocument $domDocument, $type = null)
78     {
79         $this->domDocument = $domDocument;
80         $this->xpath = new DOMXPath($this->domDocument);
81
82         if ($type !== null) {
83             $this->data['type'] = $type;
84         } else {
85             $this->data['type'] = Reader\Reader::detectType($this->domDocument);
86         }
87         $this->registerNamespaces();
88         $this->indexEntries();
89         $this->loadExtensions();
90     }
91
92     /**
93      * Set an original source URI for the feed being parsed. This value
94      * is returned from getFeedLink() method if the feed does not carry
95      * a self-referencing URI.
96      *
97      * @param string $uri
98      */
99     public function setOriginalSourceUri($uri)
100     {
101         $this->originalSourceUri = $uri;
102     }
103
104     /**
105      * Get an original source URI for the feed being parsed. Returns null if
106      * unset or the feed was not imported from a URI.
107      *
108      * @return string|null
109      */
110     public function getOriginalSourceUri()
111     {
112         return $this->originalSourceUri;
113     }
114
115     /**
116      * Get the number of feed entries.
117      * Required by the Iterator interface.
118      *
119      * @return int
120      */
121     public function count()
122     {
123         return count($this->entries);
124     }
125
126     /**
127      * Return the current entry
128      *
129      * @return \Zend\Feed\Reader\Entry\EntryInterface
130      */
131     public function current()
132     {
133         if (substr($this->getType(), 0, 3) == 'rss') {
134             $reader = new Reader\Entry\Rss($this->entries[$this->key()], $this->key(), $this->getType());
135         } else {
136             $reader = new Reader\Entry\Atom($this->entries[$this->key()], $this->key(), $this->getType());
137         }
138
139         $reader->setXpath($this->xpath);
140
141         return $reader;
142     }
143
144     /**
145      * Get the DOM
146      *
147      * @return DOMDocument
148      */
149     public function getDomDocument()
150     {
151         return $this->domDocument;
152     }
153
154     /**
155      * Get the Feed's encoding
156      *
157      * @return string
158      */
159     public function getEncoding()
160     {
161         $assumed = $this->getDomDocument()->encoding;
162         if (empty($assumed)) {
163             $assumed = 'UTF-8';
164         }
165         return $assumed;
166     }
167
168     /**
169      * Get feed as xml
170      *
171      * @return string
172      */
173     public function saveXml()
174     {
175         return $this->getDomDocument()->saveXML();
176     }
177
178     /**
179      * Get the DOMElement representing the items/feed element
180      *
181      * @return DOMElement
182      */
183     public function getElement()
184     {
185         return $this->getDomDocument()->documentElement;
186     }
187
188     /**
189      * Get the DOMXPath object for this feed
190      *
191      * @return DOMXPath
192      */
193     public function getXpath()
194     {
195         return $this->xpath;
196     }
197
198     /**
199      * Get the feed type
200      *
201      * @return string
202      */
203     public function getType()
204     {
205         return $this->data['type'];
206     }
207
208     /**
209      * Return the current feed key
210      *
211      * @return int
212      */
213     public function key()
214     {
215         return $this->entriesKey;
216     }
217
218     /**
219      * Move the feed pointer forward
220      *
221      */
222     public function next()
223     {
224         ++$this->entriesKey;
225     }
226
227     /**
228      * Reset the pointer in the feed object
229      *
230      */
231     public function rewind()
232     {
233         $this->entriesKey = 0;
234     }
235
236     /**
237      * Check to see if the iterator is still valid
238      *
239      * @return bool
240      */
241     public function valid()
242     {
243         return 0 <= $this->entriesKey && $this->entriesKey < $this->count();
244     }
245
246     public function getExtensions()
247     {
248         return $this->extensions;
249     }
250
251     public function __call($method, $args)
252     {
253         foreach ($this->extensions as $extension) {
254             if (method_exists($extension, $method)) {
255                 return call_user_func_array([$extension, $method], $args);
256             }
257         }
258         throw new Exception\BadMethodCallException('Method: ' . $method
259         . 'does not exist and could not be located on a registered Extension');
260     }
261
262     /**
263      * Return an Extension object with the matching name (postfixed with _Feed)
264      *
265      * @param string $name
266      * @return \Zend\Feed\Reader\Extension\AbstractFeed
267      */
268     public function getExtension($name)
269     {
270         if (array_key_exists($name . '\\Feed', $this->extensions)) {
271             return $this->extensions[$name . '\\Feed'];
272         }
273         return;
274     }
275
276     protected function loadExtensions()
277     {
278         $all     = Reader\Reader::getExtensions();
279         $manager = Reader\Reader::getExtensionManager();
280         $feed    = $all['feed'];
281         foreach ($feed as $extension) {
282             if (in_array($extension, $all['core'])) {
283                 continue;
284             }
285             if (! $manager->has($extension)) {
286                 throw new Exception\RuntimeException(
287                     sprintf('Unable to load extension "%s"; cannot find class', $extension)
288                 );
289             }
290             $plugin = $manager->get($extension);
291             $plugin->setDomDocument($this->getDomDocument());
292             $plugin->setType($this->data['type']);
293             $plugin->setXpath($this->xpath);
294             $this->extensions[$extension] = $plugin;
295         }
296     }
297
298     /**
299      * Read all entries to the internal entries array
300      *
301      */
302     abstract protected function indexEntries();
303
304     /**
305      * Register the default namespaces for the current feed format
306      *
307      */
308     abstract protected function registerNamespaces();
309 }