File indexing completed on 2024-12-22 05:36:40
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 0024 */ 0025 // require_once 'Zend/Feed.php'; 0026 0027 /** 0028 * @see Zend_Feed_Reader_Feed_Rss 0029 */ 0030 // require_once 'Zend/Feed/Reader/Feed/Rss.php'; 0031 0032 /** 0033 * @see Zend_Feed_Reader_Feed_Atom 0034 */ 0035 // require_once 'Zend/Feed/Reader/Feed/Atom.php'; 0036 0037 /** 0038 * @see Zend_Feed_Reader_FeedSet 0039 */ 0040 // require_once 'Zend/Feed/Reader/FeedSet.php'; 0041 0042 /** @see Zend_Xml_Security */ 0043 // require_once 'Zend/Xml/Security.php'; 0044 0045 /** @see Zend_Xml_Exception */ 0046 // require_once 'Zend/Xml/Exception.php'; 0047 0048 /** 0049 * @category Zend 0050 * @package Zend_Feed_Reader 0051 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0052 * @license http://framework.zend.com/license/new-bsd New BSD License 0053 */ 0054 class Zend_Feed_Reader 0055 { 0056 /** 0057 * Namespace constants 0058 */ 0059 const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#'; 0060 const NAMESPACE_ATOM_10 = 'http://www.w3.org/2005/Atom'; 0061 const NAMESPACE_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; 0062 const NAMESPACE_RSS_090 = 'http://my.netscape.com/rdf/simple/0.9/'; 0063 const NAMESPACE_RSS_10 = 'http://purl.org/rss/1.0/'; 0064 0065 /** 0066 * Feed type constants 0067 */ 0068 const TYPE_ANY = 'any'; 0069 const TYPE_ATOM_03 = 'atom-03'; 0070 const TYPE_ATOM_10 = 'atom-10'; 0071 const TYPE_ATOM_10_ENTRY = 'atom-10-entry'; 0072 const TYPE_ATOM_ANY = 'atom'; 0073 const TYPE_RSS_090 = 'rss-090'; 0074 const TYPE_RSS_091 = 'rss-091'; 0075 const TYPE_RSS_091_NETSCAPE = 'rss-091n'; 0076 const TYPE_RSS_091_USERLAND = 'rss-091u'; 0077 const TYPE_RSS_092 = 'rss-092'; 0078 const TYPE_RSS_093 = 'rss-093'; 0079 const TYPE_RSS_094 = 'rss-094'; 0080 const TYPE_RSS_10 = 'rss-10'; 0081 const TYPE_RSS_20 = 'rss-20'; 0082 const TYPE_RSS_ANY = 'rss'; 0083 0084 /** 0085 * Cache instance 0086 * 0087 * @var Zend_Cache_Core 0088 */ 0089 protected static $_cache = null; 0090 0091 /** 0092 * HTTP client object to use for retrieving feeds 0093 * 0094 * @var Zend_Http_Client 0095 */ 0096 protected static $_httpClient = null; 0097 0098 /** 0099 * Override HTTP PUT and DELETE request methods? 0100 * 0101 * @var boolean 0102 */ 0103 protected static $_httpMethodOverride = false; 0104 0105 protected static $_httpConditionalGet = false; 0106 0107 protected static $_pluginLoader = null; 0108 0109 protected static $_prefixPaths = array(); 0110 0111 protected static $_extensions = array( 0112 'feed' => array( 0113 'DublinCore_Feed', 0114 'Atom_Feed' 0115 ), 0116 'entry' => array( 0117 'Content_Entry', 0118 'DublinCore_Entry', 0119 'Atom_Entry' 0120 ), 0121 'core' => array( 0122 'DublinCore_Feed', 0123 'Atom_Feed', 0124 'Content_Entry', 0125 'DublinCore_Entry', 0126 'Atom_Entry' 0127 ) 0128 ); 0129 0130 /** 0131 * Get the Feed cache 0132 * 0133 * @return Zend_Cache_Core 0134 */ 0135 public static function getCache() 0136 { 0137 return self::$_cache; 0138 } 0139 0140 /** 0141 * Set the feed cache 0142 * 0143 * @param Zend_Cache_Core $cache 0144 * @return void 0145 */ 0146 public static function setCache(Zend_Cache_Core $cache) 0147 { 0148 self::$_cache = $cache; 0149 } 0150 0151 /** 0152 * Set the HTTP client instance 0153 * 0154 * Sets the HTTP client object to use for retrieving the feeds. 0155 * 0156 * @param Zend_Http_Client $httpClient 0157 * @return void 0158 */ 0159 public static function setHttpClient(Zend_Http_Client $httpClient) 0160 { 0161 self::$_httpClient = $httpClient; 0162 } 0163 0164 0165 /** 0166 * Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used. 0167 * 0168 * @return Zend_Http_Client_Abstract 0169 */ 0170 public static function getHttpClient() 0171 { 0172 if (!self::$_httpClient instanceof Zend_Http_Client) { 0173 /** 0174 * @see Zend_Http_Client 0175 */ 0176 // require_once 'Zend/Http/Client.php'; 0177 self::$_httpClient = new Zend_Http_Client(); 0178 } 0179 0180 return self::$_httpClient; 0181 } 0182 0183 /** 0184 * Toggle using POST instead of PUT and DELETE HTTP methods 0185 * 0186 * Some feed implementations do not accept PUT and DELETE HTTP 0187 * methods, or they can't be used because of proxies or other 0188 * measures. This allows turning on using POST where PUT and 0189 * DELETE would normally be used; in addition, an 0190 * X-Method-Override header will be sent with a value of PUT or 0191 * DELETE as appropriate. 0192 * 0193 * @param boolean $override Whether to override PUT and DELETE. 0194 * @return void 0195 */ 0196 public static function setHttpMethodOverride($override = true) 0197 { 0198 self::$_httpMethodOverride = $override; 0199 } 0200 0201 /** 0202 * Get the HTTP override state 0203 * 0204 * @return boolean 0205 */ 0206 public static function getHttpMethodOverride() 0207 { 0208 return self::$_httpMethodOverride; 0209 } 0210 0211 /** 0212 * Set the flag indicating whether or not to use HTTP conditional GET 0213 * 0214 * @param bool $bool 0215 * @return void 0216 */ 0217 public static function useHttpConditionalGet($bool = true) 0218 { 0219 self::$_httpConditionalGet = $bool; 0220 } 0221 0222 /** 0223 * Import a feed by providing a URL 0224 * 0225 * @param string $url The URL to the feed 0226 * @param string $etag OPTIONAL Last received ETag for this resource 0227 * @param string $lastModified OPTIONAL Last-Modified value for this resource 0228 * @return Zend_Feed_Reader_FeedInterface 0229 */ 0230 public static function import($uri, $etag = null, $lastModified = null) 0231 { 0232 $cache = self::getCache(); 0233 $feed = null; 0234 $responseXml = ''; 0235 $client = self::getHttpClient(); 0236 $client->resetParameters(); 0237 $client->setHeaders('If-None-Match', null); 0238 $client->setHeaders('If-Modified-Since', null); 0239 $client->setUri($uri); 0240 $cacheId = 'Zend_Feed_Reader_' . md5($uri); 0241 0242 if (self::$_httpConditionalGet && $cache) { 0243 $data = $cache->load($cacheId); 0244 if ($data) { 0245 if ($etag === null) { 0246 $etag = $cache->load($cacheId.'_etag'); 0247 } 0248 if ($lastModified === null) { 0249 $lastModified = $cache->load($cacheId.'_lastmodified'); 0250 } 0251 if ($etag) { 0252 $client->setHeaders('If-None-Match', $etag); 0253 } 0254 if ($lastModified) { 0255 $client->setHeaders('If-Modified-Since', $lastModified); 0256 } 0257 } 0258 $response = $client->request('GET'); 0259 if ($response->getStatus() !== 200 && $response->getStatus() !== 304) { 0260 // require_once 'Zend/Feed/Exception.php'; 0261 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); 0262 } 0263 if ($response->getStatus() == 304) { 0264 $responseXml = $data; 0265 } else { 0266 $responseXml = $response->getBody(); 0267 $cache->save($responseXml, $cacheId); 0268 if ($response->getHeader('ETag')) { 0269 $cache->save($response->getHeader('ETag'), $cacheId.'_etag'); 0270 } 0271 if ($response->getHeader('Last-Modified')) { 0272 $cache->save($response->getHeader('Last-Modified'), $cacheId.'_lastmodified'); 0273 } 0274 } 0275 if (empty($responseXml)) { 0276 // require_once 'Zend/Feed/Exception.php'; 0277 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); 0278 } 0279 return self::importString($responseXml); 0280 } elseif ($cache) { 0281 $data = $cache->load($cacheId); 0282 if ($data !== false) { 0283 return self::importString($data); 0284 } 0285 $response = $client->request('GET'); 0286 if ($response->getStatus() !== 200) { 0287 // require_once 'Zend/Feed/Exception.php'; 0288 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); 0289 } 0290 $responseXml = $response->getBody(); 0291 $cache->save($responseXml, $cacheId); 0292 if (empty($responseXml)) { 0293 // require_once 'Zend/Feed/Exception.php'; 0294 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); 0295 } 0296 return self::importString($responseXml); 0297 } else { 0298 $response = $client->request('GET'); 0299 if ($response->getStatus() !== 200) { 0300 // require_once 'Zend/Feed/Exception.php'; 0301 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); 0302 } 0303 $responseXml = $response->getBody(); 0304 if (empty($responseXml)) { 0305 // require_once 'Zend/Feed/Exception.php'; 0306 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); 0307 } 0308 $reader = self::importString($responseXml); 0309 $reader->setOriginalSourceUri($uri); 0310 return $reader; 0311 } 0312 } 0313 0314 /** 0315 * Import a feed by providing a Zend_Feed_Abstract object 0316 * 0317 * @param Zend_Feed_Abstract $feed A fully instantiated Zend_Feed object 0318 * @return Zend_Feed_Reader_FeedInterface 0319 */ 0320 public static function importFeed(Zend_Feed_Abstract $feed) 0321 { 0322 $dom = $feed->getDOM()->ownerDocument; 0323 $type = self::detectType($dom); 0324 self::_registerCoreExtensions(); 0325 if (substr($type, 0, 3) == 'rss') { 0326 $reader = new Zend_Feed_Reader_Feed_Rss($dom, $type); 0327 } else { 0328 $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type); 0329 } 0330 0331 return $reader; 0332 } 0333 0334 /** 0335 * Import a feed from a string 0336 * 0337 * @param string $string 0338 * @return Zend_Feed_Reader_FeedInterface 0339 */ 0340 public static function importString($string) 0341 { 0342 $dom = new DOMDocument; 0343 try { 0344 $dom = Zend_Xml_Security::scan($string, $dom); 0345 } catch (Zend_Xml_Exception $e) { 0346 // require_once 'Zend/Feed/Exception.php'; 0347 throw new Zend_Feed_Exception( 0348 $e->getMessage() 0349 ); 0350 } 0351 if (!$dom) { 0352 // Build error message 0353 $error = libxml_get_last_error(); 0354 if ($error && $error->message) { 0355 $errormsg = "DOMDocument cannot parse XML: {$error->message}"; 0356 } else { 0357 $errormsg = "DOMDocument cannot parse XML: Please check the XML document's validity"; 0358 } 0359 0360 // require_once 'Zend/Feed/Exception.php'; 0361 throw new Zend_Feed_Exception($errormsg); 0362 } 0363 0364 $type = self::detectType($dom); 0365 0366 self::_registerCoreExtensions(); 0367 0368 if (substr($type, 0, 3) == 'rss') { 0369 $reader = new Zend_Feed_Reader_Feed_Rss($dom, $type); 0370 } elseif (substr($type, 8, 5) == 'entry') { 0371 $reader = new Zend_Feed_Reader_Entry_Atom($dom->documentElement, 0, Zend_Feed_Reader::TYPE_ATOM_10); 0372 } elseif (substr($type, 0, 4) == 'atom') { 0373 $reader = new Zend_Feed_Reader_Feed_Atom($dom, $type); 0374 } else { 0375 // require_once 'Zend/Feed/Exception.php'; 0376 throw new Zend_Feed_Exception('The URI used does not point to a ' 0377 . 'valid Atom, RSS or RDF feed that Zend_Feed_Reader can parse.'); 0378 } 0379 return $reader; 0380 } 0381 0382 /** 0383 * Imports a feed from a file located at $filename. 0384 * 0385 * @param string $filename 0386 * @throws Zend_Feed_Exception 0387 * @return Zend_Feed_Reader_FeedInterface 0388 */ 0389 public static function importFile($filename) 0390 { 0391 @ini_set('track_errors', 1); 0392 $feed = @file_get_contents($filename); 0393 @ini_restore('track_errors'); 0394 if ($feed === false) { 0395 /** 0396 * @see Zend_Feed_Exception 0397 */ 0398 // require_once 'Zend/Feed/Exception.php'; 0399 throw new Zend_Feed_Exception("File could not be loaded: $php_errormsg"); 0400 } 0401 return self::importString($feed); 0402 } 0403 0404 public static function findFeedLinks($uri) 0405 { 0406 // Get the HTTP response from $uri and save the contents 0407 $client = self::getHttpClient(); 0408 $client->setUri($uri); 0409 $response = $client->request(); 0410 if ($response->getStatus() !== 200) { 0411 /** 0412 * @see Zend_Feed_Exception 0413 */ 0414 // require_once 'Zend/Feed/Exception.php'; 0415 throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus()); 0416 } 0417 $responseHtml = $response->getBody(); 0418 $libxml_errflag = libxml_use_internal_errors(true); 0419 $oldValue = libxml_disable_entity_loader(true); 0420 $dom = new DOMDocument; 0421 $status = $dom->loadHTML($responseHtml); 0422 libxml_disable_entity_loader($oldValue); 0423 libxml_use_internal_errors($libxml_errflag); 0424 if (!$status) { 0425 // Build error message 0426 $error = libxml_get_last_error(); 0427 if ($error && $error->message) { 0428 $errormsg = "DOMDocument cannot parse HTML: {$error->message}"; 0429 } else { 0430 $errormsg = "DOMDocument cannot parse HTML: Please check the XML document's validity"; 0431 } 0432 0433 // require_once 'Zend/Feed/Exception.php'; 0434 throw new Zend_Feed_Exception($errormsg); 0435 } 0436 $feedSet = new Zend_Feed_Reader_FeedSet; 0437 $links = $dom->getElementsByTagName('link'); 0438 $feedSet->addLinks($links, $uri); 0439 return $feedSet; 0440 } 0441 0442 /** 0443 * Detect the feed type of the provided feed 0444 * 0445 * @param Zend_Feed_Abstract|DOMDocument|string $feed 0446 * @param bool $specOnly 0447 * @return string 0448 * @throws Zend_Feed_Exception 0449 */ 0450 public static function detectType($feed, $specOnly = false) 0451 { 0452 if ($feed instanceof Zend_Feed_Reader_FeedInterface) { 0453 $dom = $feed->getDomDocument(); 0454 } elseif($feed instanceof DOMDocument) { 0455 $dom = $feed; 0456 } elseif(is_string($feed) && !empty($feed)) { 0457 @ini_set('track_errors', 1); 0458 //$oldValue = libxml_disable_entity_loader(true); 0459 $dom = new DOMDocument; 0460 try { 0461 $dom = Zend_Xml_Security::scan($feed, $dom); 0462 } catch (Zend_Xml_Exception $e) { 0463 // require_once 'Zend/Feed/Exception.php'; 0464 throw new Zend_Feed_Exception( 0465 $e->getMessage() 0466 ); 0467 } 0468 //libxml_disable_entity_loader($oldValue); 0469 @ini_restore('track_errors'); 0470 if (!$dom) { 0471 if (!isset($php_errormsg)) { 0472 if (function_exists('xdebug_is_enabled')) { 0473 $php_errormsg = '(error message not available, when XDebug is running)'; 0474 } else { 0475 $php_errormsg = '(error message not available)'; 0476 } 0477 } 0478 // require_once 'Zend/Feed/Exception.php'; 0479 throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg"); 0480 } 0481 } else { 0482 // require_once 'Zend/Feed/Exception.php'; 0483 throw new Zend_Feed_Exception('Invalid object/scalar provided: must' 0484 . ' be of type Zend_Feed_Reader_FeedInterface, DomDocument or string'); 0485 } 0486 $xpath = new DOMXPath($dom); 0487 0488 if ($xpath->query('/rss')->length) { 0489 $type = self::TYPE_RSS_ANY; 0490 $version = $xpath->evaluate('string(/rss/@version)'); 0491 0492 if (strlen($version) > 0) { 0493 switch($version) { 0494 case '2.0': 0495 $type = self::TYPE_RSS_20; 0496 break; 0497 0498 case '0.94': 0499 $type = self::TYPE_RSS_094; 0500 break; 0501 0502 case '0.93': 0503 $type = self::TYPE_RSS_093; 0504 break; 0505 0506 case '0.92': 0507 $type = self::TYPE_RSS_092; 0508 break; 0509 0510 case '0.91': 0511 $type = self::TYPE_RSS_091; 0512 break; 0513 } 0514 } 0515 0516 return $type; 0517 } 0518 0519 $xpath->registerNamespace('rdf', self::NAMESPACE_RDF); 0520 0521 if ($xpath->query('/rdf:RDF')->length) { 0522 $xpath->registerNamespace('rss', self::NAMESPACE_RSS_10); 0523 0524 if ($xpath->query('/rdf:RDF/rss:channel')->length 0525 || $xpath->query('/rdf:RDF/rss:image')->length 0526 || $xpath->query('/rdf:RDF/rss:item')->length 0527 || $xpath->query('/rdf:RDF/rss:textinput')->length 0528 ) { 0529 return self::TYPE_RSS_10; 0530 } 0531 0532 $xpath->registerNamespace('rss', self::NAMESPACE_RSS_090); 0533 0534 if ($xpath->query('/rdf:RDF/rss:channel')->length 0535 || $xpath->query('/rdf:RDF/rss:image')->length 0536 || $xpath->query('/rdf:RDF/rss:item')->length 0537 || $xpath->query('/rdf:RDF/rss:textinput')->length 0538 ) { 0539 return self::TYPE_RSS_090; 0540 } 0541 } 0542 0543 $type = self::TYPE_ATOM_ANY; 0544 $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10); 0545 0546 if ($xpath->query('//atom:feed')->length) { 0547 return self::TYPE_ATOM_10; 0548 } 0549 0550 if ($xpath->query('//atom:entry')->length) { 0551 if ($specOnly == true) { 0552 return self::TYPE_ATOM_10; 0553 } else { 0554 return self::TYPE_ATOM_10_ENTRY; 0555 } 0556 } 0557 0558 $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_03); 0559 0560 if ($xpath->query('//atom:feed')->length) { 0561 return self::TYPE_ATOM_03; 0562 } 0563 0564 return self::TYPE_ANY; 0565 } 0566 0567 /** 0568 * Set plugin loader for use with Extensions 0569 * 0570 * @param Zend_Loader_PluginLoader_Interface $loader 0571 */ 0572 public static function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader) 0573 { 0574 self::$_pluginLoader = $loader; 0575 } 0576 0577 /** 0578 * Get plugin loader for use with Extensions 0579 * 0580 * @return Zend_Loader_PluginLoader_Interface $loader 0581 */ 0582 public static function getPluginLoader() 0583 { 0584 if (!isset(self::$_pluginLoader)) { 0585 // require_once 'Zend/Loader/PluginLoader.php'; 0586 self::$_pluginLoader = new Zend_Loader_PluginLoader(array( 0587 'Zend_Feed_Reader_Extension_' => 'Zend/Feed/Reader/Extension/', 0588 )); 0589 } 0590 return self::$_pluginLoader; 0591 } 0592 0593 /** 0594 * Add prefix path for loading Extensions 0595 * 0596 * @param string $prefix 0597 * @param string $path 0598 * @return void 0599 */ 0600 public static function addPrefixPath($prefix, $path) 0601 { 0602 $prefix = rtrim($prefix, '_'); 0603 $path = rtrim($path, DIRECTORY_SEPARATOR); 0604 self::getPluginLoader()->addPrefixPath($prefix, $path); 0605 } 0606 0607 /** 0608 * Add multiple Extension prefix paths at once 0609 * 0610 * @param array $spec 0611 * @return void 0612 */ 0613 public static function addPrefixPaths(array $spec) 0614 { 0615 if (isset($spec['prefix']) && isset($spec['path'])) { 0616 self::addPrefixPath($spec['prefix'], $spec['path']); 0617 } 0618 foreach ($spec as $prefixPath) { 0619 if (isset($prefixPath['prefix']) && isset($prefixPath['path'])) { 0620 self::addPrefixPath($prefixPath['prefix'], $prefixPath['path']); 0621 } 0622 } 0623 } 0624 0625 /** 0626 * Register an Extension by name 0627 * 0628 * @param string $name 0629 * @return void 0630 * @throws Zend_Feed_Exception if unable to resolve Extension class 0631 */ 0632 public static function registerExtension($name) 0633 { 0634 $feedName = $name . '_Feed'; 0635 $entryName = $name . '_Entry'; 0636 if (self::isRegistered($name)) { 0637 if (self::getPluginLoader()->isLoaded($feedName) || 0638 self::getPluginLoader()->isLoaded($entryName)) { 0639 return; 0640 } 0641 } 0642 try { 0643 self::getPluginLoader()->load($feedName); 0644 self::$_extensions['feed'][] = $feedName; 0645 } catch (Zend_Loader_PluginLoader_Exception $e) { 0646 } 0647 try { 0648 self::getPluginLoader()->load($entryName); 0649 self::$_extensions['entry'][] = $entryName; 0650 } catch (Zend_Loader_PluginLoader_Exception $e) { 0651 } 0652 if (!self::getPluginLoader()->isLoaded($feedName) 0653 && !self::getPluginLoader()->isLoaded($entryName) 0654 ) { 0655 // require_once 'Zend/Feed/Exception.php'; 0656 throw new Zend_Feed_Exception('Could not load extension: ' . $name 0657 . 'using Plugin Loader. Check prefix paths are configured and extension exists.'); 0658 } 0659 } 0660 0661 /** 0662 * Is a given named Extension registered? 0663 * 0664 * @param string $extensionName 0665 * @return boolean 0666 */ 0667 public static function isRegistered($extensionName) 0668 { 0669 $feedName = $extensionName . '_Feed'; 0670 $entryName = $extensionName . '_Entry'; 0671 if (in_array($feedName, self::$_extensions['feed']) 0672 || in_array($entryName, self::$_extensions['entry']) 0673 ) { 0674 return true; 0675 } 0676 return false; 0677 } 0678 0679 /** 0680 * Get a list of extensions 0681 * 0682 * @return array 0683 */ 0684 public static function getExtensions() 0685 { 0686 return self::$_extensions; 0687 } 0688 0689 /** 0690 * Reset class state to defaults 0691 * 0692 * @return void 0693 */ 0694 public static function reset() 0695 { 0696 self::$_cache = null; 0697 self::$_httpClient = null; 0698 self::$_httpMethodOverride = false; 0699 self::$_httpConditionalGet = false; 0700 self::$_pluginLoader = null; 0701 self::$_prefixPaths = array(); 0702 self::$_extensions = array( 0703 'feed' => array( 0704 'DublinCore_Feed', 0705 'Atom_Feed' 0706 ), 0707 'entry' => array( 0708 'Content_Entry', 0709 'DublinCore_Entry', 0710 'Atom_Entry' 0711 ), 0712 'core' => array( 0713 'DublinCore_Feed', 0714 'Atom_Feed', 0715 'Content_Entry', 0716 'DublinCore_Entry', 0717 'Atom_Entry' 0718 ) 0719 ); 0720 } 0721 0722 /** 0723 * Register core (default) extensions 0724 * 0725 * @return void 0726 */ 0727 protected static function _registerCoreExtensions() 0728 { 0729 self::registerExtension('DublinCore'); 0730 self::registerExtension('Content'); 0731 self::registerExtension('Atom'); 0732 self::registerExtension('Slash'); 0733 self::registerExtension('WellFormedWeb'); 0734 self::registerExtension('Thread'); 0735 self::registerExtension('Podcast'); 0736 } 0737 0738 /** 0739 * Utility method to apply array_unique operation to a multidimensional 0740 * array. 0741 * 0742 * @param array 0743 * @return array 0744 */ 0745 public static function arrayUnique(array $array) 0746 { 0747 foreach ($array as &$value) { 0748 $value = serialize($value); 0749 } 0750 $array = array_unique($array); 0751 foreach ($array as &$value) { 0752 $value = unserialize($value); 0753 } 0754 return $array; 0755 } 0756 0757 }