File indexing completed on 2025-01-19 05:21:05
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Feed_Reader 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Feed_Reader 0024 */ 0025 // require_once 'Zend/Feed/Reader.php'; 0026 0027 /** 0028 * @see Zend_Feed_Reader_EntryInterface 0029 */ 0030 // require_once 'Zend/Feed/Reader/EntryInterface.php'; 0031 0032 /** 0033 * @see Zend_Feed_Reader_EntryAbstract 0034 */ 0035 // require_once 'Zend/Feed/Reader/EntryAbstract.php'; 0036 0037 /** 0038 * @see Zend_Feed_Reader_Extension_DublinCore_Entry 0039 */ 0040 // require_once 'Zend/Feed/Reader/Extension/DublinCore/Entry.php'; 0041 0042 /** 0043 * @see Zend_Feed_Reader_Extension_Content_Entry 0044 */ 0045 // require_once 'Zend/Feed/Reader/Extension/Content/Entry.php'; 0046 0047 /** 0048 * @see Zend_Feed_Reader_Extension_Atom_Entry 0049 */ 0050 // require_once 'Zend/Feed/Reader/Extension/Atom/Entry.php'; 0051 0052 /** 0053 * @see Zend_Feed_Reader_Extension_WellformedWeb_Entry 0054 */ 0055 // require_once 'Zend/Feed/Reader/Extension/WellFormedWeb/Entry.php'; 0056 0057 /** 0058 * @see Zend_Feed_Reader_Extension_Slash_Entry 0059 */ 0060 // require_once 'Zend/Feed/Reader/Extension/Slash/Entry.php'; 0061 0062 /** 0063 * @see Zend_Feed_Reader_Extension_Thread_Entry 0064 */ 0065 // require_once 'Zend/Feed/Reader/Extension/Thread/Entry.php'; 0066 0067 /** 0068 * @see Zend_Date 0069 */ 0070 // require_once 'Zend/Date.php'; 0071 0072 /** 0073 * @see Zend_Feed_Reader_Collection_Category 0074 */ 0075 // require_once 'Zend/Feed/Reader/Collection/Category.php'; 0076 0077 /** 0078 * @category Zend 0079 * @package Zend_Feed_Reader 0080 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0081 * @license http://framework.zend.com/license/new-bsd New BSD License 0082 */ 0083 class Zend_Feed_Reader_Entry_Rss extends Zend_Feed_Reader_EntryAbstract implements Zend_Feed_Reader_EntryInterface 0084 { 0085 0086 /** 0087 * XPath query for RDF 0088 * 0089 * @var string 0090 */ 0091 protected $_xpathQueryRdf = ''; 0092 0093 /** 0094 * XPath query for RSS 0095 * 0096 * @var string 0097 */ 0098 protected $_xpathQueryRss = ''; 0099 0100 /** 0101 * Constructor 0102 * 0103 * @param Zend_Feed_Entry_Abstract $entry 0104 * @param string $entryKey 0105 * @param string $type 0106 * @return void 0107 */ 0108 public function __construct(DOMElement $entry, $entryKey, $type = null) 0109 { 0110 parent::__construct($entry, $entryKey, $type); 0111 $this->_xpathQueryRss = '//item[' . ($this->_entryKey+1) . ']'; 0112 $this->_xpathQueryRdf = '//rss:item[' . ($this->_entryKey+1) . ']'; 0113 0114 $pluginLoader = Zend_Feed_Reader::getPluginLoader(); 0115 0116 $dublinCoreClass = $pluginLoader->getClassName('DublinCore_Entry'); 0117 $this->_extensions['DublinCore_Entry'] = new $dublinCoreClass($entry, $entryKey, $type); 0118 0119 $contentClass = $pluginLoader->getClassName('Content_Entry'); 0120 $this->_extensions['Content_Entry'] = new $contentClass($entry, $entryKey, $type); 0121 0122 $atomClass = $pluginLoader->getClassName('Atom_Entry'); 0123 $this->_extensions['Atom_Entry'] = new $atomClass($entry, $entryKey, $type); 0124 0125 $wfwClass = $pluginLoader->getClassName('WellFormedWeb_Entry'); 0126 $this->_extensions['WellFormedWeb_Entry'] = new $wfwClass($entry, $entryKey, $type); 0127 0128 $slashClass = $pluginLoader->getClassName('Slash_Entry'); 0129 $this->_extensions['Slash_Entry'] = new $slashClass($entry, $entryKey, $type); 0130 0131 $threadClass = $pluginLoader->getClassName('Thread_Entry'); 0132 $this->_extensions['Thread_Entry'] = new $threadClass($entry, $entryKey, $type); 0133 } 0134 0135 /** 0136 * Get an author entry 0137 * 0138 * @param DOMElement $element 0139 * @return string 0140 */ 0141 public function getAuthor($index = 0) 0142 { 0143 $authors = $this->getAuthors(); 0144 0145 if (isset($authors[$index])) { 0146 return $authors[$index]; 0147 } 0148 0149 return null; 0150 } 0151 0152 /** 0153 * Get an array with feed authors 0154 * 0155 * @return array 0156 */ 0157 public function getAuthors() 0158 { 0159 if (array_key_exists('authors', $this->_data)) { 0160 return $this->_data['authors']; 0161 } 0162 0163 $authors = array(); 0164 $authors_dc = $this->getExtension('DublinCore')->getAuthors(); 0165 if (!empty($authors_dc)) { 0166 foreach ($authors_dc as $author) { 0167 $authors[] = array( 0168 'name' => $author['name'] 0169 ); 0170 } 0171 } 0172 0173 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0174 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) { 0175 $list = $this->_xpath->query($this->_xpathQueryRss . '//author'); 0176 } else { 0177 $list = $this->_xpath->query($this->_xpathQueryRdf . '//rss:author'); 0178 } 0179 if ($list->length) { 0180 foreach ($list as $author) { 0181 $string = trim($author->nodeValue); 0182 $email = null; 0183 $name = null; 0184 $data = array(); 0185 // Pretty rough parsing - but it's a catchall 0186 if (preg_match("/^.*@[^ ]*/", $string, $matches)) { 0187 $data['email'] = trim($matches[0]); 0188 if (preg_match("/\((.*)\)$/", $string, $matches)) { 0189 $data['name'] = $matches[1]; 0190 } 0191 $authors[] = $data; 0192 } 0193 } 0194 } 0195 0196 if (count($authors) == 0) { 0197 $authors = $this->getExtension('Atom')->getAuthors(); 0198 } else { 0199 $authors = new Zend_Feed_Reader_Collection_Author( 0200 Zend_Feed_Reader::arrayUnique($authors) 0201 ); 0202 } 0203 0204 if (count($authors) == 0) { 0205 $authors = null; 0206 } 0207 0208 $this->_data['authors'] = $authors; 0209 0210 return $this->_data['authors']; 0211 } 0212 0213 /** 0214 * Get the entry content 0215 * 0216 * @return string 0217 */ 0218 public function getContent() 0219 { 0220 if (array_key_exists('content', $this->_data)) { 0221 return $this->_data['content']; 0222 } 0223 0224 $content = $this->getExtension('Content')->getContent(); 0225 0226 if (!$content) { 0227 $content = $this->getDescription(); 0228 } 0229 0230 if (empty($content)) { 0231 $content = $this->getExtension('Atom')->getContent(); 0232 } 0233 0234 $this->_data['content'] = $content; 0235 0236 return $this->_data['content']; 0237 } 0238 0239 /** 0240 * Get the entry's date of creation 0241 * 0242 * @return string 0243 */ 0244 public function getDateCreated() 0245 { 0246 return $this->getDateModified(); 0247 } 0248 0249 /** 0250 * Get the entry's date of modification 0251 * 0252 * @return string 0253 */ 0254 public function getDateModified() 0255 { 0256 if (array_key_exists('datemodified', $this->_data)) { 0257 return $this->_data['datemodified']; 0258 } 0259 0260 $dateModified = null; 0261 $date = null; 0262 0263 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0264 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090 0265 ) { 0266 $dateModified = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/pubDate)'); 0267 if ($dateModified) { 0268 $dateModifiedParsed = strtotime($dateModified); 0269 if ($dateModifiedParsed) { 0270 $date = new Zend_Date($dateModifiedParsed); 0271 } else { 0272 $dateStandards = array(Zend_Date::RSS, Zend_Date::RFC_822, 0273 Zend_Date::RFC_2822, Zend_Date::DATES); 0274 $date = new Zend_Date; 0275 foreach ($dateStandards as $standard) { 0276 try { 0277 $date->set($dateModified, $standard); 0278 break; 0279 } catch (Zend_Date_Exception $e) { 0280 if ($standard == Zend_Date::DATES) { 0281 // require_once 'Zend/Feed/Exception.php'; 0282 throw new Zend_Feed_Exception( 0283 'Could not load date due to unrecognised' 0284 .' format (should follow RFC 822 or 2822):' 0285 . $e->getMessage(), 0286 0, $e 0287 ); 0288 } 0289 } 0290 } 0291 } 0292 } 0293 } 0294 0295 if (!$date) { 0296 $date = $this->getExtension('DublinCore')->getDate(); 0297 } 0298 0299 if (!$date) { 0300 $date = $this->getExtension('Atom')->getDateModified(); 0301 } 0302 0303 if (!$date) { 0304 $date = null; 0305 } 0306 0307 $this->_data['datemodified'] = $date; 0308 0309 return $this->_data['datemodified']; 0310 } 0311 0312 /** 0313 * Get the entry description 0314 * 0315 * @return string 0316 */ 0317 public function getDescription() 0318 { 0319 if (array_key_exists('description', $this->_data)) { 0320 return $this->_data['description']; 0321 } 0322 0323 $description = null; 0324 0325 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0326 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090 0327 ) { 0328 $description = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/description)'); 0329 } else { 0330 $description = $this->_xpath->evaluate('string('.$this->_xpathQueryRdf.'/rss:description)'); 0331 } 0332 0333 if (!$description) { 0334 $description = $this->getExtension('DublinCore')->getDescription(); 0335 } 0336 0337 if (empty($description)) { 0338 $description = $this->getExtension('Atom')->getDescription(); 0339 } 0340 0341 if (!$description) { 0342 $description = null; 0343 } 0344 0345 $this->_data['description'] = $description; 0346 0347 return $this->_data['description']; 0348 } 0349 0350 /** 0351 * Get the entry enclosure 0352 * @return string 0353 */ 0354 public function getEnclosure() 0355 { 0356 if (array_key_exists('enclosure', $this->_data)) { 0357 return $this->_data['enclosure']; 0358 } 0359 0360 $enclosure = null; 0361 0362 if ($this->getType() == Zend_Feed_Reader::TYPE_RSS_20) { 0363 $nodeList = $this->_xpath->query($this->_xpathQueryRss . '/enclosure'); 0364 0365 if ($nodeList->length > 0) { 0366 $enclosure = new stdClass(); 0367 $enclosure->url = $nodeList->item(0)->getAttribute('url'); 0368 $enclosure->length = $nodeList->item(0)->getAttribute('length'); 0369 $enclosure->type = $nodeList->item(0)->getAttribute('type'); 0370 } 0371 } 0372 0373 if (!$enclosure) { 0374 $enclosure = $this->getExtension('Atom')->getEnclosure(); 0375 } 0376 0377 $this->_data['enclosure'] = $enclosure; 0378 0379 return $this->_data['enclosure']; 0380 } 0381 0382 /** 0383 * Get the entry ID 0384 * 0385 * @return string 0386 */ 0387 public function getId() 0388 { 0389 if (array_key_exists('id', $this->_data)) { 0390 return $this->_data['id']; 0391 } 0392 0393 $id = null; 0394 0395 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0396 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090 0397 ) { 0398 $id = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/guid)'); 0399 } 0400 0401 if (!$id) { 0402 $id = $this->getExtension('DublinCore')->getId(); 0403 } 0404 0405 if (empty($id)) { 0406 $id = $this->getExtension('Atom')->getId(); 0407 } 0408 0409 if (!$id) { 0410 if ($this->getPermalink()) { 0411 $id = $this->getPermalink(); 0412 } elseif ($this->getTitle()) { 0413 $id = $this->getTitle(); 0414 } else { 0415 $id = null; 0416 } 0417 } 0418 0419 $this->_data['id'] = $id; 0420 0421 return $this->_data['id']; 0422 } 0423 0424 /** 0425 * Get a specific link 0426 * 0427 * @param int $index 0428 * @return string 0429 */ 0430 public function getLink($index = 0) 0431 { 0432 if (!array_key_exists('links', $this->_data)) { 0433 $this->getLinks(); 0434 } 0435 0436 if (isset($this->_data['links'][$index])) { 0437 return $this->_data['links'][$index]; 0438 } 0439 0440 return null; 0441 } 0442 0443 /** 0444 * Get all links 0445 * 0446 * @return array 0447 */ 0448 public function getLinks() 0449 { 0450 if (array_key_exists('links', $this->_data)) { 0451 return $this->_data['links']; 0452 } 0453 0454 $links = array(); 0455 0456 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 && 0457 $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) { 0458 $list = $this->_xpath->query($this->_xpathQueryRss.'//link'); 0459 } else { 0460 $list = $this->_xpath->query($this->_xpathQueryRdf.'//rss:link'); 0461 } 0462 0463 if (!$list->length) { 0464 $links = $this->getExtension('Atom')->getLinks(); 0465 } else { 0466 foreach ($list as $link) { 0467 $links[] = $link->nodeValue; 0468 } 0469 } 0470 0471 $this->_data['links'] = $links; 0472 0473 return $this->_data['links']; 0474 } 0475 0476 /** 0477 * Get all categories 0478 * 0479 * @return Zend_Feed_Reader_Collection_Category 0480 */ 0481 public function getCategories() 0482 { 0483 if (array_key_exists('categories', $this->_data)) { 0484 return $this->_data['categories']; 0485 } 0486 0487 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 && 0488 $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) { 0489 $list = $this->_xpath->query($this->_xpathQueryRss.'//category'); 0490 } else { 0491 $list = $this->_xpath->query($this->_xpathQueryRdf.'//rss:category'); 0492 } 0493 0494 if ($list->length) { 0495 $categoryCollection = new Zend_Feed_Reader_Collection_Category; 0496 foreach ($list as $category) { 0497 $categoryCollection[] = array( 0498 'term' => $category->nodeValue, 0499 'scheme' => $category->getAttribute('domain'), 0500 'label' => $category->nodeValue, 0501 ); 0502 } 0503 } else { 0504 $categoryCollection = $this->getExtension('DublinCore')->getCategories(); 0505 } 0506 0507 if (count($categoryCollection) == 0) { 0508 $categoryCollection = $this->getExtension('Atom')->getCategories(); 0509 } 0510 0511 $this->_data['categories'] = $categoryCollection; 0512 0513 return $this->_data['categories']; 0514 } 0515 0516 /** 0517 * Get a permalink to the entry 0518 * 0519 * @return string 0520 */ 0521 public function getPermalink() 0522 { 0523 return $this->getLink(0); 0524 } 0525 0526 /** 0527 * Get the entry title 0528 * 0529 * @return string 0530 */ 0531 public function getTitle() 0532 { 0533 if (array_key_exists('title', $this->_data)) { 0534 return $this->_data['title']; 0535 } 0536 0537 $title = null; 0538 0539 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0540 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090 0541 ) { 0542 $title = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/title)'); 0543 } else { 0544 $title = $this->_xpath->evaluate('string('.$this->_xpathQueryRdf.'/rss:title)'); 0545 } 0546 0547 if (!$title) { 0548 $title = $this->getExtension('DublinCore')->getTitle(); 0549 } 0550 0551 if (!$title) { 0552 $title = $this->getExtension('Atom')->getTitle(); 0553 } 0554 0555 if (!$title) { 0556 $title = null; 0557 } 0558 0559 $this->_data['title'] = $title; 0560 0561 return $this->_data['title']; 0562 } 0563 0564 /** 0565 * Get the number of comments/replies for current entry 0566 * 0567 * @return string|null 0568 */ 0569 public function getCommentCount() 0570 { 0571 if (array_key_exists('commentcount', $this->_data)) { 0572 return $this->_data['commentcount']; 0573 } 0574 0575 $commentcount = $this->getExtension('Slash')->getCommentCount(); 0576 0577 if (!$commentcount) { 0578 $commentcount = $this->getExtension('Thread')->getCommentCount(); 0579 } 0580 0581 if (!$commentcount) { 0582 $commentcount = $this->getExtension('Atom')->getCommentCount(); 0583 } 0584 0585 if (!$commentcount) { 0586 $commentcount = null; 0587 } 0588 0589 $this->_data['commentcount'] = $commentcount; 0590 0591 return $this->_data['commentcount']; 0592 } 0593 0594 /** 0595 * Returns a URI pointing to the HTML page where comments can be made on this entry 0596 * 0597 * @return string 0598 */ 0599 public function getCommentLink() 0600 { 0601 if (array_key_exists('commentlink', $this->_data)) { 0602 return $this->_data['commentlink']; 0603 } 0604 0605 $commentlink = null; 0606 0607 if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 0608 && $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090 0609 ) { 0610 $commentlink = $this->_xpath->evaluate('string('.$this->_xpathQueryRss.'/comments)'); 0611 } 0612 0613 if (!$commentlink) { 0614 $commentlink = $this->getExtension('Atom')->getCommentLink(); 0615 } 0616 0617 if (!$commentlink) { 0618 $commentlink = null; 0619 } 0620 0621 $this->_data['commentlink'] = $commentlink; 0622 0623 return $this->_data['commentlink']; 0624 } 0625 0626 /** 0627 * Returns a URI pointing to a feed of all comments for this entry 0628 * 0629 * @return string 0630 */ 0631 public function getCommentFeedLink() 0632 { 0633 if (array_key_exists('commentfeedlink', $this->_data)) { 0634 return $this->_data['commentfeedlink']; 0635 } 0636 0637 $commentfeedlink = $this->getExtension('WellFormedWeb')->getCommentFeedLink(); 0638 0639 if (!$commentfeedlink) { 0640 $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rss'); 0641 } 0642 0643 if (!$commentfeedlink) { 0644 $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink('rdf'); 0645 } 0646 0647 if (!$commentfeedlink) { 0648 $commentfeedlink = null; 0649 } 0650 0651 $this->_data['commentfeedlink'] = $commentfeedlink; 0652 0653 return $this->_data['commentfeedlink']; 0654 } 0655 0656 /** 0657 * Set the XPath query (incl. on all Extensions) 0658 * 0659 * @param DOMXPath $xpath 0660 */ 0661 public function setXpath(DOMXPath $xpath) 0662 { 0663 parent::setXpath($xpath); 0664 foreach ($this->_extensions as $extension) { 0665 $extension->setXpath($this->_xpath); 0666 } 0667 } 0668 }