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 * @return void 95 */ 96 public function setOriginalSourceUri($uri) 97 { 98 $this->originalSourceUri = $uri; 99 } 100 101 /** 102 * Get an original source URI for the feed being parsed. Returns null if 103 * unset or the feed was not imported from a URI. 104 * 105 * @return null|string 106 */ 107 public function getOriginalSourceUri() 108 { 109 return $this->originalSourceUri; 110 } 111 112 /** 113 * Get the number of feed entries. 114 * Required by the Iterator interface. 115 * 116 * @return int 117 */ 118 public function count() 119 { 120 return count($this->entries); 121 } 122 123 /** 124 * Return the current entry 125 * 126 * @return Entry\AbstractEntry 127 */ 128 public function current() 129 { 130 if (0 === strpos($this->getType(), 'rss')) { 131 $reader = new Entry\Rss($this->entries[$this->key()], $this->key(), $this->getType()); 132 } else { 133 $reader = new Entry\Atom($this->entries[$this->key()], $this->key(), $this->getType()); 134 } 135 136 $reader->setXpath($this->xpath); 137 138 return $reader; 139 } 140 141 /** 142 * Get the DOM 143 * 144 * @return DOMDocument 145 */ 146 public function getDomDocument() 147 { 148 return $this->domDocument; 149 } 150 151 /** 152 * Get the Feed's encoding 153 * 154 * @return string 155 */ 156 public function getEncoding() 157 { 158 $assumed = $this->getDomDocument()->encoding; 159 if (empty($assumed)) { 160 $assumed = 'UTF-8'; 161 } 162 return $assumed; 163 } 164 165 /** 166 * Get feed as xml 167 * 168 * @return string 169 */ 170 public function saveXml() 171 { 172 return $this->getDomDocument()->saveXML(); 173 } 174 175 /** 176 * Get the DOMElement representing the items/feed element 177 * 178 * @return DOMElement 179 */ 180 public function getElement() 181 { 182 return $this->getDomDocument()->documentElement; 183 } 184 185 /** 186 * Get the DOMXPath object for this feed 187 * 188 * @return DOMXPath 189 */ 190 public function getXpath() 191 { 192 return $this->xpath; 193 } 194 195 /** 196 * Get the feed type 197 * 198 * @return string 199 */ 200 public function getType() 201 { 202 return $this->data['type']; 203 } 204 205 /** 206 * Return the current feed key 207 * 208 * @return int 209 */ 210 public function key() 211 { 212 return $this->entriesKey; 213 } 214 215 /** 216 * Move the feed pointer forward 217 */ 218 public function next() 219 { 220 ++$this->entriesKey; 221 } 222 223 /** 224 * Reset the pointer in the feed object 225 */ 226 public function rewind() 227 { 228 $this->entriesKey = 0; 229 } 230 231 /** 232 * Check to see if the iterator is still valid 233 * 234 * @return bool 235 */ 236 public function valid() 237 { 238 return 0 <= $this->entriesKey && $this->entriesKey < $this->count(); 239 } 240 241 public function getExtensions() 242 { 243 return $this->extensions; 244 } 245 246 public function __call($method, $args) 247 { 248 foreach ($this->extensions as $extension) { 249 if (method_exists($extension, $method)) { 250 return call_user_func_array([$extension, $method], $args); 251 } 252 } 253 throw new Exception\BadMethodCallException( 254 'Method: ' . $method . ' does not exist and could not be located on a registered Extension' 255 ); 256 } 257 258 /** 259 * Return an Extension object with the matching name (postfixed with _Feed) 260 * 261 * @param string $name 262 * @return 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 abstract protected function indexEntries(); 293 294 /** 295 * Register the default namespaces for the current feed format 296 */ 297 abstract protected function registerNamespaces(); 298} 299