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