12 * obtain it through the world-wide-web, please send an email |
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. |
13 * to license@zend.com so we can send you a copy immediately. |
14 * |
14 * |
15 * @category Zend |
15 * @category Zend |
16 * @package Zend_Feed_Reader |
16 * @package Zend_Feed_Reader |
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
17 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
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 $ |
19 * @version $Id: Reader.php 25275 2013-03-06 09:55:33Z frosch $ |
20 */ |
20 */ |
21 |
21 |
22 /** |
22 /** |
23 * @see Zend_Feed |
23 * @see Zend_Feed |
24 */ |
24 */ |
40 require_once 'Zend/Feed/Reader/FeedSet.php'; |
40 require_once 'Zend/Feed/Reader/FeedSet.php'; |
41 |
41 |
42 /** |
42 /** |
43 * @category Zend |
43 * @category Zend |
44 * @package Zend_Feed_Reader |
44 * @package Zend_Feed_Reader |
45 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
45 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
46 * @license http://framework.zend.com/license/new-bsd New BSD License |
46 * @license http://framework.zend.com/license/new-bsd New BSD License |
47 */ |
47 */ |
48 class Zend_Feed_Reader |
48 class Zend_Feed_Reader |
49 { |
49 { |
50 /** |
50 /** |
238 if ($data) { |
238 if ($data) { |
239 if ($etag === null) { |
239 if ($etag === null) { |
240 $etag = $cache->load($cacheId.'_etag'); |
240 $etag = $cache->load($cacheId.'_etag'); |
241 } |
241 } |
242 if ($lastModified === null) { |
242 if ($lastModified === null) { |
243 $lastModified = $cache->load($cacheId.'_lastmodified');; |
243 $lastModified = $cache->load($cacheId.'_lastmodified'); |
244 } |
244 } |
245 if ($etag) { |
245 if ($etag) { |
246 $client->setHeaders('If-None-Match', $etag); |
246 $client->setHeaders('If-None-Match', $etag); |
247 } |
247 } |
248 if ($lastModified) { |
248 if ($lastModified) { |
264 } |
264 } |
265 if ($response->getHeader('Last-Modified')) { |
265 if ($response->getHeader('Last-Modified')) { |
266 $cache->save($response->getHeader('Last-Modified'), $cacheId.'_lastmodified'); |
266 $cache->save($response->getHeader('Last-Modified'), $cacheId.'_lastmodified'); |
267 } |
267 } |
268 } |
268 } |
|
269 if (empty($responseXml)) { |
|
270 require_once 'Zend/Feed/Exception.php'; |
|
271 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); |
|
272 } |
269 return self::importString($responseXml); |
273 return self::importString($responseXml); |
270 } elseif ($cache) { |
274 } elseif ($cache) { |
271 $data = $cache->load($cacheId); |
275 $data = $cache->load($cacheId); |
272 if ($data !== false) { |
276 if ($data !== false) { |
273 return self::importString($data); |
277 return self::importString($data); |
277 require_once 'Zend/Feed/Exception.php'; |
281 require_once 'Zend/Feed/Exception.php'; |
278 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); |
282 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); |
279 } |
283 } |
280 $responseXml = $response->getBody(); |
284 $responseXml = $response->getBody(); |
281 $cache->save($responseXml, $cacheId); |
285 $cache->save($responseXml, $cacheId); |
|
286 if (empty($responseXml)) { |
|
287 require_once 'Zend/Feed/Exception.php'; |
|
288 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); |
|
289 } |
282 return self::importString($responseXml); |
290 return self::importString($responseXml); |
283 } else { |
291 } else { |
284 $response = $client->request('GET'); |
292 $response = $client->request('GET'); |
285 if ($response->getStatus() !== 200) { |
293 if ($response->getStatus() !== 200) { |
286 require_once 'Zend/Feed/Exception.php'; |
294 require_once 'Zend/Feed/Exception.php'; |
287 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); |
295 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus()); |
288 } |
296 } |
289 $reader = self::importString($response->getBody()); |
297 $responseXml = $response->getBody(); |
|
298 if (empty($responseXml)) { |
|
299 require_once 'Zend/Feed/Exception.php'; |
|
300 throw new Zend_Feed_Exception('Feed failed to load, got empty response body'); |
|
301 } |
|
302 $reader = self::importString($responseXml); |
290 $reader->setOriginalSourceUri($uri); |
303 $reader->setOriginalSourceUri($uri); |
291 return $reader; |
304 return $reader; |
292 } |
305 } |
293 } |
306 } |
294 |
307 |
319 * @return Zend_Feed_Reader_FeedInterface |
332 * @return Zend_Feed_Reader_FeedInterface |
320 */ |
333 */ |
321 public static function importString($string) |
334 public static function importString($string) |
322 { |
335 { |
323 $libxml_errflag = libxml_use_internal_errors(true); |
336 $libxml_errflag = libxml_use_internal_errors(true); |
|
337 $oldValue = libxml_disable_entity_loader(true); |
324 $dom = new DOMDocument; |
338 $dom = new DOMDocument; |
325 $status = $dom->loadXML($string); |
339 $status = $dom->loadXML($string); |
|
340 foreach ($dom->childNodes as $child) { |
|
341 if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { |
|
342 require_once 'Zend/Feed/Exception.php'; |
|
343 throw new Zend_Feed_Exception( |
|
344 'Invalid XML: Detected use of illegal DOCTYPE' |
|
345 ); |
|
346 } |
|
347 } |
|
348 libxml_disable_entity_loader($oldValue); |
326 libxml_use_internal_errors($libxml_errflag); |
349 libxml_use_internal_errors($libxml_errflag); |
327 |
350 |
328 if (!$status) { |
351 if (!$status) { |
329 // Build error message |
352 // Build error message |
330 $error = libxml_get_last_error(); |
353 $error = libxml_get_last_error(); |
391 require_once 'Zend/Feed/Exception.php'; |
414 require_once 'Zend/Feed/Exception.php'; |
392 throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus()); |
415 throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus()); |
393 } |
416 } |
394 $responseHtml = $response->getBody(); |
417 $responseHtml = $response->getBody(); |
395 $libxml_errflag = libxml_use_internal_errors(true); |
418 $libxml_errflag = libxml_use_internal_errors(true); |
|
419 $oldValue = libxml_disable_entity_loader(true); |
396 $dom = new DOMDocument; |
420 $dom = new DOMDocument; |
397 $status = $dom->loadHTML($responseHtml); |
421 $status = $dom->loadHTML($responseHtml); |
|
422 libxml_disable_entity_loader($oldValue); |
398 libxml_use_internal_errors($libxml_errflag); |
423 libxml_use_internal_errors($libxml_errflag); |
399 if (!$status) { |
424 if (!$status) { |
400 // Build error message |
425 // Build error message |
401 $error = libxml_get_last_error(); |
426 $error = libxml_get_last_error(); |
402 if ($error && $error->message) { |
427 if ($error && $error->message) { |
416 |
441 |
417 /** |
442 /** |
418 * Detect the feed type of the provided feed |
443 * Detect the feed type of the provided feed |
419 * |
444 * |
420 * @param Zend_Feed_Abstract|DOMDocument|string $feed |
445 * @param Zend_Feed_Abstract|DOMDocument|string $feed |
|
446 * @param bool $specOnly |
421 * @return string |
447 * @return string |
|
448 * @throws Zend_Feed_Exception |
422 */ |
449 */ |
423 public static function detectType($feed, $specOnly = false) |
450 public static function detectType($feed, $specOnly = false) |
424 { |
451 { |
425 if ($feed instanceof Zend_Feed_Reader_FeedInterface) { |
452 if ($feed instanceof Zend_Feed_Reader_FeedInterface) { |
426 $dom = $feed->getDomDocument(); |
453 $dom = $feed->getDomDocument(); |
427 } elseif($feed instanceof DOMDocument) { |
454 } elseif($feed instanceof DOMDocument) { |
428 $dom = $feed; |
455 $dom = $feed; |
429 } elseif(is_string($feed) && !empty($feed)) { |
456 } elseif(is_string($feed) && !empty($feed)) { |
430 @ini_set('track_errors', 1); |
457 @ini_set('track_errors', 1); |
|
458 $oldValue = libxml_disable_entity_loader(true); |
431 $dom = new DOMDocument; |
459 $dom = new DOMDocument; |
432 $status = @$dom->loadXML($feed); |
460 $status = @$dom->loadXML($feed); |
|
461 foreach ($dom->childNodes as $child) { |
|
462 if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { |
|
463 require_once 'Zend/Feed/Exception.php'; |
|
464 throw new Zend_Feed_Exception( |
|
465 'Invalid XML: Detected use of illegal DOCTYPE' |
|
466 ); |
|
467 } |
|
468 } |
|
469 libxml_disable_entity_loader($oldValue); |
433 @ini_restore('track_errors'); |
470 @ini_restore('track_errors'); |
434 if (!$status) { |
471 if (!$status) { |
435 if (!isset($php_errormsg)) { |
472 if (!isset($php_errormsg)) { |
436 if (function_exists('xdebug_is_enabled')) { |
473 if (function_exists('xdebug_is_enabled')) { |
437 $php_errormsg = '(error message not available, when XDebug is running)'; |
474 $php_errormsg = '(error message not available, when XDebug is running)'; |
508 $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10); |
545 $xpath->registerNamespace('atom', self::NAMESPACE_ATOM_10); |
509 |
546 |
510 if ($xpath->query('//atom:feed')->length) { |
547 if ($xpath->query('//atom:feed')->length) { |
511 return self::TYPE_ATOM_10; |
548 return self::TYPE_ATOM_10; |
512 } |
549 } |
513 |
550 |
514 if ($xpath->query('//atom:entry')->length) { |
551 if ($xpath->query('//atom:entry')->length) { |
515 if ($specOnly == true) { |
552 if ($specOnly == true) { |
516 return self::TYPE_ATOM_10; |
553 return self::TYPE_ATOM_10; |
517 } else { |
554 } else { |
518 return self::TYPE_ATOM_10_ENTRY; |
555 return self::TYPE_ATOM_10_ENTRY; |
696 self::registerExtension('Slash'); |
733 self::registerExtension('Slash'); |
697 self::registerExtension('WellFormedWeb'); |
734 self::registerExtension('WellFormedWeb'); |
698 self::registerExtension('Thread'); |
735 self::registerExtension('Thread'); |
699 self::registerExtension('Podcast'); |
736 self::registerExtension('Podcast'); |
700 } |
737 } |
701 |
738 |
702 /** |
739 /** |
703 * Utility method to apply array_unique operation to a multidimensional |
740 * Utility method to apply array_unique operation to a multidimensional |
704 * array. |
741 * array. |
705 * |
742 * |
706 * @param array |
743 * @param array |