1<?php 2 3/** 4 * @see https://github.com/laminas/laminas-feed for the canonical source repository 5 * @copyright https://github.com/laminas/laminas-feed/blob/master/COPYRIGHT.md 6 * @license https://github.com/laminas/laminas-feed/blob/master/LICENSE.md New BSD License 7 */ 8 9namespace Laminas\Feed\Reader; 10 11use DOMDocument; 12use DOMElement; 13use DOMXPath; 14 15/** 16 * @deprecated This (abstract) class is deprecated. Use \Laminas\Feed\Reader\Feed\AbstractFeed instead. 17 */ 18abstract class AbstractFeed implements Feed\FeedInterface 19{ 20 /** 21 * Parsed feed data 22 * 23 * @var array 24 */ 25 protected $data = []; 26 27 /** 28 * Parsed feed data in the shape of a DOMDocument 29 * 30 * @var DOMDocument 31 */ 32 protected $domDocument; 33 34 /** 35 * An array of parsed feed entries 36 * 37 * @var array 38 */ 39 protected $entries = []; 40 41 /** 42 * A pointer for the iterator to keep track of the entries array 43 * 44 * @var int 45 */ 46 protected $entriesKey = 0; 47 48 /** 49 * The base XPath query used to retrieve feed data 50 * 51 * @var DOMXPath 52 */ 53 protected $xpath; 54 55 /** 56 * Array of loaded extensions 57 * 58 * @var array 59 */ 60 protected $extensions = []; 61 62 /** 63 * Original Source URI (set if imported from a URI) 64 * 65 * @var string 66 */ 67 protected $originalSourceUri; 68 69 /** 70 * @param DOMDocument $domDocument The DOM object for the feed's XML 71 * @param null|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 null|string 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 Entry\AbstractEntry 126 */ 127 public function current() 128 { 129 if (0 === strpos($this->getType(), '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 public function next() 218 { 219 ++$this->entriesKey; 220 } 221 222 /** 223 * Reset the pointer in the feed object 224 */ 225 public function rewind() 226 { 227 $this->entriesKey = 0; 228 } 229 230 /** 231 * Check to see if the iterator is still valid 232 * 233 * @return bool 234 */ 235 public function valid() 236 { 237 return 0 <= $this->entriesKey && $this->entriesKey < $this->count(); 238 } 239 240 public function getExtensions() 241 { 242 return $this->extensions; 243 } 244 245 public function __call($method, $args) 246 { 247 foreach ($this->extensions as $extension) { 248 if (method_exists($extension, $method)) { 249 return call_user_func_array([$extension, $method], $args); 250 } 251 } 252 throw new Exception\BadMethodCallException( 253 'Method: ' . $method . ' does not exist and could not be located on a registered Extension' 254 ); 255 } 256 257 /** 258 * Return an Extension object with the matching name (postfixed with _Feed) 259 * 260 * @param string $name 261 * @return Extension\AbstractFeed 262 */ 263 public function getExtension($name) 264 { 265 if (array_key_exists($name . '\Feed', $this->extensions)) { 266 return $this->extensions[$name . '\Feed']; 267 } 268 return; 269 } 270 271 protected function loadExtensions() 272 { 273 $all = Reader::getExtensions(); 274 $manager = Reader::getExtensionManager(); 275 $feed = $all['feed']; 276 foreach ($feed as $extension) { 277 if (in_array($extension, $all['core'])) { 278 continue; 279 } 280 $plugin = $manager->get($extension); 281 $plugin->setDomDocument($this->getDomDocument()); 282 $plugin->setType($this->data['type']); 283 $plugin->setXpath($this->xpath); 284 $this->extensions[$extension] = $plugin; 285 } 286 } 287 288 /** 289 * Read all entries to the internal entries array 290 */ 291 abstract protected function indexEntries(); 292 293 /** 294 * Register the default namespaces for the current feed format 295 */ 296 abstract protected function registerNamespaces(); 297} 298