web/lib/Zend/Feed/Reader.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Feed_Reader
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version    $Id: Reader.php 22662 2010-07-24 17:37:36Z mabe $
       
    20  */
       
    21 
       
    22 /**
       
    23  * @see Zend_Feed
       
    24  */
       
    25 require_once 'Zend/Feed.php';
       
    26 
       
    27 /**
       
    28  * @see Zend_Feed_Reader_Feed_Rss
       
    29  */
       
    30 require_once 'Zend/Feed/Reader/Feed/Rss.php';
       
    31 
       
    32 /**
       
    33  * @see Zend_Feed_Reader_Feed_Atom
       
    34  */
       
    35 require_once 'Zend/Feed/Reader/Feed/Atom.php';
       
    36 
       
    37 /**
       
    38  * @see Zend_Feed_Reader_FeedSet
       
    39  */
       
    40 require_once 'Zend/Feed/Reader/FeedSet.php';
       
    41 
       
    42 /**
       
    43  * @category   Zend
       
    44  * @package    Zend_Feed_Reader
       
    45  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    46  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    47  */
       
    48 class Zend_Feed_Reader
       
    49 {
       
    50     /**
       
    51      * Namespace constants
       
    52      */
       
    53     const NAMESPACE_ATOM_03  = 'http://purl.org/atom/ns#';
       
    54     const NAMESPACE_ATOM_10  = 'http://www.w3.org/2005/Atom';
       
    55     const NAMESPACE_RDF      = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
       
    56     const NAMESPACE_RSS_090  = 'http://my.netscape.com/rdf/simple/0.9/';
       
    57     const NAMESPACE_RSS_10   = 'http://purl.org/rss/1.0/';
       
    58 
       
    59     /**
       
    60      * Feed type constants
       
    61      */
       
    62     const TYPE_ANY              = 'any';
       
    63     const TYPE_ATOM_03          = 'atom-03';
       
    64     const TYPE_ATOM_10          = 'atom-10';
       
    65     const TYPE_ATOM_10_ENTRY    = 'atom-10-entry';
       
    66     const TYPE_ATOM_ANY         = 'atom';
       
    67     const TYPE_RSS_090          = 'rss-090';
       
    68     const TYPE_RSS_091          = 'rss-091';
       
    69     const TYPE_RSS_091_NETSCAPE = 'rss-091n';
       
    70     const TYPE_RSS_091_USERLAND = 'rss-091u';
       
    71     const TYPE_RSS_092          = 'rss-092';
       
    72     const TYPE_RSS_093          = 'rss-093';
       
    73     const TYPE_RSS_094          = 'rss-094';
       
    74     const TYPE_RSS_10           = 'rss-10';
       
    75     const TYPE_RSS_20           = 'rss-20';
       
    76     const TYPE_RSS_ANY          = 'rss';
       
    77 
       
    78     /**
       
    79      * Cache instance
       
    80      *
       
    81      * @var Zend_Cache_Core
       
    82      */
       
    83     protected static $_cache = null;
       
    84 
       
    85     /**
       
    86      * HTTP client object to use for retrieving feeds
       
    87      *
       
    88      * @var Zend_Http_Client
       
    89      */
       
    90     protected static $_httpClient = null;
       
    91 
       
    92     /**
       
    93      * Override HTTP PUT and DELETE request methods?
       
    94      *
       
    95      * @var boolean
       
    96      */
       
    97     protected static $_httpMethodOverride = false;
       
    98 
       
    99     protected static $_httpConditionalGet = false;
       
   100 
       
   101     protected static $_pluginLoader = null;
       
   102 
       
   103     protected static $_prefixPaths = array();
       
   104 
       
   105     protected static $_extensions = array(
       
   106         'feed' => array(
       
   107             'DublinCore_Feed',
       
   108             'Atom_Feed'
       
   109         ),
       
   110         'entry' => array(
       
   111             'Content_Entry',
       
   112             'DublinCore_Entry',
       
   113             'Atom_Entry'
       
   114         ),
       
   115         'core' => array(
       
   116             'DublinCore_Feed',
       
   117             'Atom_Feed',
       
   118             'Content_Entry',
       
   119             'DublinCore_Entry',
       
   120             'Atom_Entry'
       
   121         )
       
   122     );
       
   123 
       
   124     /**
       
   125      * Get the Feed cache
       
   126      *
       
   127      * @return Zend_Cache_Core
       
   128      */
       
   129     public static function getCache()
       
   130     {
       
   131         return self::$_cache;
       
   132     }
       
   133 
       
   134     /**
       
   135      * Set the feed cache
       
   136      *
       
   137      * @param Zend_Cache_Core $cache
       
   138      * @return void
       
   139      */
       
   140     public static function setCache(Zend_Cache_Core $cache)
       
   141     {
       
   142         self::$_cache = $cache;
       
   143     }
       
   144 
       
   145     /**
       
   146      * Set the HTTP client instance
       
   147      *
       
   148      * Sets the HTTP client object to use for retrieving the feeds.
       
   149      *
       
   150      * @param  Zend_Http_Client $httpClient
       
   151      * @return void
       
   152      */
       
   153     public static function setHttpClient(Zend_Http_Client $httpClient)
       
   154     {
       
   155         self::$_httpClient = $httpClient;
       
   156     }
       
   157 
       
   158 
       
   159     /**
       
   160      * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used.
       
   161      *
       
   162      * @return Zend_Http_Client_Abstract
       
   163      */
       
   164     public static function getHttpClient()
       
   165     {
       
   166         if (!self::$_httpClient instanceof Zend_Http_Client) {
       
   167             /**
       
   168              * @see Zend_Http_Client
       
   169              */
       
   170             require_once 'Zend/Http/Client.php';
       
   171             self::$_httpClient = new Zend_Http_Client();
       
   172         }
       
   173 
       
   174         return self::$_httpClient;
       
   175     }
       
   176 
       
   177     /**
       
   178      * Toggle using POST instead of PUT and DELETE HTTP methods
       
   179      *
       
   180      * Some feed implementations do not accept PUT and DELETE HTTP
       
   181      * methods, or they can't be used because of proxies or other
       
   182      * measures. This allows turning on using POST where PUT and
       
   183      * DELETE would normally be used; in addition, an
       
   184      * X-Method-Override header will be sent with a value of PUT or
       
   185      * DELETE as appropriate.
       
   186      *
       
   187      * @param  boolean $override Whether to override PUT and DELETE.
       
   188      * @return void
       
   189      */
       
   190     public static function setHttpMethodOverride($override = true)
       
   191     {
       
   192         self::$_httpMethodOverride = $override;
       
   193     }
       
   194 
       
   195     /**
       
   196      * Get the HTTP override state
       
   197      *
       
   198      * @return boolean
       
   199      */
       
   200     public static function getHttpMethodOverride()
       
   201     {
       
   202         return self::$_httpMethodOverride;
       
   203     }
       
   204 
       
   205     /**
       
   206      * Set the flag indicating whether or not to use HTTP conditional GET
       
   207      *
       
   208      * @param  bool $bool
       
   209      * @return void
       
   210      */
       
   211     public static function useHttpConditionalGet($bool = true)
       
   212     {
       
   213         self::$_httpConditionalGet = $bool;
       
   214     }
       
   215 
       
   216     /**
       
   217      * Import a feed by providing a URL
       
   218      *
       
   219      * @param  string $url The URL to the feed
       
   220      * @param  string $etag OPTIONAL Last received ETag for this resource
       
   221      * @param  string $lastModified OPTIONAL Last-Modified value for this resource
       
   222      * @return Zend_Feed_Reader_FeedInterface
       
   223      */
       
   224     public static function import($uri, $etag = null, $lastModified = null)
       
   225     {
       
   226         $cache       = self::getCache();
       
   227         $feed        = null;
       
   228         $responseXml = '';
       
   229         $client      = self::getHttpClient();
       
   230         $client->resetParameters();
       
   231         $client->setHeaders('If-None-Match', null);
       
   232         $client->setHeaders('If-Modified-Since', null);
       
   233         $client->setUri($uri);
       
   234         $cacheId = 'Zend_Feed_Reader_' . md5($uri);
       
   235 
       
   236         if (self::$_httpConditionalGet && $cache) {
       
   237             $data = $cache->load($cacheId);
       
   238             if ($data) {
       
   239                 if ($etag === null) {
       
   240                     $etag = $cache->load($cacheId.'_etag');
       
   241                 }
       
   242                 if ($lastModified === null) {
       
   243                     $lastModified = $cache->load($cacheId.'_lastmodified');;
       
   244                 }
       
   245                 if ($etag) {
       
   246                     $client->setHeaders('If-None-Match', $etag);
       
   247                 }
       
   248                 if ($lastModified) {
       
   249                     $client->setHeaders('If-Modified-Since', $lastModified);
       
   250                 }
       
   251             }
       
   252             $response = $client->request('GET');
       
   253             if ($response->getStatus() !== 200 && $response->getStatus() !== 304) {
       
   254                 require_once 'Zend/Feed/Exception.php';
       
   255                 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
       
   256             }
       
   257             if ($response->getStatus() == 304) {
       
   258                 $responseXml = $data;
       
   259             } else {
       
   260                 $responseXml = $response->getBody();
       
   261                 $cache->save($responseXml, $cacheId);
       
   262                 if ($response->getHeader('ETag')) {
       
   263                     $cache->save($response->getHeader('ETag'), $cacheId.'_etag');
       
   264                 }
       
   265                 if ($response->getHeader('Last-Modified')) {
       
   266                     $cache->save($response->getHeader('Last-Modified'), $cacheId.'_lastmodified');
       
   267                 }
       
   268             }
       
   269             return self::importString($responseXml);
       
   270         } elseif ($cache) {
       
   271             $data = $cache->load($cacheId);
       
   272             if ($data !== false) {
       
   273                 return self::importString($data);
       
   274             }
       
   275             $response = $client->request('GET');
       
   276             if ($response->getStatus() !== 200) {
       
   277                 require_once 'Zend/Feed/Exception.php';
       
   278                 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
       
   279             }
       
   280             $responseXml = $response->getBody();
       
   281             $cache->save($responseXml, $cacheId);
       
   282             return self::importString($responseXml);
       
   283         } else {
       
   284             $response = $client->request('GET');
       
   285             if ($response->getStatus() !== 200) {
       
   286                 require_once 'Zend/Feed/Exception.php';
       
   287                 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
       
   288             }
       
   289             $reader = self::importString($response->getBody());
       
   290             $reader->setOriginalSourceUri($uri);
       
   291             return $reader;
       
   292         }
       
   293     }
       
   294 
       
   295     /**
       
   296      * Import a feed by providing a Zend_Feed_Abstract object
       
   297      *
       
   298      * @param  Zend_Feed_Abstract $feed A fully instantiated Zend_Feed object
       
   299      * @return Zend_Feed_Reader_FeedInterface
       
   300      */
       
   301     public static function importFeed(Zend_Feed_Abstract $feed)
       
   302     {
       
   303         $dom  = $feed->getDOM()->ownerDocument;
       
   304         $type = self::detectType($dom);
       
   305         self::_registerCoreExtensions();
       
   306         if (substr($type, 0, 3) == 'rss') {
       
   307             $reader = new Zend_Feed_Reader_Feed_Rss($dom, $type);
       
   308         } else {
       
   309             $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
       
   310         }
       
   311 
       
   312         return $reader;
       
   313     }
       
   314 
       
   315     /**
       
   316      * Import a feed froma string
       
   317      *
       
   318      * @param  string $string
       
   319      * @return Zend_Feed_Reader_FeedInterface
       
   320      */
       
   321     public static function importString($string)
       
   322     {
       
   323         $libxml_errflag = libxml_use_internal_errors(true);
       
   324         $dom = new DOMDocument;
       
   325         $status = $dom->loadXML($string);
       
   326         libxml_use_internal_errors($libxml_errflag);
       
   327 
       
   328         if (!$status) {
       
   329             // Build error message
       
   330             $error = libxml_get_last_error();
       
   331             if ($error && $error->message) {
       
   332                 $errormsg = "DOMDocument cannot parse XML: {$error->message}";
       
   333             } else {
       
   334                 $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity";
       
   335             }
       
   336 
       
   337             require_once 'Zend/Feed/Exception.php';
       
   338             throw new Zend_Feed_Exception($errormsg);
       
   339         }
       
   340 
       
   341         $type = self::detectType($dom);
       
   342 
       
   343         self::_registerCoreExtensions();
       
   344 
       
   345         if (substr($type, 0, 3) == 'rss') {
       
   346             $reader = new Zend_Feed_Reader_Feed_Rss($dom, $type);
       
   347         } elseif (substr($type, 8, 5) == 'entry') {
       
   348             $reader = new Zend_Feed_Reader_Entry_Atom($dom->documentElement, 0, Zend_Feed_Reader::TYPE_ATOM_10);
       
   349         } elseif (substr($type, 0, 4) == 'atom') {
       
   350             $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type);
       
   351         } else {
       
   352             require_once 'Zend/Feed/Exception.php';
       
   353             throw new Zend_Feed_Exception('The URI used does not point to a '
       
   354             . 'valid Atom, RSS or RDF feed that Zend_Feed_Reader can parse.');
       
   355         }
       
   356         return $reader;
       
   357     }
       
   358 
       
   359     /**
       
   360      * Imports a feed from a file located at $filename.
       
   361      *
       
   362      * @param  string $filename
       
   363      * @throws Zend_Feed_Exception
       
   364      * @return Zend_Feed_Reader_FeedInterface
       
   365      */
       
   366     public static function importFile($filename)
       
   367     {
       
   368         @ini_set('track_errors', 1);
       
   369         $feed = @file_get_contents($filename);
       
   370         @ini_restore('track_errors');
       
   371         if ($feed === false) {
       
   372             /**
       
   373              * @see Zend_Feed_Exception
       
   374              */
       
   375             require_once 'Zend/Feed/Exception.php';
       
   376             throw new Zend_Feed_Exception("File could not be loaded: $php_errormsg");
       
   377         }
       
   378         return self::importString($feed);
       
   379     }
       
   380 
       
   381     public static function findFeedLinks($uri)
       
   382     {
       
   383         // Get the HTTP response from $uri and save the contents
       
   384         $client = self::getHttpClient();
       
   385         $client->setUri($uri);
       
   386         $response = $client->request();
       
   387         if ($response->getStatus() !== 200) {
       
   388             /**
       
   389              * @see Zend_Feed_Exception
       
   390              */
       
   391             require_once 'Zend/Feed/Exception.php';
       
   392             throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus());
       
   393         }
       
   394         $responseHtml = $response->getBody();
       
   395         $libxml_errflag = libxml_use_internal_errors(true);
       
   396         $dom = new DOMDocument;
       
   397         $status = $dom->loadHTML($responseHtml);
       
   398         libxml_use_internal_errors($libxml_errflag);
       
   399         if (!$status) {
       
   400             // Build error message
       
   401             $error = libxml_get_last_error();
       
   402             if ($error && $error->message) {
       
   403                 $errormsg = "DOMDocument cannot parse HTML: {$error->message}";
       
   404             } else {
       
   405                 $errormsg = "DOMDocument cannot parse HTML: Please check the XML document's validity";
       
   406             }
       
   407 
       
   408             require_once 'Zend/Feed/Exception.php';
       
   409             throw new Zend_Feed_Exception($errormsg);
       
   410         }
       
   411         $feedSet = new Zend_Feed_Reader_FeedSet;
       
   412         $links = $dom->getElementsByTagName('link');
       
   413         $feedSet->addLinks($links, $uri);
       
   414         return $feedSet;
       
   415     }
       
   416 
       
   417     /**
       
   418      * Detect the feed type of the provided feed
       
   419      *
       
   420      * @param  Zend_Feed_Abstract|DOMDocument|string $feed
       
   421      * @return string
       
   422      */
       
   423     public static function detectType($feed, $specOnly = false)
       
   424     {
       
   425         if ($feed instanceof Zend_Feed_Reader_FeedInterface) {
       
   426             $dom = $feed->getDomDocument();
       
   427         } elseif($feed instanceof DOMDocument) {
       
   428             $dom = $feed;
       
   429         } elseif(is_string($feed) && !empty($feed)) {
       
   430             @ini_set('track_errors', 1);
       
   431             $dom = new DOMDocument;
       
   432             $status = @$dom->loadXML($feed);
       
   433             @ini_restore('track_errors');
       
   434             if (!$status) {
       
   435                 if (!isset($php_errormsg)) {
       
   436                     if (function_exists('xdebug_is_enabled')) {
       
   437                         $php_errormsg = '(error message not available, when XDebug is running)';
       
   438                     } else {
       
   439                         $php_errormsg = '(error message not available)';
       
   440                     }
       
   441                 }
       
   442                 require_once 'Zend/Feed/Exception.php';
       
   443                 throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
       
   444             }
       
   445         } else {
       
   446             require_once 'Zend/Feed/Exception.php';
       
   447             throw new Zend_Feed_Exception('Invalid object/scalar provided: must'
       
   448             . ' be of type Zend_Feed_Reader_FeedInterface, DomDocument or string');
       
   449         }
       
   450         $xpath = new DOMXPath($dom);
       
   451 
       
   452         if ($xpath->query('/rss')->length) {
       
   453             $type = self::TYPE_RSS_ANY;
       
   454             $version = $xpath->evaluate('string(/rss/@version)');
       
   455 
       
   456             if (strlen($version) > 0) {
       
   457                 switch($version) {
       
   458                     case '2.0':
       
   459                         $type = self::TYPE_RSS_20;
       
   460                         break;
       
   461 
       
   462                     case '0.94':
       
   463                         $type = self::TYPE_RSS_094;
       
   464                         break;
       
   465 
       
   466                     case '0.93':
       
   467                         $type = self::TYPE_RSS_093;
       
   468                         break;
       
   469 
       
   470                     case '0.92':
       
   471                         $type = self::TYPE_RSS_092;
       
   472                         break;
       
   473 
       
   474                     case '0.91':
       
   475                         $type = self::TYPE_RSS_091;
       
   476                         break;
       
   477                 }
       
   478             }
       
   479 
       
   480             return $type;
       
   481         }
       
   482 
       
   483         $xpath->registerNamespace('rdf', self::NAMESPACE_RDF);
       
   484 
       
   485         if ($xpath->query('/rdf:RDF')->length) {
       
   486             $xpath->registerNamespace('rss', self::NAMESPACE_RSS_10);
       
   487 
       
   488             if ($xpath->query('/rdf:RDF/rss:channel')->length
       
   489                 || $xpath->query('/rdf:RDF/rss:image')->length
       
   490                 || $xpath->query('/rdf:RDF/rss:item')->length
       
   491                 || $xpath->query('/rdf:RDF/rss:textinput')->length
       
   492             ) {
       
   493                 return self::TYPE_RSS_10;
       
   494             }
       
   495 
       
   496             $xpath->registerNamespace('rss', self::NAMESPACE_RSS_090);
       
   497 
       
   498             if ($xpath->query('/rdf:RDF/rss:channel')->length
       
   499                 || $xpath->query('/rdf:RDF/rss:image')->length
       
   500                 || $xpath->query('/rdf:RDF/rss:item')->length
       
   501                 || $xpath->query('/rdf:RDF/rss:textinput')->length
       
   502             ) {
       
   503                 return self::TYPE_RSS_090;
       
   504             }
       
   505         }
       
   506 
       
   507         $type = self::TYPE_ATOM_ANY;
       
   508         $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10);
       
   509 
       
   510         if ($xpath->query('//atom:feed')->length) {
       
   511             return self::TYPE_ATOM_10;
       
   512         }
       
   513         
       
   514         if ($xpath->query('//atom:entry')->length) {
       
   515             if ($specOnly == true) {
       
   516                 return self::TYPE_ATOM_10;
       
   517             } else {
       
   518                 return self::TYPE_ATOM_10_ENTRY;
       
   519             }
       
   520         }
       
   521 
       
   522         $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_03);
       
   523 
       
   524         if ($xpath->query('//atom:feed')->length) {
       
   525             return self::TYPE_ATOM_03;
       
   526         }
       
   527 
       
   528         return self::TYPE_ANY;
       
   529     }
       
   530 
       
   531     /**
       
   532      * Set plugin loader for use with Extensions
       
   533      *
       
   534      * @param  Zend_Loader_PluginLoader_Interface $loader
       
   535      */
       
   536     public static function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader)
       
   537     {
       
   538         self::$_pluginLoader = $loader;
       
   539     }
       
   540 
       
   541     /**
       
   542      * Get plugin loader for use with Extensions
       
   543      *
       
   544      * @return  Zend_Loader_PluginLoader_Interface $loader
       
   545      */
       
   546     public static function getPluginLoader()
       
   547     {
       
   548         if (!isset(self::$_pluginLoader)) {
       
   549             require_once 'Zend/Loader/PluginLoader.php';
       
   550             self::$_pluginLoader = new Zend_Loader_PluginLoader(array(
       
   551                 'Zend_Feed_Reader_Extension_' => 'Zend/Feed/Reader/Extension/',
       
   552             ));
       
   553         }
       
   554         return self::$_pluginLoader;
       
   555     }
       
   556 
       
   557     /**
       
   558      * Add prefix path for loading Extensions
       
   559      *
       
   560      * @param  string $prefix
       
   561      * @param  string $path
       
   562      * @return void
       
   563      */
       
   564     public static function addPrefixPath($prefix, $path)
       
   565     {
       
   566         $prefix = rtrim($prefix, '_');
       
   567         $path   = rtrim($path, DIRECTORY_SEPARATOR);
       
   568         self::getPluginLoader()->addPrefixPath($prefix, $path);
       
   569     }
       
   570 
       
   571     /**
       
   572      * Add multiple Extension prefix paths at once
       
   573      *
       
   574      * @param  array $spec
       
   575      * @return void
       
   576      */
       
   577     public static function addPrefixPaths(array $spec)
       
   578     {
       
   579         if (isset($spec['prefix']) && isset($spec['path'])) {
       
   580             self::addPrefixPath($spec['prefix'], $spec['path']);
       
   581         }
       
   582         foreach ($spec as $prefixPath) {
       
   583             if (isset($prefixPath['prefix']) && isset($prefixPath['path'])) {
       
   584                 self::addPrefixPath($prefixPath['prefix'], $prefixPath['path']);
       
   585             }
       
   586         }
       
   587     }
       
   588 
       
   589     /**
       
   590      * Register an Extension by name
       
   591      *
       
   592      * @param  string $name
       
   593      * @return void
       
   594      * @throws Zend_Feed_Exception if unable to resolve Extension class
       
   595      */
       
   596     public static function registerExtension($name)
       
   597     {
       
   598         $feedName  = $name . '_Feed';
       
   599         $entryName = $name . '_Entry';
       
   600         if (self::isRegistered($name)) {
       
   601             if (self::getPluginLoader()->isLoaded($feedName) ||
       
   602                 self::getPluginLoader()->isLoaded($entryName)) {
       
   603                 return;
       
   604             }
       
   605         }
       
   606         try {
       
   607             self::getPluginLoader()->load($feedName);
       
   608             self::$_extensions['feed'][] = $feedName;
       
   609         } catch (Zend_Loader_PluginLoader_Exception $e) {
       
   610         }
       
   611         try {
       
   612             self::getPluginLoader()->load($entryName);
       
   613             self::$_extensions['entry'][] = $entryName;
       
   614         } catch (Zend_Loader_PluginLoader_Exception $e) {
       
   615         }
       
   616         if (!self::getPluginLoader()->isLoaded($feedName)
       
   617             && !self::getPluginLoader()->isLoaded($entryName)
       
   618         ) {
       
   619             require_once 'Zend/Feed/Exception.php';
       
   620             throw new Zend_Feed_Exception('Could not load extension: ' . $name
       
   621                 . 'using Plugin Loader. Check prefix paths are configured and extension exists.');
       
   622         }
       
   623     }
       
   624 
       
   625     /**
       
   626      * Is a given named Extension registered?
       
   627      *
       
   628      * @param  string $extensionName
       
   629      * @return boolean
       
   630      */
       
   631     public static function isRegistered($extensionName)
       
   632     {
       
   633         $feedName  = $extensionName . '_Feed';
       
   634         $entryName = $extensionName . '_Entry';
       
   635         if (in_array($feedName, self::$_extensions['feed'])
       
   636             || in_array($entryName, self::$_extensions['entry'])
       
   637         ) {
       
   638             return true;
       
   639         }
       
   640         return false;
       
   641     }
       
   642 
       
   643     /**
       
   644      * Get a list of extensions
       
   645      *
       
   646      * @return array
       
   647      */
       
   648     public static function getExtensions()
       
   649     {
       
   650         return self::$_extensions;
       
   651     }
       
   652 
       
   653     /**
       
   654      * Reset class state to defaults
       
   655      *
       
   656      * @return void
       
   657      */
       
   658     public static function reset()
       
   659     {
       
   660         self::$_cache              = null;
       
   661         self::$_httpClient         = null;
       
   662         self::$_httpMethodOverride = false;
       
   663         self::$_httpConditionalGet = false;
       
   664         self::$_pluginLoader       = null;
       
   665         self::$_prefixPaths        = array();
       
   666         self::$_extensions         = array(
       
   667             'feed' => array(
       
   668                 'DublinCore_Feed',
       
   669                 'Atom_Feed'
       
   670             ),
       
   671             'entry' => array(
       
   672                 'Content_Entry',
       
   673                 'DublinCore_Entry',
       
   674                 'Atom_Entry'
       
   675             ),
       
   676             'core' => array(
       
   677                 'DublinCore_Feed',
       
   678                 'Atom_Feed',
       
   679                 'Content_Entry',
       
   680                 'DublinCore_Entry',
       
   681                 'Atom_Entry'
       
   682             )
       
   683         );
       
   684     }
       
   685 
       
   686     /**
       
   687      * Register core (default) extensions
       
   688      *
       
   689      * @return void
       
   690      */
       
   691     protected static function _registerCoreExtensions()
       
   692     {
       
   693         self::registerExtension('DublinCore');
       
   694         self::registerExtension('Content');
       
   695         self::registerExtension('Atom');
       
   696         self::registerExtension('Slash');
       
   697         self::registerExtension('WellFormedWeb');
       
   698         self::registerExtension('Thread');
       
   699         self::registerExtension('Podcast');
       
   700     }
       
   701     
       
   702     /**
       
   703      * Utility method to apply array_unique operation to a multidimensional
       
   704      * array.
       
   705      *
       
   706      * @param array
       
   707      * @return array
       
   708      */
       
   709     public static function arrayUnique(array $array)
       
   710     {
       
   711         foreach ($array as &$value) {
       
   712             $value = serialize($value);
       
   713         }
       
   714         $array = array_unique($array);
       
   715         foreach ($array as &$value) {
       
   716             $value = unserialize($value);
       
   717         }
       
   718         return $array;
       
   719     }
       
   720  
       
   721 }