summaryrefslogtreecommitdiffstats
path: root/3rdparty/ZendFeed/Reader/Reader.php
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/ZendFeed/Reader/Reader.php')
-rw-r--r--3rdparty/ZendFeed/Reader/Reader.php678
1 files changed, 0 insertions, 678 deletions
diff --git a/3rdparty/ZendFeed/Reader/Reader.php b/3rdparty/ZendFeed/Reader/Reader.php
deleted file mode 100644
index bcd387ad2..000000000
--- a/3rdparty/ZendFeed/Reader/Reader.php
+++ /dev/null
@@ -1,678 +0,0 @@
-<?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;
-
-use DOMDocument;
-use DOMXPath;
-use Zend\Cache\Storage\StorageInterface as CacheStorage;
-use Zend\Http as ZendHttp;
-use Zend\Stdlib\ErrorHandler;
-
-/**
-*/
-class Reader
-{
- /**
- * Namespace constants
- */
- const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#';
- const NAMESPACE_ATOM_10 = 'http://www.w3.org/2005/Atom';
- const NAMESPACE_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
- const NAMESPACE_RSS_090 = 'http://my.netscape.com/rdf/simple/0.9/';
- const NAMESPACE_RSS_10 = 'http://purl.org/rss/1.0/';
-
- /**
- * Feed type constants
- */
- const TYPE_ANY = 'any';
- const TYPE_ATOM_03 = 'atom-03';
- const TYPE_ATOM_10 = 'atom-10';
- const TYPE_ATOM_10_ENTRY = 'atom-10-entry';
- const TYPE_ATOM_ANY = 'atom';
- const TYPE_RSS_090 = 'rss-090';
- const TYPE_RSS_091 = 'rss-091';
- const TYPE_RSS_091_NETSCAPE = 'rss-091n';
- const TYPE_RSS_091_USERLAND = 'rss-091u';
- const TYPE_RSS_092 = 'rss-092';
- const TYPE_RSS_093 = 'rss-093';
- const TYPE_RSS_094 = 'rss-094';
- const TYPE_RSS_10 = 'rss-10';
- const TYPE_RSS_20 = 'rss-20';
- const TYPE_RSS_ANY = 'rss';
-
- /**
- * Cache instance
- *
- * @var CacheStorage
- */
- protected static $cache = null;
-
- /**
- * HTTP client object to use for retrieving feeds
- *
- * @var ZendHttp\Client
- */
- protected static $httpClient = null;
-
- /**
- * Override HTTP PUT and DELETE request methods?
- *
- * @var bool
- */
- protected static $httpMethodOverride = false;
-
- protected static $httpConditionalGet = false;
-
- protected static $extensionManager = null;
-
- protected static $extensions = array(
- 'feed' => array(
- 'DublinCore\Feed',
- 'Atom\Feed'
- ),
- 'entry' => array(
- 'Content\Entry',
- 'DublinCore\Entry',
- 'Atom\Entry'
- ),
- 'core' => array(
- 'DublinCore\Feed',
- 'Atom\Feed',
- 'Content\Entry',
- 'DublinCore\Entry',
- 'Atom\Entry'
- )
- );
-
- /**
- * Get the Feed cache
- *
- * @return CacheStorage
- */
- public static function getCache()
- {
- return static::$cache;
- }
-
- /**
- * Set the feed cache
- *
- * @param CacheStorage $cache
- * @return void
- */
- public static function setCache(CacheStorage $cache)
- {
- static::$cache = $cache;
- }
-
- /**
- * Set the HTTP client instance
- *
- * Sets the HTTP client object to use for retrieving the feeds.
- *
- * @param ZendHttp\Client $httpClient
- * @return void
- */
- public static function setHttpClient(ZendHttp\Client $httpClient)
- {
- static::$httpClient = $httpClient;
- }
-
-
- /**
- * Gets the HTTP client object. If none is set, a new ZendHttp\Client will be used.
- *
- * @return ZendHttp\Client
- */
- public static function getHttpClient()
- {
- if (!static::$httpClient instanceof ZendHttp\Client) {
- static::$httpClient = new ZendHttp\Client();
- }
-
- return static::$httpClient;
- }
-
- /**
- * Toggle using POST instead of PUT and DELETE HTTP methods
- *
- * Some feed implementations do not accept PUT and DELETE HTTP
- * methods, or they can't be used because of proxies or other
- * measures. This allows turning on using POST where PUT and
- * DELETE would normally be used; in addition, an
- * X-Method-Override header will be sent with a value of PUT or
- * DELETE as appropriate.
- *
- * @param bool $override Whether to override PUT and DELETE.
- * @return void
- */
- public static function setHttpMethodOverride($override = true)
- {
- static::$httpMethodOverride = $override;
- }
-
- /**
- * Get the HTTP override state
- *
- * @return bool
- */
- public static function getHttpMethodOverride()
- {
- return static::$httpMethodOverride;
- }
-
- /**
- * Set the flag indicating whether or not to use HTTP conditional GET
- *
- * @param bool $bool
- * @return void
- */
- public static function useHttpConditionalGet($bool = true)
- {
- static::$httpConditionalGet = $bool;
- }
-
- /**
- * Import a feed by providing a URI
- *
- * @param string $uri The URI to the feed
- * @param string $etag OPTIONAL Last received ETag for this resource
- * @param string $lastModified OPTIONAL Last-Modified value for this resource
- * @return Feed\FeedInterface
- * @throws Exception\RuntimeException
- */
- public static function import($uri, $etag = null, $lastModified = null)
- {
- $cache = self::getCache();
- $feed = null;
- $client = self::getHttpClient();
- $client->resetParameters();
- $headers = new ZendHttp\Headers();
- $client->setHeaders($headers);
- $client->setUri($uri);
- $cacheId = 'Zend_Feed_Reader_' . md5($uri);
-
- if (static::$httpConditionalGet && $cache) {
- $data = $cache->getItem($cacheId);
- if ($data) {
- if ($etag === null) {
- $etag = $cache->getItem($cacheId . '_etag');
- }
- if ($lastModified === null) {
- $lastModified = $cache->getItem($cacheId . '_lastmodified');
- }
- if ($etag) {
- $headers->addHeaderLine('If-None-Match', $etag);
- }
- if ($lastModified) {
- $headers->addHeaderLine('If-Modified-Since', $lastModified);
- }
- }
- $response = $client->send();
- if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 304) {
- throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
- }
- if ($response->getStatusCode() == 304) {
- $responseXml = $data;
- } else {
- $responseXml = $response->getBody();
- $cache->setItem($cacheId, $responseXml);
- if ($response->getHeaders()->get('ETag')) {
- $cache->setItem($cacheId . '_etag', $response->getHeaders()->get('ETag')->getFieldValue());
- }
- if ($response->getHeaders()->get('Last-Modified')) {
- $cache->setItem($cacheId . '_lastmodified', $response->getHeaders()->get('Last-Modified')->getFieldValue());
- }
- }
- return static::importString($responseXml);
- } elseif ($cache) {
- $data = $cache->getItem($cacheId);
- if ($data) {
- return static::importString($data);
- }
- $response = $client->send();
- if ((int) $response->getStatusCode() !== 200) {
- throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
- }
- $responseXml = $response->getBody();
- $cache->setItem($cacheId, $responseXml);
- return static::importString($responseXml);
- } else {
- $response = $client->send();
- if ((int) $response->getStatusCode() !== 200) {
- throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
- }
- $reader = static::importString($response->getBody());
- $reader->setOriginalSourceUri($uri);
- return $reader;
- }
- }
-
- /**
- * Import a feed from a remote URI
- *
- * Performs similarly to import(), except it uses the HTTP client passed to
- * the method, and does not take into account cached data.
- *
- * Primary purpose is to make it possible to use the Reader with alternate
- * HTTP client implementations.
- *
- * @param string $uri
- * @param Http\ClientInterface $client
- * @return self
- * @throws Exception\RuntimeException if response is not an Http\ResponseInterface
- */
- public static function importRemoteFeed($uri, Http\ClientInterface $client)
- {
- $response = $client->get($uri);
- if (!$response instanceof Http\ResponseInterface) {
- throw new Exception\RuntimeException(sprintf(
- 'Did not receive a %s\Http\ResponseInterface from the provided HTTP client; received "%s"',
- __NAMESPACE__,
- (is_object($response) ? get_class($response) : gettype($response))
- ));
- }
-
- if ((int) $response->getStatusCode() !== 200) {
- throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
- }
- $reader = static::importString($response->getBody());
- $reader->setOriginalSourceUri($uri);
- return $reader;
- }
-
- /**
- * Import a feed from a string
- *
- * @param string $string
- * @return Feed\FeedInterface
- * @throws Exception\InvalidArgumentException
- * @throws Exception\RuntimeException
- */
- public static function importString($string)
- {
- $trimmed = trim($string);
- if (!is_string($string) || empty($trimmed)) {
- throw new Exception\InvalidArgumentException('Only non empty strings are allowed as input');
- }
-
- $libxmlErrflag = libxml_use_internal_errors(true);
- $oldValue = libxml_disable_entity_loader(true);
- $dom = new DOMDocument;
- $status = $dom->loadXML(trim($string));
- foreach ($dom->childNodes as $child) {
- if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
- throw new Exception\InvalidArgumentException(
- 'Invalid XML: Detected use of illegal DOCTYPE'
- );
- }
- }
- libxml_disable_entity_loader($oldValue);
- libxml_use_internal_errors($libxmlErrflag);
-
- if (!$status) {
- // Build error message
- $error = libxml_get_last_error();
- if ($error && $error->message) {
- $error->message = trim($error->message);
- $errormsg = "DOMDocument cannot parse XML: {$error->message}";
- } else {
- $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity";
- }
- throw new Exception\RuntimeException($errormsg);
- }
-
- $type = static::detectType($dom);
-
- static::registerCoreExtensions();
-
- if (substr($type, 0, 3) == 'rss') {
- $reader = new Feed\Rss($dom, $type);
- } elseif (substr($type, 8, 5) == 'entry') {
- $reader = new Entry\Atom($dom->documentElement, 0, self::TYPE_ATOM_10);
- } elseif (substr($type, 0, 4) == 'atom') {
- $reader = new Feed\Atom($dom, $type);
- } else {
- throw new Exception\RuntimeException('The URI used does not point to a '
- . 'valid Atom, RSS or RDF feed that Zend\Feed\Reader can parse.');
- }
- return $reader;
- }
-
- /**
- * Imports a feed from a file located at $filename.
- *
- * @param string $filename
- * @throws Exception\RuntimeException
- * @return Feed\FeedInterface
- */
- public static function importFile($filename)
- {
- ErrorHandler::start();
- $feed = file_get_contents($filename);
- $err = ErrorHandler::stop();
- if ($feed === false) {
- throw new Exception\RuntimeException("File '{$filename}' could not be loaded", 0, $err);
- }
- return static::importString($feed);
- }
-
- /**
- * Find feed links
- *
- * @param $uri
- * @return FeedSet
- * @throws Exception\RuntimeException
- */
- public static function findFeedLinks($uri)
- {
- $client = static::getHttpClient();
- $client->setUri($uri);
- $response = $client->send();
- if ($response->getStatusCode() !== 200) {
- throw new Exception\RuntimeException("Failed to access $uri, got response code " . $response->getStatusCode());
- }
- $responseHtml = $response->getBody();
- $libxmlErrflag = libxml_use_internal_errors(true);
- $oldValue = libxml_disable_entity_loader(true);
- $dom = new DOMDocument;
- $status = $dom->loadHTML(trim($responseHtml));
- libxml_disable_entity_loader($oldValue);
- libxml_use_internal_errors($libxmlErrflag);
- if (!$status) {
- // Build error message
- $error = libxml_get_last_error();
- if ($error && $error->message) {
- $error->message = trim($error->message);
- $errormsg = "DOMDocument cannot parse HTML: {$error->message}";
- } else {
- $errormsg = "DOMDocument cannot parse HTML: Please check the XML document's validity";
- }
- throw new Exception\RuntimeException($errormsg);
- }
- $feedSet = new FeedSet;
- $links = $dom->getElementsByTagName('link');
- $feedSet->addLinks($links, $uri);
- return $feedSet;
- }
-
- /**
- * Detect the feed type of the provided feed
- *
- * @param Feed\AbstractFeed|DOMDocument|string $feed
- * @param bool $specOnly
- * @return string
- * @throws Exception\InvalidArgumentException
- * @throws Exception\RuntimeException
- */
- public static function detectType($feed, $specOnly = false)
- {
- if ($feed instanceof Feed\AbstractFeed) {
- $dom = $feed->getDomDocument();
- } elseif ($feed instanceof DOMDocument) {
- $dom = $feed;
- } elseif (is_string($feed) && !empty($feed)) {
- ErrorHandler::start(E_NOTICE|E_WARNING);
- ini_set('track_errors', 1);
- $oldValue = libxml_disable_entity_loader(true);
- $dom = new DOMDocument;
- $status = $dom->loadXML($feed);
- foreach ($dom->childNodes as $child) {
- if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
- throw new Exception\InvalidArgumentException(
- 'Invalid XML: Detected use of illegal DOCTYPE'
- );
- }
- }
- libxml_disable_entity_loader($oldValue);
- ini_restore('track_errors');
- ErrorHandler::stop();
- if (!$status) {
- if (!isset($phpErrormsg)) {
- if (function_exists('xdebug_is_enabled')) {
- $phpErrormsg = '(error message not available, when XDebug is running)';
- } else {
- $phpErrormsg = '(error message not available)';
- }
- }
- throw new Exception\RuntimeException("DOMDocument cannot parse XML: $phpErrormsg");
- }
- } else {
- throw new Exception\InvalidArgumentException('Invalid object/scalar provided: must'
- . ' be of type Zend\Feed\Reader\Feed, DomDocument or string');
- }
- $xpath = new DOMXPath($dom);
-
- if ($xpath->query('/rss')->length) {
- $type = self::TYPE_RSS_ANY;
- $version = $xpath->evaluate('string(/rss/@version)');
-
- if (strlen($version) > 0) {
- switch ($version) {
- case '2.0':
- $type = self::TYPE_RSS_20;
- break;
-
- case '0.94':
- $type = self::TYPE_RSS_094;
- break;
-
- case '0.93':
- $type = self::TYPE_RSS_093;
- break;
-
- case '0.92':
- $type = self::TYPE_RSS_092;
- break;
-
- case '0.91':
- $type = self::TYPE_RSS_091;
- break;
- }
- }
-
- return $type;
- }
-
- $xpath->registerNamespace('rdf', self::NAMESPACE_RDF);
-
- if ($xpath->query('/rdf:RDF')->length) {
- $xpath->registerNamespace('rss', self::NAMESPACE_RSS_10);
-
- if ($xpath->query('/rdf:RDF/rss:channel')->length
- || $xpath->query('/rdf:RDF/rss:image')->length
- || $xpath->query('/rdf:RDF/rss:item')->length
- || $xpath->query('/rdf:RDF/rss:textinput')->length
- ) {
- return self::TYPE_RSS_10;
- }
-
- $xpath->registerNamespace('rss', self::NAMESPACE_RSS_090);
-
- if ($xpath->query('/rdf:RDF/rss:channel')->length
- || $xpath->query('/rdf:RDF/rss:image')->length
- || $xpath->query('/rdf:RDF/rss:item')->length
- || $xpath->query('/rdf:RDF/rss:textinput')->length
- ) {
- return self::TYPE_RSS_090;
- }
- }
-
- $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10);
-
- if ($xpath->query('//atom:feed')->length) {
- return self::TYPE_ATOM_10;
- }
-
- if ($xpath->query('//atom:entry')->length) {
- if ($specOnly == true) {
- return self::TYPE_ATOM_10;
- } else {
- return self::TYPE_ATOM_10_ENTRY;
- }
- }
-
- $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_03);
-
- if ($xpath->query('//atom:feed')->length) {
- return self::TYPE_ATOM_03;
- }
-
- return self::TYPE_ANY;
- }
-
- /**
- * Set plugin manager for use with Extensions
- *
- * @param ExtensionManagerInterface $extensionManager
- */
- public static function setExtensionManager(ExtensionManagerInterface $extensionManager)
- {
- static::$extensionManager = $extensionManager;
- }
-
- /**
- * Get plugin manager for use with Extensions
- *
- * @return ExtensionManagerInterface
- */
- public static function getExtensionManager()
- {
- if (!isset(static::$extensionManager)) {
- static::setExtensionManager(new ExtensionManager());
- }
- return static::$extensionManager;
- }
-
- /**
- * Register an Extension by name
- *
- * @param string $name
- * @return void
- * @throws Exception\RuntimeException if unable to resolve Extension class
- */
- public static function registerExtension($name)
- {
- $feedName = $name . '\Feed';
- $entryName = $name . '\Entry';
- $manager = static::getExtensionManager();
- if (static::isRegistered($name)) {
- if ($manager->has($feedName) || $manager->has($entryName)) {
- return;
- }
- }
-
- if (!$manager->has($feedName) && !$manager->has($entryName)) {
- throw new Exception\RuntimeException('Could not load extension: ' . $name
- . ' using Plugin Loader. Check prefix paths are configured and extension exists.');
- }
- if ($manager->has($feedName)) {
- static::$extensions['feed'][] = $feedName;
- }
- if ($manager->has($entryName)) {
- static::$extensions['entry'][] = $entryName;
- }
- }
-
- /**
- * Is a given named Extension registered?
- *
- * @param string $extensionName
- * @return bool
- */
- public static function isRegistered($extensionName)
- {
- $feedName = $extensionName . '\Feed';
- $entryName = $extensionName . '\Entry';
- if (in_array($feedName, static::$extensions['feed'])
- || in_array($entryName, static::$extensions['entry'])
- ) {
- return true;
- }
- return false;
- }
-
- /**
- * Get a list of extensions
- *
- * @return array
- */
- public static function getExtensions()
- {
- return static::$extensions;
- }
-
- /**
- * Reset class state to defaults
- *
- * @return void
- */
- public static function reset()
- {
- static::$cache = null;
- static::$httpClient = null;
- static::$httpMethodOverride = false;
- static::$httpConditionalGet = false;
- static::$extensionManager = null;
- static::$extensions = array(
- 'feed' => array(
- 'DublinCore\Feed',
- 'Atom\Feed'
- ),
- 'entry' => array(
- 'Content\Entry',
- 'DublinCore\Entry',
- 'Atom\Entry'
- ),
- 'core' => array(
- 'DublinCore\Feed',
- 'Atom\Feed',
- 'Content\Entry',
- 'DublinCore\Entry',
- 'Atom\Entry'
- )
- );
- }
-
- /**
- * Register core (default) extensions
- *
- * @return void
- */
- protected static function registerCoreExtensions()
- {
- static::registerExtension('DublinCore');
- static::registerExtension('Content');
- static::registerExtension('Atom');
- static::registerExtension('Slash');
- static::registerExtension('WellFormedWeb');
- static::registerExtension('Thread');
- static::registerExtension('Podcast');
- }
-
- /**
- * Utility method to apply array_unique operation to a multidimensional
- * array.
- *
- * @param array
- * @return array
- */
- public static function arrayUnique(array $array)
- {
- foreach ($array as &$value) {
- $value = serialize($value);
- }
- $array = array_unique($array);
- foreach ($array as &$value) {
- $value = unserialize($value);
- }
- return $array;
- }
-}