diff options
Diffstat (limited to '3rdparty/ZendFeed/Reader/Entry')
-rw-r--r-- | 3rdparty/ZendFeed/Reader/Entry/AbstractEntry.php | 230 | ||||
-rw-r--r-- | 3rdparty/ZendFeed/Reader/Entry/Atom.php | 370 | ||||
-rw-r--r-- | 3rdparty/ZendFeed/Reader/Entry/EntryInterface.php | 129 | ||||
-rw-r--r-- | 3rdparty/ZendFeed/Reader/Entry/Rss.php | 599 |
4 files changed, 1328 insertions, 0 deletions
diff --git a/3rdparty/ZendFeed/Reader/Entry/AbstractEntry.php b/3rdparty/ZendFeed/Reader/Entry/AbstractEntry.php new file mode 100644 index 000000000..241a8cdba --- /dev/null +++ b/3rdparty/ZendFeed/Reader/Entry/AbstractEntry.php @@ -0,0 +1,230 @@ +<?php +/** + * Zend Framework (http://framework.zend.com/) + * + * @link http://github.com/zendframework/zf2 for the canonical source repository + * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Feed\Reader\Entry; + +use DOMDocument; +use DOMElement; +use DOMXPath; +use Zend\Feed\Reader; +use Zend\Feed\Reader\Exception; + +abstract class AbstractEntry +{ + /** + * Feed entry data + * + * @var array + */ + protected $data = array(); + + /** + * DOM document object + * + * @var DOMDocument + */ + protected $domDocument = null; + + /** + * Entry instance + * + * @var DOMElement + */ + protected $entry = null; + + /** + * Pointer to the current entry + * + * @var int + */ + protected $entryKey = 0; + + /** + * XPath object + * + * @var DOMXPath + */ + protected $xpath = null; + + /** + * Registered extensions + * + * @var array + */ + protected $extensions = array(); + + /** + * Constructor + * + * @param DOMElement $entry + * @param int $entryKey + * @param string $type + */ + public function __construct(DOMElement $entry, $entryKey, $type = null) + { + $this->entry = $entry; + $this->entryKey = $entryKey; + $this->domDocument = $entry->ownerDocument; + if ($type !== null) { + $this->data['type'] = $type; + } elseif ($this->domDocument !== null) { + $this->data['type'] = Reader\Reader::detectType($this->domDocument); + } else { + $this->data['type'] = Reader\Reader::TYPE_ANY; + } + $this->loadExtensions(); + } + + /** + * Get the DOM + * + * @return DOMDocument + */ + public function getDomDocument() + { + return $this->domDocument; + } + + /** + * Get the entry element + * + * @return DOMElement + */ + public function getElement() + { + return $this->entry; + } + + /** + * Get the Entry's encoding + * + * @return string + */ + public function getEncoding() + { + $assumed = $this->getDomDocument()->encoding; + if (empty($assumed)) { + $assumed = 'UTF-8'; + } + return $assumed; + } + + /** + * Get entry as xml + * + * @return string + */ + public function saveXml() + { + $dom = new DOMDocument('1.0', $this->getEncoding()); + $entry = $dom->importNode($this->getElement(), true); + $dom->appendChild($entry); + return $dom->saveXml(); + } + + /** + * Get the entry type + * + * @return string + */ + public function getType() + { + return $this->data['type']; + } + + /** + * Get the XPath query object + * + * @return DOMXPath + */ + public function getXpath() + { + if (!$this->xpath) { + $this->setXpath(new DOMXPath($this->getDomDocument())); + } + return $this->xpath; + } + + /** + * Set the XPath query + * + * @param DOMXPath $xpath + * @return AbstractEntry + */ + public function setXpath(DOMXPath $xpath) + { + $this->xpath = $xpath; + return $this; + } + + /** + * Get registered extensions + * + * @return array + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Return an Extension object with the matching name (postfixed with _Entry) + * + * @param string $name + * @return Reader\Extension\AbstractEntry + */ + public function getExtension($name) + { + if (array_key_exists($name . '\\Entry', $this->extensions)) { + return $this->extensions[$name . '\\Entry']; + } + return null; + } + + /** + * Method overloading: call given method on first extension implementing it + * + * @param string $method + * @param array $args + * @return mixed + * @throws Exception\RuntimeException if no extensions implements the method + */ + public function __call($method, $args) + { + foreach ($this->extensions as $extension) { + if (method_exists($extension, $method)) { + return call_user_func_array(array($extension, $method), $args); + } + } + throw new Exception\RuntimeException('Method: ' . $method + . ' does not exist and could not be located on a registered Extension'); + } + + /** + * Load extensions from Zend\Feed\Reader\Reader + * + * @return void + */ + protected function loadExtensions() + { + $all = Reader\Reader::getExtensions(); + $manager = Reader\Reader::getExtensionManager(); + $feed = $all['entry']; + foreach ($feed as $extension) { + if (in_array($extension, $all['core'])) { + continue; + } + $plugin = $manager->get($extension); + $plugin->setEntryElement($this->getElement()); + $plugin->setEntryKey($this->entryKey); + $plugin->setType($this->data['type']); + $this->extensions[$extension] = $plugin; + } + } +} diff --git a/3rdparty/ZendFeed/Reader/Entry/Atom.php b/3rdparty/ZendFeed/Reader/Entry/Atom.php new file mode 100644 index 000000000..ed61a21e5 --- /dev/null +++ b/3rdparty/ZendFeed/Reader/Entry/Atom.php @@ -0,0 +1,370 @@ +<?php +/** + * Zend Framework (http://framework.zend.com/) + * + * @link http://github.com/zendframework/zf2 for the canonical source repository + * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Feed\Reader\Entry; + +use DOMElement; +use DOMXPath; +use Zend\Feed\Reader; + +class Atom extends AbstractEntry implements EntryInterface +{ + /** + * XPath query + * + * @var string + */ + protected $xpathQuery = ''; + + /** + * Constructor + * + * @param DOMElement $entry + * @param int $entryKey + * @param string $type + */ + public function __construct(DOMElement $entry, $entryKey, $type = null) + { + parent::__construct($entry, $entryKey, $type); + + // Everyone by now should know XPath indices start from 1 not 0 + $this->xpathQuery = '//atom:entry[' . ($this->entryKey + 1) . ']'; + + $manager = Reader\Reader::getExtensionManager(); + $extensions = array('Atom\Entry', 'Thread\Entry', 'DublinCore\Entry'); + + foreach ($extensions as $name) { + $extension = $manager->get($name); + $extension->setEntryElement($entry); + $extension->setEntryKey($entryKey); + $extension->setType($type); + $this->extensions[$name] = $extension; + } + } + + /** + * Get the specified author + * + * @param int $index + * @return string|null + */ + public function getAuthor($index = 0) + { + $authors = $this->getAuthors(); + + if (isset($authors[$index])) { + return $authors[$index]; + } + + return null; + } + + /** + * Get an array with feed authors + * + * @return array + */ + public function getAuthors() + { + if (array_key_exists('authors', $this->data)) { + return $this->data['authors']; + } + + $people = $this->getExtension('Atom')->getAuthors(); + + $this->data['authors'] = $people; + + return $this->data['authors']; + } + + /** + * Get the entry content + * + * @return string + */ + public function getContent() + { + if (array_key_exists('content', $this->data)) { + return $this->data['content']; + } + + $content = $this->getExtension('Atom')->getContent(); + + $this->data['content'] = $content; + + return $this->data['content']; + } + + /** + * Get the entry creation date + * + * @return string + */ + public function getDateCreated() + { + if (array_key_exists('datecreated', $this->data)) { + return $this->data['datecreated']; + } + + $dateCreated = $this->getExtension('Atom')->getDateCreated(); + + $this->data['datecreated'] = $dateCreated; + + return $this->data['datecreated']; + } + + /** + * Get the entry modification date + * + * @return string + */ + public function getDateModified() + { + if (array_key_exists('datemodified', $this->data)) { + return $this->data['datemodified']; + } + + $dateModified = $this->getExtension('Atom')->getDateModified(); + + $this->data['datemodified'] = $dateModified; + + return $this->data['datemodified']; + } + + /** + * Get the entry description + * + * @return string + */ + public function getDescription() + { + if (array_key_exists('description', $this->data)) { + return $this->data['description']; + } + + $description = $this->getExtension('Atom')->getDescription(); + + $this->data['description'] = $description; + + return $this->data['description']; + } + + /** + * Get the entry enclosure + * + * @return string + */ + public function getEnclosure() + { + if (array_key_exists('enclosure', $this->data)) { + return $this->data['enclosure']; + } + + $enclosure = $this->getExtension('Atom')->getEnclosure(); + + $this->data['enclosure'] = $enclosure; + + return $this->data['enclosure']; + } + + /** + * Get the entry ID + * + * @return string + */ + public function getId() + { + if (array_key_exists('id', $this->data)) { + return $this->data['id']; + } + + $id = $this->getExtension('Atom')->getId(); + + $this->data['id'] = $id; + + return $this->data['id']; + } + + /** + * Get a specific link + * + * @param int $index + * @return string + */ + public function getLink($index = 0) + { + if (!array_key_exists('links', $this->data)) { + $this->getLinks(); + } + + if (isset($this->data['links'][$index])) { + return $this->data['links'][$index]; + } + + return null; + } + + /** + * Get all links + * + * @return array + */ + public function getLinks() + { + if (array_key_exists('links', $this->data)) { + return $this->data['links']; + } + + $links = $this->getExtension('Atom')->getLinks(); + + $this->data['links'] = $links; + + return $this->data['links']; + } + + /** + * Get a permalink to the entry + * + * @return string + */ + public function getPermalink() + { + return $this->getLink(0); + } + + /** + * Get the entry title + * + * @return string + */ + public function getTitle() + { + if (array_key_exists('title', $this->data)) { + return $this->data['title']; + } + + $title = $this->getExtension('Atom')->getTitle(); + + $this->data['title'] = $title; + + return $this->data['title']; + } + + /** + * Get the number of comments/replies for current entry + * + * @return int + */ + public function getCommentCount() + { + if (array_key_exists('commentcount', $this->data)) { + return $this->data['commentcount']; + } + + $commentcount = $this->getExtension('Thread')->getCommentCount(); + + if (!$commentcount) { + $commentcount = $this->getExtension('Atom')->getCommentCount(); + } + + $this->data['commentcount'] = $commentcount; + + return $this->data['commentcount']; + } + + /** + * Returns a URI pointing to the HTML page where comments can be made on this entry + * + * @return string + */ + public function getCommentLink() + { + if (array_key_exists('commentlink', $this->data)) { + return $this->data['commentlink']; + } + + $commentlink = $this->getExtension('Atom')->getCommentLink(); + + $this->data['commentlink'] = $commentlink; + + return $this->data['commentlink']; + } + + /** + * Returns a URI pointing to a feed of all comments for this entry + * + * @return string + */ + public function getCommentFeedLink() + { + if (array_key_exists('commentfeedlink', $this->data)) { + return $this->data['commentfeedlink']; + } + + $commentfeedlink = $this->getExtension('Atom')->getCommentFeedLink(); + + $this->data['commentfeedlink'] = $commentfeedlink; + + return $this->data['commentfeedlink']; + } + + /** + * Get category data as a Reader\Reader_Collection_Category object + * + * @return Reader\Collection\Category + */ + public function getCategories() + { + if (array_key_exists('categories', $this->data)) { + return $this->data['categories']; + } + + $categoryCollection = $this->getExtension('Atom')->getCategories(); + + if (count($categoryCollection) == 0) { + $categoryCollection = $this->getExtension('DublinCore')->getCategories(); + } + + $this->data['categories'] = $categoryCollection; + + return $this->data['categories']; + } + + /** + * Get source feed metadata from the entry + * + * @return Reader\Feed\Atom\Source|null + */ + public function getSource() + { + if (array_key_exists('source', $this->data)) { + return $this->data['source']; + } + + $source = $this->getExtension('Atom')->getSource(); + + $this->data['source'] = $source; + + return $this->data['source']; + } + + /** + * Set the XPath query (incl. on all Extensions) + * + * @param DOMXPath $xpath + * @return void + */ + public function setXpath(DOMXPath $xpath) + { + parent::setXpath($xpath); + foreach ($this->extensions as $extension) { + $extension->setXpath($this->xpath); + } + } +} diff --git a/3rdparty/ZendFeed/Reader/Entry/EntryInterface.php b/3rdparty/ZendFeed/Reader/Entry/EntryInterface.php new file mode 100644 index 000000000..86fea3ec5 --- /dev/null +++ b/3rdparty/ZendFeed/Reader/Entry/EntryInterface.php @@ -0,0 +1,129 @@ +<?php +/** + * Zend Framework (http://framework.zend.com/) + * + * @link http://github.com/zendframework/zf2 for the canonical source repository + * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Feed\Reader\Entry; + +use Zend\Feed\Reader\Collection\Category; + +interface EntryInterface +{ + /** + * Get the specified author + * + * @param int $index + * @return string|null + */ + public function getAuthor($index = 0); + + /** + * Get an array with feed authors + * + * @return array + */ + public function getAuthors(); + + /** + * Get the entry content + * + * @return string + */ + public function getContent(); + + /** + * Get the entry creation date + * + * @return string + */ + public function getDateCreated(); + + /** + * Get the entry modification date + * + * @return string + */ + public function getDateModified(); + + /** + * Get the entry description + * + * @return string + */ + public function getDescription(); + + /** + * Get the entry enclosure + * + * @return \stdClass + */ + public function getEnclosure(); + + /** + * Get the entry ID + * + * @return string + */ + public function getId(); + + /** + * Get a specific link + * + * @param int $index + * @return string + */ + public function getLink($index = 0); + + /** + * Get all links + * + * @return array + */ + public function getLinks(); + + /** + * Get a permalink to the entry + * + * @return string + */ + public function getPermalink(); + + /** + * Get the entry title + * + * @return string + */ + public function getTitle(); + + /** + * Get the number of comments/replies for current entry + * + * @return int + */ + public function getCommentCount(); + + /** + * Returns a URI pointing to the HTML page where comments can be made on this entry + * + * @return string + */ + public function getCommentLink(); + + /** + * Returns a URI pointing to a feed of all comments for this entry + * + * @return string + */ + public function getCommentFeedLink(); + + /** + * Get all categories + * + * @return Category + */ + public function getCategories(); +} diff --git a/3rdparty/ZendFeed/Reader/Entry/Rss.php b/3rdparty/ZendFeed/Reader/Entry/Rss.php new file mode 100644 index 000000000..27337b1b0 --- /dev/null +++ b/3rdparty/ZendFeed/Reader/Entry/Rss.php @@ -0,0 +1,599 @@ +<?php +/** + * Zend Framework (http://framework.zend.com/) + * + * @link http://github.com/zendframework/zf2 for the canonical source repository + * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Feed\Reader\Entry; + +use DateTime; +use DOMElement; +use DOMXPath; +use Zend\Feed\Reader; +use Zend\Feed\Reader\Exception; + +class Rss extends AbstractEntry implements EntryInterface +{ + + /** + * XPath query for RDF + * + * @var string + */ + protected $xpathQueryRdf = ''; + + /** + * XPath query for RSS + * + * @var string + */ + protected $xpathQueryRss = ''; + + /** + * Constructor + * + * @param DOMElement $entry + * @param string $entryKey + * @param string $type + */ + public function __construct(DOMElement $entry, $entryKey, $type = null) + { + parent::__construct($entry, $entryKey, $type); + $this->xpathQueryRss = '//item[' . ($this->entryKey+1) . ']'; + $this->xpathQueryRdf = '//rss:item[' . ($this->entryKey+1) . ']'; + + $manager = Reader\Reader::getExtensionManager(); + $extensions = array( + 'DublinCore\Entry', + 'Content\Entry', + 'Atom\Entry', + 'WellFormedWeb\Entry', + 'Slash\Entry', + 'Thread\Entry', + ); + foreach ($extensions as $name) { + $extension = $manager->get($name); + $extension->setEntryElement($entry); + $extension->setEntryKey($entryKey); + $extension->setType($type); + $this->extensions[$name] = $extension; + } + } + + /** + * Get an author entry + * + * @param int $index + * @return string + */ + public function getAuthor($index = 0) + { + $authors = $this->getAuthors(); + + if (isset($authors[$index])) { + return $authors[$index]; + } + + return null; + } + + /** + * Get an array with feed authors + * + * @return array + */ + public function getAuthors() + { + if (array_key_exists('authors', $this->data)) { + return $this->data['authors']; + } + + $authors = array(); + $authorsDc = $this->getExtension('DublinCore')->getAuthors(); + if (!empty($authorsDc)) { + foreach ($authorsDc as $author) { + $authors[] = array( + 'name' => $author['name'] + ); + } + } + + if ($this->getType() !== Reader\Reader::TYPE_RSS_10 + && $this->getType() !== Reader\Reader::TYPE_RSS_090) { + $list = $this->xpath->query($this->xpathQueryRss . '//author'); + } else { + $list = $this->xpath->query($this->xpathQueryRdf . '//rss:author'); + } + if ($list->length) { + foreach ($list as $author) { + $string = trim($author->nodeValue); + $email = null; + $name = null; + $data = array(); + // Pretty rough parsing - but it's a catchall + if (preg_match("/^.*@[^ ]*/", $string, $matches)) { + $data['email'] = trim($matches[0]); + if (preg_match("/\((.*)\)$/", $string, $matches)) { + $data['name'] = $matches[1]; + } + $authors[] = $data; + } + } + } + + if (count($authors) == 0) { + $authors = $this->getExtension('Atom')->getAuthors(); + } else { + $authors = new Reader\Collection\Author( + Reader\Reader::arrayUnique($authors) + ); + } + + if (count($authors) == 0) { + $authors = null; + } + + $this->data['authors'] = $authors; + + return $this->data['authors']; + } + + /** + * Get the entry content + * + * @return string + */ + public function getContent() + { + if (array_key_exists('content', $this->data)) { + return $this->data['content']; + } + + $content = $this->getExtension('Content')->getContent(); + + if (!$content) { + $content = $this->getDescription(); + } + + if (empty($content)) { + $content = $this->getExtension('Atom')->getContent(); + } + + $this->data['content'] = $content; + + return $this->data['content']; + } + + /** + * Get the entry's date of creation + * + * @return string + */ + public function getDateCreated() + { + return $this->getDateModified(); + } + + /** + * Get the entry's date of modification + * + * @throws Exception\RuntimeException + * @return string + */ + public function getDateModified() + { + if (array_key_exists('datemodified', $this->data)) { + return $this->data['datemodified']; + } + + $dateModified = null; + $date = null; + + if ($this->getType() !== Reader\Reader::TYPE_RSS_10 + && $this->getType() !== Reader\Reader::TYPE_RSS_090 + ) { + $dateModified = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/pubDate)'); + if ($dateModified) { + $dateModifiedParsed = strtotime($dateModified); + if ($dateModifiedParsed) { + $date = new DateTime('@' . $dateModifiedParsed); + } else { + $dateStandards = array(DateTime::RSS, DateTime::RFC822, + DateTime::RFC2822, null); + foreach ($dateStandards as $standard) { + try { + $date = date_create_from_format($standard, $dateModified); + break; + } catch (\Exception $e) { + if ($standard == null) { + throw new Exception\RuntimeException( + 'Could not load date due to unrecognised' + .' format (should follow RFC 822 or 2822):' + . $e->getMessage(), + 0, $e + ); + } + } + } + } + } + } + + if (!$date) { + $date = $this->getExtension('DublinCore')->getDate(); + } + + if (!$date) { + $date = $this->getExtension('Atom')->getDateModified(); + } + + if (!$date) { + $date = null; + } + + $this->data['datemodified'] = $date; + + return $this->data['datemodified']; + } + + /** + * Get the entry description + * + * @return string + */ + public function getDescription() + { + if (array_key_exists('description', $this->data)) { + return $this->data['description']; + } + + $description = null; + + if ($this->getType() !== Reader\Reader::TYPE_RSS_10 + && $this->getType() !== Reader\Reader::TYPE_RSS_090 + ) { + $description = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/description)'); + } else { + $description = $this->xpath->evaluate('string(' . $this->xpathQueryRdf . '/rss:description)'); + } + + if (!$description) { + $description = $this->getExtension('DublinCore')->getDescription(); + } + + if (empty($description)) { + $description = $this->getExtension('Atom')->getDescription(); + } + + if (!$description) { + $description = null; + } + + $this->data['description'] = $description; + + return $this->data['description']; + } + + /** + * Get the entry enclosure + * @return string + */ + public function getEnclosure() + { + if (array_key_exists('enclosure', $this->data)) { + return $this->data['enclosure']; + } + + $enclosure = null; + + if ($this->getType() == Reader\Reader::TYPE_RSS_20) { + $nodeList = $this->xpath->query($this->xpathQueryRss . '/enclosure'); + + if ($nodeList->length > 0) { + $enclosure = new \stdClass(); + $enclosure->url = $nodeList->item(0)->getAttribute('url'); + $enclosure->length = $nodeList->item(0)->getAttribute('length'); + $enclosure->type = $nodeList->item(0)->getAttribute('type'); + } + } + + if (!$enclosure) { + $enclosure = $this->getExtension('Atom')->getEnclosure(); + } + + $this->data['enclosure'] = $enclosure; + + return $this->data['enclosure']; + } + + /** + * Get the entry ID + * + * @return string + */ + public function getId() + { + if (array_key_exists('id', $this->data)) { + return $this->data['id']; + } + + $id = null; + + if ($this->getType() !== Reader\Reader::TYPE_RSS_10 + && $this->getType() !== Reader\Reader::TYPE_RSS_090 + ) { + $id = $this->xpath->evaluate('string(' . $this->xpathQueryRss . '/guid)'); + } + + if (!$id) { + $id = $this->getExtension('DublinCore')->getId(); + } + + if (empty($id)) { + $id = $this->getExtension('Atom')->getId(); + } + + if (!$id) { + if ($this->getPermalink()) { + $id = $this->getPermalink(); + } elseif ($this->getTitle()) { + $id = $this->getTitle(); + } else { + $id = null; + } + } + + $this->data['id'] = $id; + + return $this->data['id']; + } + + /** + * Get a specific link + * + * @param int $index + * @return string + */ + public function getLink($index = 0) + { + if (!array_key_exists('links |