Changeset 21644
- Timestamp:
- 08/28/2012 05:24:33 PM (13 years ago)
- Location:
- trunk/wp-includes
- Files:
-
- 42 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/class-feed.php
r17928 r21644 11 11 * @access public 12 12 */ 13 function create($location, $filename, $extension) {13 public static function create($location, $filename, $extension) { 14 14 return new WP_Feed_Cache_Transient($location, $filename, $extension); 15 15 } -
trunk/wp-includes/class-simplepie.php
r20715 r21644 1 1 <?php 2 2 if ( ! class_exists( 'SimplePie' ) ) : 3 4 // Load classes we will need. 5 require ABSPATH . WPINC . '/SimplePie/Misc.php'; 6 require ABSPATH . WPINC . '/SimplePie/Cache.php'; 7 require ABSPATH . WPINC . '/SimplePie/File.php'; 8 require ABSPATH . WPINC . '/SimplePie/Sanitize.php'; 9 require ABSPATH . WPINC . '/SimplePie/Registry.php'; 10 require ABSPATH . WPINC . '/SimplePie/IRI.php'; 11 require ABSPATH . WPINC . '/SimplePie/Locator.php'; 12 require ABSPATH . WPINC . '/SimplePie/Content/Type/Sniffer.php'; 13 require ABSPATH . WPINC . '/SimplePie/XML/Declaration/Parser.php'; 14 require ABSPATH . WPINC . '/SimplePie/Parser.php'; 15 require ABSPATH . WPINC . '/SimplePie/Item.php'; 16 require ABSPATH . WPINC . '/SimplePie/Parse/Date.php'; 17 require ABSPATH . WPINC . '/SimplePie/Author.php'; 18 19 /** 20 * WordPress autoloader for SimplePie. 21 * 22 * @since 3.5.0 23 */ 24 function wp_simplepie_autoload( $class ) { 25 if ( 0 !== strpos( $class, 'SimplePie_' ) ) 26 return; 27 28 $file = dirname( __FILE__ ) . '/' . str_replace( '_', '/', $class ) . '.php'; 29 include $file; 30 } 31 32 if ( function_exists( 'spl_autoload_register' ) ) { 33 /** 34 * We autoload classes we may not need. 35 * 36 * If SPL is disabled, we load all of SimplePie manually. 37 * 38 * Core.php is not loaded manually, because SimplePie_Core (a deprecated class) 39 * was never included in WordPress core. 40 */ 41 spl_autoload_register( 'wp_simplepie_autoload' ); 42 } else { 43 require ABSPATH . WPINC . '/SimplePie/Cache/Base.php'; 44 require ABSPATH . WPINC . '/SimplePie/Cache/DB.php'; 45 require ABSPATH . WPINC . '/SimplePie/Cache/File.php'; 46 require ABSPATH . WPINC . '/SimplePie/Cache/Memcache.php'; 47 require ABSPATH . WPINC . '/SimplePie/Cache/MySQL.php'; 48 require ABSPATH . WPINC . '/SimplePie/Caption.php'; 49 require ABSPATH . WPINC . '/SimplePie/Category.php'; 50 require ABSPATH . WPINC . '/SimplePie/Copyright.php'; 51 require ABSPATH . WPINC . '/SimplePie/Credit.php'; 52 require ABSPATH . WPINC . '/SimplePie/Decode/HTML/Entities.php'; 53 require ABSPATH . WPINC . '/SimplePie/Enclosure.php'; 54 require ABSPATH . WPINC . '/SimplePie/gzdecode.php'; 55 require ABSPATH . WPINC . '/SimplePie/HTTP/Parser.php'; 56 require ABSPATH . WPINC . '/SimplePie/Net/IPv6.php'; 57 require ABSPATH . WPINC . '/SimplePie/Rating.php'; 58 require ABSPATH . WPINC . '/SimplePie/Restriction.php'; 59 require ABSPATH . WPINC . '/SimplePie/Source.php'; 60 } 61 3 62 /** 4 63 * SimplePie … … 7 66 * Takes the hard work out of managing a complete RSS/Atom solution. 8 67 * 9 * Copyright (c) 2004-201 1, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors68 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors 10 69 * All rights reserved. 11 70 * … … 35 94 * 36 95 * @package SimplePie 37 * @version 1. 2.138 * @copyright 2004-201 1Ryan Parman, Geoffrey Sneddon, Ryan McCue96 * @version 1.3 97 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue 39 98 * @author Ryan Parman 40 99 * @author Geoffrey Sneddon 41 100 * @author Ryan McCue 42 101 * @link http://simplepie.org/ SimplePie 43 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums44 102 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 45 * @todo phpDoc comments46 103 */ 47 104 … … 54 111 * SimplePie Version 55 112 */ 56 define('SIMPLEPIE_VERSION', '1. 2.1');113 define('SIMPLEPIE_VERSION', '1.3'); 57 114 58 115 /** 59 116 * SimplePie Build 60 */ 61 define('SIMPLEPIE_BUILD', '20111015034325'); 117 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc) 118 */ 119 define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build())); 62 120 63 121 /** … … 336 394 337 395 /** 338 * Wrong Media RSS Namespace 396 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec. 339 397 */ 340 398 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss'); 341 399 342 400 /** 401 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5. 402 */ 403 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss'); 404 405 /** 406 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace. 407 */ 408 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/'); 409 410 /** 411 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace. 412 */ 413 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss'); 414 415 /** 416 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL. 417 */ 418 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/'); 419 420 /** 343 421 * iTunes RSS Namespace 344 422 */ … … 356 434 357 435 /** 358 * Whether we're running on PHP5359 */360 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));361 362 /**363 436 * No file source 364 437 */ … … 389 462 */ 390 463 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); 464 465 391 466 392 467 /** … … 394 469 * 395 470 * @package SimplePie 471 * @subpackage API 396 472 */ 397 473 class SimplePie … … 401 477 * @access private 402 478 */ 403 var$data = array();479 public $data = array(); 404 480 405 481 /** … … 407 483 * @access private 408 484 */ 409 var$error;485 public $error; 410 486 411 487 /** … … 414 490 * @access private 415 491 */ 416 var$sanitize;492 public $sanitize; 417 493 418 494 /** … … 421 497 * @access private 422 498 */ 423 var$useragent = SIMPLEPIE_USERAGENT;499 public $useragent = SIMPLEPIE_USERAGENT; 424 500 425 501 /** … … 428 504 * @access private 429 505 */ 430 var$feed_url;506 public $feed_url; 431 507 432 508 /** … … 435 511 * @access private 436 512 */ 437 var$file;513 public $file; 438 514 439 515 /** … … 442 518 * @access private 443 519 */ 444 var$raw_data;520 public $raw_data; 445 521 446 522 /** … … 449 525 * @access private 450 526 */ 451 var$timeout = 10;527 public $timeout = 10; 452 528 453 529 /** … … 457 533 * @access private 458 534 */ 459 var$force_fsockopen = false;535 public $force_fsockopen = false; 460 536 461 537 /** … … 465 541 * @access private 466 542 */ 467 var $force_feed = false; 468 469 /** 470 * @var bool Enable/Disable XML dump 471 * @see SimplePie::enable_xml_dump() 472 * @access private 473 */ 474 var $xml_dump = false; 543 public $force_feed = false; 475 544 476 545 /** … … 479 548 * @access private 480 549 */ 481 var$cache = true;550 public $cache = true; 482 551 483 552 /** … … 486 555 * @access private 487 556 */ 488 var$cache_duration = 3600;557 public $cache_duration = 3600; 489 558 490 559 /** … … 493 562 * @access private 494 563 */ 495 var$autodiscovery_cache_duration = 604800; // 7 Days.564 public $autodiscovery_cache_duration = 604800; // 7 Days. 496 565 497 566 /** … … 500 569 * @access private 501 570 */ 502 var$cache_location = './cache';571 public $cache_location = './cache'; 503 572 504 573 /** … … 507 576 * @access private 508 577 */ 509 var$cache_name_function = 'md5';578 public $cache_name_function = 'md5'; 510 579 511 580 /** … … 514 583 * @access private 515 584 */ 516 var$order_by_date = true;585 public $order_by_date = true; 517 586 518 587 /** … … 522 591 * @access private 523 592 */ 524 var$input_encoding = false;593 public $input_encoding = false; 525 594 526 595 /** … … 529 598 * @access private 530 599 */ 531 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; 532 533 /** 534 * @var string Class used for caching feeds 535 * @see SimplePie::set_cache_class() 536 * @access private 537 */ 538 var $cache_class = 'SimplePie_Cache'; 539 540 /** 541 * @var string Class used for locating feeds 542 * @see SimplePie::set_locator_class() 543 * @access private 544 */ 545 var $locator_class = 'SimplePie_Locator'; 546 547 /** 548 * @var string Class used for parsing feeds 549 * @see SimplePie::set_parser_class() 550 * @access private 551 */ 552 var $parser_class = 'SimplePie_Parser'; 553 554 /** 555 * @var string Class used for fetching feeds 556 * @see SimplePie::set_file_class() 557 * @access private 558 */ 559 var $file_class = 'SimplePie_File'; 560 561 /** 562 * @var string Class used for items 563 * @see SimplePie::set_item_class() 564 * @access private 565 */ 566 var $item_class = 'SimplePie_Item'; 567 568 /** 569 * @var string Class used for authors 570 * @see SimplePie::set_author_class() 571 * @access private 572 */ 573 var $author_class = 'SimplePie_Author'; 574 575 /** 576 * @var string Class used for categories 577 * @see SimplePie::set_category_class() 578 * @access private 579 */ 580 var $category_class = 'SimplePie_Category'; 581 582 /** 583 * @var string Class used for enclosures 584 * @see SimplePie::set_enclosures_class() 585 * @access private 586 */ 587 var $enclosure_class = 'SimplePie_Enclosure'; 588 589 /** 590 * @var string Class used for Media RSS <media:text> captions 591 * @see SimplePie::set_caption_class() 592 * @access private 593 */ 594 var $caption_class = 'SimplePie_Caption'; 595 596 /** 597 * @var string Class used for Media RSS <media:copyright> 598 * @see SimplePie::set_copyright_class() 599 * @access private 600 */ 601 var $copyright_class = 'SimplePie_Copyright'; 602 603 /** 604 * @var string Class used for Media RSS <media:credit> 605 * @see SimplePie::set_credit_class() 606 * @access private 607 */ 608 var $credit_class = 'SimplePie_Credit'; 609 610 /** 611 * @var string Class used for Media RSS <media:rating> 612 * @see SimplePie::set_rating_class() 613 * @access private 614 */ 615 var $rating_class = 'SimplePie_Rating'; 616 617 /** 618 * @var string Class used for Media RSS <media:restriction> 619 * @see SimplePie::set_restriction_class() 620 * @access private 621 */ 622 var $restriction_class = 'SimplePie_Restriction'; 623 624 /** 625 * @var string Class used for content-type sniffing 626 * @see SimplePie::set_content_type_sniffer_class() 627 * @access private 628 */ 629 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 630 631 /** 632 * @var string Class used for item sources. 633 * @see SimplePie::set_source_class() 634 * @access private 635 */ 636 var $source_class = 'SimplePie_Source'; 637 638 /** 639 * @var mixed Set javascript query string parameter (false, or 640 * anything type-cast to false, disables this feature) 641 * @see SimplePie::set_javascript() 642 * @access private 643 */ 644 var $javascript = 'js'; 600 public $autodiscovery = SIMPLEPIE_LOCATOR_ALL; 601 602 /** 603 * Class registry object 604 * 605 * @var SimplePie_Registry 606 */ 607 public $registry; 645 608 646 609 /** … … 649 612 * @access private 650 613 */ 651 var$max_checked_feeds = 10;614 public $max_checked_feeds = 10; 652 615 653 616 /** … … 656 619 * @access private 657 620 */ 658 var $all_discovered_feeds = array(); 659 660 /** 661 * @var string Web-accessible path to the handler_favicon.php file. 662 * @see SimplePie::set_favicon_handler() 663 * @access private 664 */ 665 var $favicon_handler = ''; 621 public $all_discovered_feeds = array(); 666 622 667 623 /** … … 670 626 * @access private 671 627 */ 672 var$image_handler = '';628 public $image_handler = ''; 673 629 674 630 /** … … 677 633 * @access private 678 634 */ 679 var$multifeed_url = array();635 public $multifeed_url = array(); 680 636 681 637 /** … … 683 639 * @access private 684 640 */ 685 var$multifeed_objects = array();641 public $multifeed_objects = array(); 686 642 687 643 /** … … 690 646 * @access private 691 647 */ 692 var$config_settings = null;648 public $config_settings = null; 693 649 694 650 /** … … 697 653 * @access private 698 654 */ 699 var$item_limit = 0;655 public $item_limit = 0; 700 656 701 657 /** … … 704 660 * @access private 705 661 */ 706 var$strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');662 public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 707 663 708 664 /** … … 711 667 * @access private 712 668 */ 713 var$strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');669 public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 714 670 715 671 /** 716 672 * The SimplePie class contains feed level data and options 717 673 * 718 * There are two ways that you can create a new SimplePie object. The first 719 * is by passing a feed URL as a parameter to the SimplePie constructor 720 * (as well as optionally setting the cache location and cache expiry). This 721 * will initialise the whole feed with all of the default settings, and you 722 * can begin accessing methods and properties immediately. 723 * 724 * The second way is to create the SimplePie object with no parameters 725 * at all. This will enable you to set configuration options. After setting 674 * To use SimplePie, create the SimplePie object with no parameters. You can 675 * then set configuration options using the provided methods. After setting 726 676 * them, you must initialise the feed using $feed->init(). At that point the 727 * object's methods and properties will be available to you. This format is 728 * what is used throughout this documentation. 729 * 730 * @access public 677 * object's methods and properties will be available to you. 678 * 679 * Previously, it was possible to pass in the feed URL along with cache 680 * options directly into the constructor. This has been removed as of 1.3 as 681 * it caused a lot of confusion. 682 * 731 683 * @since 1.0 Preview Release 732 * @param string $feed_url This is the URL you want to parse. 733 * @param string $cache_location This is where you want the cache to be stored. 734 * @param int $cache_duration This is the number of seconds that you want to store the cache file for. 735 */ 736 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) 737 { 684 */ 685 public function __construct() 686 { 687 if (version_compare(PHP_VERSION, '5.2', '<')) 688 { 689 trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.'); 690 die(); 691 } 692 738 693 // Other objects, instances created here so we can set options on them 739 $this->sanitize =& new SimplePie_Sanitize; 740 741 // Set options if they're passed to the constructor 742 if ($cache_location !== null) 743 { 744 $this->set_cache_location($cache_location); 745 } 746 747 if ($cache_duration !== null) 748 { 749 $this->set_cache_duration($cache_duration); 750 } 751 752 // Only init the script if we're passed a feed URL 753 if ($feed_url !== null) 754 { 755 $this->set_feed_url($feed_url); 756 $this->init(); 694 $this->sanitize = new SimplePie_Sanitize(); 695 $this->registry = new SimplePie_Registry(); 696 697 if (func_num_args() > 0) 698 { 699 trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.'); 757 700 } 758 701 } … … 761 704 * Used for converting object to a string 762 705 */ 763 function __toString()706 public function __toString() 764 707 { 765 708 return md5(serialize($this->data)); … … 769 712 * Remove items that link back to this before destroying this object 770 713 */ 771 function __destruct()714 public function __destruct() 772 715 { 773 716 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) … … 793 736 794 737 /** 795 * Force the given data/URL to be treated as a feed no matter what it 796 * appears like 797 * 798 * @access public 738 * Force the given data/URL to be treated as a feed 739 * 740 * This tells SimplePie to ignore the content-type provided by the server. 741 * Be careful when using this option, as it will also disable autodiscovery. 742 * 799 743 * @since 1.1 800 744 * @param bool $enable Force the given data/URL to be treated as a feed 801 745 */ 802 function force_feed($enable = false)746 public function force_feed($enable = false) 803 747 { 804 748 $this->force_feed = (bool) $enable; … … 806 750 807 751 /** 808 * This is the URL of the feed you want to parse.752 * Set the URL of the feed you want to parse 809 753 * 810 754 * This allows you to enter the URL of the feed you want to parse, or the … … 816 760 * additional processing and resources. 817 761 * 818 * @access public819 762 * @since 1.0 Preview Release 820 * @param mixed $url This is the URL (or array of URLs) that you want to parse. 821 * @see SimplePie::set_raw_data() 822 */ 823 function set_feed_url($url) 824 { 763 * @see set_raw_data() 764 * @param string|array $url This is the URL (or array of URLs) that you want to parse. 765 */ 766 public function set_feed_url($url) 767 { 768 $this->multifeed_url = array(); 825 769 if (is_array($url)) 826 770 { 827 $this->multifeed_url = array();828 771 foreach ($url as $value) 829 772 { 830 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);773 $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1)); 831 774 } 832 775 } 833 776 else 834 777 { 835 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); 836 } 837 } 838 839 /** 840 * Provides an instance of SimplePie_File to use as a feed 841 * 842 * @access public 843 * @param object &$file Instance of SimplePie_File (or subclass) 778 $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1)); 779 } 780 } 781 782 /** 783 * Set an instance of {@see SimplePie_File} to use as a feed 784 * 785 * @param SimplePie_File &$file 844 786 * @return bool True on success, false on failure 845 787 */ 846 function set_file(&$file)847 { 848 if ( is_a($file, 'SimplePie_File'))788 public function set_file(&$file) 789 { 790 if ($file instanceof SimplePie_File) 849 791 { 850 792 $this->feed_url = $file->url; … … 856 798 857 799 /** 800 * Set the raw XML data to parse 801 * 858 802 * Allows you to use a string of RSS/Atom data instead of a remote feed. 859 803 * … … 862 806 * takes precedence. 863 807 * 864 * @access public865 808 * @since 1.0 Beta 3 866 809 * @param string $data RSS or Atom data as a string. 867 * @see SimplePie::set_feed_url()868 */ 869 function set_raw_data($data)810 * @see set_feed_url() 811 */ 812 public function set_raw_data($data) 870 813 { 871 814 $this->raw_data = $data; … … 873 816 874 817 /** 875 * Allows you to override the default timeout for fetching remote feeds.818 * Set the the default timeout for fetching remote feeds 876 819 * 877 820 * This allows you to change the maximum time the feed's server to respond 878 821 * and send the feed back. 879 822 * 880 * @access public881 823 * @since 1.0 Beta 3 882 824 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. 883 825 */ 884 function set_timeout($timeout = 10)826 public function set_timeout($timeout = 10) 885 827 { 886 828 $this->timeout = (int) $timeout; … … 888 830 889 831 /** 890 * Forces SimplePie to use fsockopen() instead of the preferred cURL 891 * functions. 892 * 893 * @access public 832 * Force SimplePie to use fsockopen() instead of cURL 833 * 894 834 * @since 1.0 Beta 3 895 835 * @param bool $enable Force fsockopen() to be used 896 836 */ 897 function force_fsockopen($enable = false)837 public function force_fsockopen($enable = false) 898 838 { 899 839 $this->force_fsockopen = (bool) $enable; … … 901 841 902 842 /** 903 * Outputs the raw XML content of the feed, after it has gone through 904 * SimplePie's filters. 905 * 906 * Used only for debugging, this function will output the XML content as 907 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up 908 * before trying to parse it. Many parts of the feed are re-written in 909 * memory, and in the end, you have a parsable feed. XML dump shows you the 910 * actual XML that SimplePie tries to parse, which may or may not be very 911 * different from the original feed. 912 * 913 * @access public 914 * @since 1.0 Preview Release 915 * @param bool $enable Enable XML dump 916 */ 917 function enable_xml_dump($enable = false) 918 { 919 $this->xml_dump = (bool) $enable; 920 } 921 922 /** 923 * Enables/disables caching in SimplePie. 843 * Enable/disable caching in SimplePie. 924 844 * 925 845 * This option allows you to disable caching all-together in SimplePie. 926 846 * However, disabling the cache can lead to longer load times. 927 847 * 928 * @access public929 848 * @since 1.0 Preview Release 930 849 * @param bool $enable Enable caching 931 850 */ 932 function enable_cache($enable = true)851 public function enable_cache($enable = true) 933 852 { 934 853 $this->cache = (bool) $enable; … … 936 855 937 856 /** 938 * Set the length of time (in seconds) that the contents of a feed 939 * will be cached. 940 * 941 * @access public 942 * @param int $seconds The feed content cache duration. 943 */ 944 function set_cache_duration($seconds = 3600) 857 * Set the length of time (in seconds) that the contents of a feed will be 858 * cached 859 * 860 * @param int $seconds The feed content cache duration 861 */ 862 public function set_cache_duration($seconds = 3600) 945 863 { 946 864 $this->cache_duration = (int) $seconds; … … 948 866 949 867 /** 950 * Set the length of time (in seconds) that the autodiscovered feed 951 * URL will be cached. 952 * 953 * @access public 868 * Set the length of time (in seconds) that the autodiscovered feed URL will 869 * be cached 870 * 954 871 * @param int $seconds The autodiscovered feed URL cache duration. 955 872 */ 956 function set_autodiscovery_cache_duration($seconds = 604800)873 public function set_autodiscovery_cache_duration($seconds = 604800) 957 874 { 958 875 $this->autodiscovery_cache_duration = (int) $seconds; … … 960 877 961 878 /** 962 * Set the file system location where the cached files should be stored. 963 * 964 * @access public 879 * Set the file system location where the cached files should be stored 880 * 965 881 * @param string $location The file system location. 966 882 */ 967 function set_cache_location($location = './cache')883 public function set_cache_location($location = './cache') 968 884 { 969 885 $this->cache_location = (string) $location; … … 971 887 972 888 /** 973 * Determines whether feed items should be sorted into reverse chronological order. 974 * 975 * @access public 889 * Set whether feed items should be sorted into reverse chronological order 890 * 976 891 * @param bool $enable Sort as reverse chronological order. 977 892 */ 978 function enable_order_by_date($enable = true)893 public function enable_order_by_date($enable = true) 979 894 { 980 895 $this->order_by_date = (bool) $enable; … … 982 897 983 898 /** 984 * Allows you to override the character encoding reported by the feed. 985 * 986 * @access public 987 * @param string $encoding Character encoding. 988 */ 989 function set_input_encoding($encoding = false) 899 * Set the character encoding used to parse the feed 900 * 901 * This overrides the encoding reported by the feed, however it will fall 902 * back to the normal encoding detection if the override fails 903 * 904 * @param string $encoding Character encoding 905 */ 906 public function set_input_encoding($encoding = false) 990 907 { 991 908 if ($encoding) … … 1002 919 * Set how much feed autodiscovery to do 1003 920 * 1004 * @access public1005 921 * @see SIMPLEPIE_LOCATOR_NONE 1006 922 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY … … 1010 926 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY 1011 927 * @see SIMPLEPIE_LOCATOR_ALL 1012 * @param int $level Feed Autodiscovery Level (level can be a 1013 * combination of the above constants, see bitwise OR operator) 1014 */ 1015 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) 928 * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator) 929 */ 930 public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) 1016 931 { 1017 932 $this->autodiscovery = (int) $level; … … 1019 934 1020 935 /** 1021 * Allows you to change which class SimplePie uses for caching. 936 * Get the class registry 937 * 938 * Use this to override SimplePie's default classes 939 * @see SimplePie_Registry 940 * @return SimplePie_Registry 941 */ 942 public function &get_registry() 943 { 944 return $this->registry; 945 } 946 947 /**#@+ 1022 948 * Useful when you are overloading or extending SimplePie's default classes. 1023 949 * 1024 * @access public 1025 * @param string $class Name of custom class. 1026 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 950 * @deprecated Use {@see get_registry()} instead 1027 951 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1028 */ 1029 function set_cache_class($class = 'SimplePie_Cache') 1030 { 1031 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) 1032 { 1033 $this->cache_class = $class; 1034 return true; 1035 } 1036 return false; 1037 } 1038 1039 /** 1040 * Allows you to change which class SimplePie uses for auto-discovery. 1041 * Useful when you are overloading or extending SimplePie's default classes. 1042 * 1043 * @access public 1044 * @param string $class Name of custom class. 1045 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1046 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1047 */ 1048 function set_locator_class($class = 'SimplePie_Locator') 1049 { 1050 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) 1051 { 1052 $this->locator_class = $class; 1053 return true; 1054 } 1055 return false; 1056 } 1057 1058 /** 1059 * Allows you to change which class SimplePie uses for XML parsing. 1060 * Useful when you are overloading or extending SimplePie's default classes. 1061 * 1062 * @access public 1063 * @param string $class Name of custom class. 1064 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1065 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1066 */ 1067 function set_parser_class($class = 'SimplePie_Parser') 1068 { 1069 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) 1070 { 1071 $this->parser_class = $class; 1072 return true; 1073 } 1074 return false; 1075 } 1076 1077 /** 1078 * Allows you to change which class SimplePie uses for remote file fetching. 1079 * Useful when you are overloading or extending SimplePie's default classes. 1080 * 1081 * @access public 1082 * @param string $class Name of custom class. 1083 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1084 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1085 */ 1086 function set_file_class($class = 'SimplePie_File') 1087 { 1088 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) 1089 { 1090 $this->file_class = $class; 1091 return true; 1092 } 1093 return false; 1094 } 1095 1096 /** 1097 * Allows you to change which class SimplePie uses for data sanitization. 1098 * Useful when you are overloading or extending SimplePie's default classes. 1099 * 1100 * @access public 1101 * @param string $class Name of custom class. 1102 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1103 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1104 */ 1105 function set_sanitize_class($class = 'SimplePie_Sanitize') 1106 { 1107 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) 1108 { 1109 $this->sanitize =& new $class; 1110 return true; 1111 } 1112 return false; 1113 } 1114 1115 /** 1116 * Allows you to change which class SimplePie uses for handling feed items. 1117 * Useful when you are overloading or extending SimplePie's default classes. 1118 * 1119 * @access public 1120 * @param string $class Name of custom class. 1121 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1122 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1123 */ 1124 function set_item_class($class = 'SimplePie_Item') 1125 { 1126 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) 1127 { 1128 $this->item_class = $class; 1129 return true; 1130 } 1131 return false; 1132 } 1133 1134 /** 1135 * Allows you to change which class SimplePie uses for handling author data. 1136 * Useful when you are overloading or extending SimplePie's default classes. 1137 * 1138 * @access public 1139 * @param string $class Name of custom class. 1140 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1141 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1142 */ 1143 function set_author_class($class = 'SimplePie_Author') 1144 { 1145 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) 1146 { 1147 $this->author_class = $class; 1148 return true; 1149 } 1150 return false; 1151 } 1152 1153 /** 1154 * Allows you to change which class SimplePie uses for handling category data. 1155 * Useful when you are overloading or extending SimplePie's default classes. 1156 * 1157 * @access public 1158 * @param string $class Name of custom class. 1159 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1160 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1161 */ 1162 function set_category_class($class = 'SimplePie_Category') 1163 { 1164 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) 1165 { 1166 $this->category_class = $class; 1167 return true; 1168 } 1169 return false; 1170 } 1171 1172 /** 1173 * Allows you to change which class SimplePie uses for feed enclosures. 1174 * Useful when you are overloading or extending SimplePie's default classes. 1175 * 1176 * @access public 1177 * @param string $class Name of custom class. 1178 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1179 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1180 */ 1181 function set_enclosure_class($class = 'SimplePie_Enclosure') 1182 { 1183 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) 1184 { 1185 $this->enclosure_class = $class; 1186 return true; 1187 } 1188 return false; 1189 } 1190 1191 /** 1192 * Allows you to change which class SimplePie uses for <media:text> captions 1193 * Useful when you are overloading or extending SimplePie's default classes. 1194 * 1195 * @access public 1196 * @param string $class Name of custom class. 1197 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1198 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1199 */ 1200 function set_caption_class($class = 'SimplePie_Caption') 1201 { 1202 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) 1203 { 1204 $this->caption_class = $class; 1205 return true; 1206 } 1207 return false; 1208 } 1209 1210 /** 1211 * Allows you to change which class SimplePie uses for <media:copyright> 1212 * Useful when you are overloading or extending SimplePie's default classes. 1213 * 1214 * @access public 1215 * @param string $class Name of custom class. 1216 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1217 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1218 */ 1219 function set_copyright_class($class = 'SimplePie_Copyright') 1220 { 1221 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) 1222 { 1223 $this->copyright_class = $class; 1224 return true; 1225 } 1226 return false; 1227 } 1228 1229 /** 1230 * Allows you to change which class SimplePie uses for <media:credit> 1231 * Useful when you are overloading or extending SimplePie's default classes. 1232 * 1233 * @access public 1234 * @param string $class Name of custom class. 1235 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1236 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1237 */ 1238 function set_credit_class($class = 'SimplePie_Credit') 1239 { 1240 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) 1241 { 1242 $this->credit_class = $class; 1243 return true; 1244 } 1245 return false; 1246 } 1247 1248 /** 1249 * Allows you to change which class SimplePie uses for <media:rating> 1250 * Useful when you are overloading or extending SimplePie's default classes. 1251 * 1252 * @access public 1253 * @param string $class Name of custom class. 1254 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1255 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1256 */ 1257 function set_rating_class($class = 'SimplePie_Rating') 1258 { 1259 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) 1260 { 1261 $this->rating_class = $class; 1262 return true; 1263 } 1264 return false; 1265 } 1266 1267 /** 1268 * Allows you to change which class SimplePie uses for <media:restriction> 1269 * Useful when you are overloading or extending SimplePie's default classes. 1270 * 1271 * @access public 1272 * @param string $class Name of custom class. 1273 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1274 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1275 */ 1276 function set_restriction_class($class = 'SimplePie_Restriction') 1277 { 1278 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) 1279 { 1280 $this->restriction_class = $class; 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 /** 1287 * Allows you to change which class SimplePie uses for content-type sniffing. 1288 * Useful when you are overloading or extending SimplePie's default classes. 1289 * 1290 * @access public 1291 * @param string $class Name of custom class. 1292 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1293 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1294 */ 1295 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') 1296 { 1297 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) 1298 { 1299 $this->content_type_sniffer_class = $class; 1300 return true; 1301 } 1302 return false; 1303 } 1304 1305 /** 1306 * Allows you to change which class SimplePie uses item sources. 1307 * Useful when you are overloading or extending SimplePie's default classes. 1308 * 1309 * @access public 1310 * @param string $class Name of custom class. 1311 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1312 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1313 */ 1314 function set_source_class($class = 'SimplePie_Source') 1315 { 1316 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) 1317 { 1318 $this->source_class = $class; 1319 return true; 1320 } 1321 return false; 1322 } 1323 1324 /** 1325 * Allows you to override the default user agent string. 1326 * 1327 * @access public 952 * @param string $class Name of custom class 953 * @return boolean True on success, false otherwise 954 */ 955 /** 956 * Set which class SimplePie uses for caching 957 */ 958 public function set_cache_class($class = 'SimplePie_Cache') 959 { 960 return $this->registry->register('Cache', $class, true); 961 } 962 963 /** 964 * Set which class SimplePie uses for auto-discovery 965 */ 966 public function set_locator_class($class = 'SimplePie_Locator') 967 { 968 return $this->registry->register('Locator', $class, true); 969 } 970 971 /** 972 * Set which class SimplePie uses for XML parsing 973 */ 974 public function set_parser_class($class = 'SimplePie_Parser') 975 { 976 return $this->registry->register('Parser', $class, true); 977 } 978 979 /** 980 * Set which class SimplePie uses for remote file fetching 981 */ 982 public function set_file_class($class = 'SimplePie_File') 983 { 984 return $this->registry->register('File', $class, true); 985 } 986 987 /** 988 * Set which class SimplePie uses for data sanitization 989 */ 990 public function set_sanitize_class($class = 'SimplePie_Sanitize') 991 { 992 return $this->registry->register('Sanitize', $class, true); 993 } 994 995 /** 996 * Set which class SimplePie uses for handling feed items 997 */ 998 public function set_item_class($class = 'SimplePie_Item') 999 { 1000 return $this->registry->register('Item', $class, true); 1001 } 1002 1003 /** 1004 * Set which class SimplePie uses for handling author data 1005 */ 1006 public function set_author_class($class = 'SimplePie_Author') 1007 { 1008 return $this->registry->register('Author', $class, true); 1009 } 1010 1011 /** 1012 * Set which class SimplePie uses for handling category data 1013 */ 1014 public function set_category_class($class = 'SimplePie_Category') 1015 { 1016 return $this->registry->register('Category', $class, true); 1017 } 1018 1019 /** 1020 * Set which class SimplePie uses for feed enclosures 1021 */ 1022 public function set_enclosure_class($class = 'SimplePie_Enclosure') 1023 { 1024 return $this->registry->register('Enclosure', $class, true); 1025 } 1026 1027 /** 1028 * Set which class SimplePie uses for `<media:text>` captions 1029 */ 1030 public function set_caption_class($class = 'SimplePie_Caption') 1031 { 1032 return $this->registry->register('Caption', $class, true); 1033 } 1034 1035 /** 1036 * Set which class SimplePie uses for `<media:copyright>` 1037 */ 1038 public function set_copyright_class($class = 'SimplePie_Copyright') 1039 { 1040 return $this->registry->register('Copyright', $class, true); 1041 } 1042 1043 /** 1044 * Set which class SimplePie uses for `<media:credit>` 1045 */ 1046 public function set_credit_class($class = 'SimplePie_Credit') 1047 { 1048 return $this->registry->register('Credit', $class, true); 1049 } 1050 1051 /** 1052 * Set which class SimplePie uses for `<media:rating>` 1053 */ 1054 public function set_rating_class($class = 'SimplePie_Rating') 1055 { 1056 return $this->registry->register('Rating', $class, true); 1057 } 1058 1059 /** 1060 * Set which class SimplePie uses for `<media:restriction>` 1061 */ 1062 public function set_restriction_class($class = 'SimplePie_Restriction') 1063 { 1064 return $this->registry->register('Restriction', $class, true); 1065 } 1066 1067 /** 1068 * Set which class SimplePie uses for content-type sniffing 1069 */ 1070 public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') 1071 { 1072 return $this->registry->register('Content_Type_Sniffer', $class, true); 1073 } 1074 1075 /** 1076 * Set which class SimplePie uses item sources 1077 */ 1078 public function set_source_class($class = 'SimplePie_Source') 1079 { 1080 return $this->registry->register('Source', $class, true); 1081 } 1082 /**#@-*/ 1083 1084 /** 1085 * Set the user agent string 1086 * 1328 1087 * @param string $ua New user agent string. 1329 1088 */ 1330 function set_useragent($ua = SIMPLEPIE_USERAGENT)1089 public function set_useragent($ua = SIMPLEPIE_USERAGENT) 1331 1090 { 1332 1091 $this->useragent = (string) $ua; … … 1336 1095 * Set callback function to create cache filename with 1337 1096 * 1338 * @access public1339 1097 * @param mixed $function Callback function 1340 1098 */ 1341 function set_cache_name_function($function = 'md5')1099 public function set_cache_name_function($function = 'md5') 1342 1100 { 1343 1101 if (is_callable($function)) … … 1348 1106 1349 1107 /** 1350 * Set javascript query string parameter 1351 * 1352 * @access public 1353 * @param mixed $get Javascript query string parameter 1354 */ 1355 function set_javascript($get = 'js') 1356 { 1357 if ($get) 1358 { 1359 $this->javascript = (string) $get; 1360 } 1361 else 1362 { 1363 $this->javascript = false; 1364 } 1365 } 1366 1367 /** 1368 * Set options to make SP as fast as possible. Forgoes a 1369 * substantial amount of data sanitization in favor of speed. 1370 * 1371 * @access public 1108 * Set options to make SP as fast as possible 1109 * 1110 * Forgoes a substantial amount of data sanitization in favor of speed. This 1111 * turns SimplePie into a dumb parser of feeds. 1112 * 1372 1113 * @param bool $set Whether to set them or not 1373 1114 */ 1374 function set_stupidly_fast($set = false)1115 public function set_stupidly_fast($set = false) 1375 1116 { 1376 1117 if ($set) … … 1388 1129 * Set maximum number of feeds to check with autodiscovery 1389 1130 * 1390 * @access public1391 1131 * @param int $max Maximum number of feeds to check 1392 1132 */ 1393 function set_max_checked_feeds($max = 10)1133 public function set_max_checked_feeds($max = 10) 1394 1134 { 1395 1135 $this->max_checked_feeds = (int) $max; 1396 1136 } 1397 1137 1398 function remove_div($enable = true)1138 public function remove_div($enable = true) 1399 1139 { 1400 1140 $this->sanitize->remove_div($enable); 1401 1141 } 1402 1142 1403 function strip_htmltags($tags = '', $encode = null)1143 public function strip_htmltags($tags = '', $encode = null) 1404 1144 { 1405 1145 if ($tags === '') … … 1414 1154 } 1415 1155 1416 function encode_instead_of_strip($enable = true)1156 public function encode_instead_of_strip($enable = true) 1417 1157 { 1418 1158 $this->sanitize->encode_instead_of_strip($enable); 1419 1159 } 1420 1160 1421 function strip_attributes($attribs = '')1161 public function strip_attributes($attribs = '') 1422 1162 { 1423 1163 if ($attribs === '') … … 1428 1168 } 1429 1169 1430 function set_output_encoding($encoding = 'UTF-8') 1170 /** 1171 * Set the output encoding 1172 * 1173 * Allows you to override SimplePie's output to match that of your webpage. 1174 * This is useful for times when your webpages are not being served as 1175 * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and 1176 * is similar to {@see set_input_encoding()}. 1177 * 1178 * It should be noted, however, that not all character encodings can support 1179 * all characters. If your page is being served as ISO-8859-1 and you try 1180 * to display a Japanese feed, you'll likely see garbled characters. 1181 * Because of this, it is highly recommended to ensure that your webpages 1182 * are served as UTF-8. 1183 * 1184 * The number of supported character encodings depends on whether your web 1185 * host supports {@link http://php.net/mbstring mbstring}, 1186 * {@link http://php.net/iconv iconv}, or both. See 1187 * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for 1188 * more information. 1189 * 1190 * @param string $encoding 1191 */ 1192 public function set_output_encoding($encoding = 'UTF-8') 1431 1193 { 1432 1194 $this->sanitize->set_output_encoding($encoding); 1433 1195 } 1434 1196 1435 function strip_comments($strip = false)1197 public function strip_comments($strip = false) 1436 1198 { 1437 1199 $this->sanitize->strip_comments($strip); … … 1442 1204 * containing URLs that need to be resolved relative to the feed 1443 1205 * 1444 * @access public 1206 * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite, 1207 * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite, 1208 * |q|@cite 1209 * 1445 1210 * @since 1.0 1446 * @param array $element_attribute Element/attribute key/value pairs1447 */ 1448 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))1211 * @param array|null $element_attribute Element/attribute key/value pairs, null for default 1212 */ 1213 public function set_url_replacements($element_attribute = null) 1449 1214 { 1450 1215 $this->sanitize->set_url_replacements($element_attribute); … … 1452 1217 1453 1218 /** 1454 * Set the handler to enable the display of cached favicons.1455 *1456 * @access public1457 * @param str $page Web-accessible path to the handler_favicon.php file.1458 * @param str $qs The query string that the value should be passed to.1459 */1460 function set_favicon_handler($page = false, $qs = 'i')1461 {1462 if ($page !== false)1463 {1464 $this->favicon_handler = $page . '?' . $qs . '=';1465 }1466 else1467 {1468 $this->favicon_handler = '';1469 }1470 }1471 1472 /**1473 1219 * Set the handler to enable the display of cached images. 1474 1220 * 1475 * @access public1476 1221 * @param str $page Web-accessible path to the handler_image.php file. 1477 1222 * @param str $qs The query string that the value should be passed to. 1478 1223 */ 1479 function set_image_handler($page = false, $qs = 'i')1224 public function set_image_handler($page = false, $qs = 'i') 1480 1225 { 1481 1226 if ($page !== false) … … 1490 1235 1491 1236 /** 1492 * Set the limit for items returned per-feed with multifeeds. 1493 * 1494 * @access public 1237 * Set the limit for items returned per-feed with multifeeds 1238 * 1495 1239 * @param integer $limit The maximum number of items to return. 1496 1240 */ 1497 function set_item_limit($limit = 0)1241 public function set_item_limit($limit = 0) 1498 1242 { 1499 1243 $this->item_limit = (int) $limit; 1500 1244 } 1501 1245 1502 function init() 1246 /** 1247 * Initialize the feed object 1248 * 1249 * This is what makes everything happen. Period. This is where all of the 1250 * configuration options get processed, feeds are fetched, cached, and 1251 * parsed, and all of that other good stuff. 1252 * 1253 * @return boolean True if successful, false otherwise 1254 */ 1255 public function init() 1503 1256 { 1504 1257 // Check absolute bare minimum requirements. 1505 if ( (function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) ||!extension_loaded('xml') || !extension_loaded('pcre'))1258 if (!extension_loaded('xml') || !extension_loaded('pcre')) 1506 1259 { 1507 1260 return false; … … 1524 1277 } 1525 1278 1526 if (isset($_GET[$this->javascript])) 1527 { 1528 SimplePie_Misc::output_javascript(); 1529 exit; 1279 if (method_exists($this->sanitize, 'set_registry')) 1280 { 1281 $this->sanitize->set_registry($this->registry); 1530 1282 } 1531 1283 1532 1284 // Pass whatever was set with config options over to the sanitizer. 1533 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); 1534 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); 1535 1536 if ($this->feed_url !== null || $this->raw_data !== null) 1537 { 1538 $this->data = array(); 1285 // Pass the classes in for legacy support; new classes should use the registry instead 1286 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache')); 1287 $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen); 1288 1289 if (!empty($this->multifeed_url)) 1290 { 1291 $i = 0; 1292 $success = 0; 1539 1293 $this->multifeed_objects = array(); 1540 $cache = false; 1541 1542 if ($this->feed_url !== null) 1543 { 1544 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); 1545 // Decide whether to enable caching 1546 if ($this->cache && $parsed_feed_url['scheme'] !== '') 1547 { 1548 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); 1549 } 1550 // If it's enabled and we don't want an XML dump, use the cache 1551 if ($cache && !$this->xml_dump) 1552 { 1553 // Load the Cache 1554 $this->data = $cache->load(); 1555 if (!empty($this->data)) 1294 $this->error = array(); 1295 foreach ($this->multifeed_url as $url) 1296 { 1297 $this->multifeed_objects[$i] = clone $this; 1298 $this->multifeed_objects[$i]->set_feed_url($url); 1299 $single_success = $this->multifeed_objects[$i]->init(); 1300 $success |= $single_success; 1301 if (!$single_success) 1302 { 1303 $this->error[$i] = $this->multifeed_objects[$i]->error(); 1304 } 1305 $i++; 1306 } 1307 return (bool) $success; 1308 } 1309 elseif ($this->feed_url === null && $this->raw_data === null) 1310 { 1311 return false; 1312 } 1313 1314 $this->error = null; 1315 $this->data = array(); 1316 $this->multifeed_objects = array(); 1317 $cache = false; 1318 1319 if ($this->feed_url !== null) 1320 { 1321 $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url)); 1322 1323 // Decide whether to enable caching 1324 if ($this->cache && $parsed_feed_url['scheme'] !== '') 1325 { 1326 $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc')); 1327 } 1328 1329 // Fetch the data via SimplePie_File into $this->raw_data 1330 if (($fetched = $this->fetch_data($cache)) === true) 1331 { 1332 return true; 1333 } 1334 elseif ($fetched === false) { 1335 return false; 1336 } 1337 1338 list($headers, $sniffed) = $fetched; 1339 } 1340 1341 // Set up array of possible encodings 1342 $encodings = array(); 1343 1344 // First check to see if input has been overridden. 1345 if ($this->input_encoding !== false) 1346 { 1347 $encodings[] = $this->input_encoding; 1348 } 1349 1350 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); 1351 $text_types = array('text/xml', 'text/xml-external-parsed-entity'); 1352 1353 // RFC 3023 (only applies to sniffed content) 1354 if (isset($sniffed)) 1355 { 1356 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') 1357 { 1358 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1359 { 1360 $encodings[] = strtoupper($charset[1]); 1361 } 1362 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry))); 1363 $encodings[] = 'UTF-8'; 1364 } 1365 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') 1366 { 1367 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1368 { 1369 $encodings[] = $charset[1]; 1370 } 1371 $encodings[] = 'US-ASCII'; 1372 } 1373 // Text MIME-type default 1374 elseif (substr($sniffed, 0, 5) === 'text/') 1375 { 1376 $encodings[] = 'US-ASCII'; 1377 } 1378 } 1379 1380 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 1381 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry))); 1382 $encodings[] = 'UTF-8'; 1383 $encodings[] = 'ISO-8859-1'; 1384 1385 // There's no point in trying an encoding twice 1386 $encodings = array_unique($encodings); 1387 1388 // Loop through each possible encoding, till we return something, or run out of possibilities 1389 foreach ($encodings as $encoding) 1390 { 1391 // Change the encoding to UTF-8 (as we always use UTF-8 internally) 1392 if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8'))) 1393 { 1394 // Create new parser 1395 $parser = $this->registry->create('Parser'); 1396 1397 // If it's parsed fine 1398 if ($parser->parse($utf8_data, 'UTF-8')) 1399 { 1400 $this->data = $parser->get_data(); 1401 if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE)) 1556 1402 { 1557 // If the cache is for an outdated build of SimplePie 1558 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) 1403 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed."; 1404 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); 1405 return false; 1406 } 1407 1408 if (isset($headers)) 1409 { 1410 $this->data['headers'] = $headers; 1411 } 1412 $this->data['build'] = SIMPLEPIE_BUILD; 1413 1414 // Cache the file if caching is enabled 1415 if ($cache && !$cache->save($this)) 1416 { 1417 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1418 } 1419 return true; 1420 } 1421 } 1422 } 1423 1424 if (isset($parser)) 1425 { 1426 // We have an error, just set SimplePie_Misc::error to it and quit 1427 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); 1428 } 1429 else 1430 { 1431 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.'; 1432 } 1433 1434 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); 1435 1436 return false; 1437 } 1438 1439 /** 1440 * Fetch the data via SimplePie_File 1441 * 1442 * If the data is already cached, attempt to fetch it from there instead 1443 * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache 1444 * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type 1445 */ 1446 protected function fetch_data(&$cache) 1447 { 1448 // If it's enabled, use the cache 1449 if ($cache) 1450 { 1451 // Load the Cache 1452 $this->data = $cache->load(); 1453 if (!empty($this->data)) 1454 { 1455 // If the cache is for an outdated build of SimplePie 1456 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) 1457 { 1458 $cache->unlink(); 1459 $this->data = array(); 1460 } 1461 // If we've hit a collision just rerun it with caching disabled 1462 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) 1463 { 1464 $cache = false; 1465 $this->data = array(); 1466 } 1467 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. 1468 elseif (isset($this->data['feed_url'])) 1469 { 1470 // If the autodiscovery cache is still valid use it. 1471 if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) 1472 { 1473 // Do not need to do feed autodiscovery yet. 1474 if ($this->data['feed_url'] !== $this->data['url']) 1559 1475 { 1560 $ cache->unlink();1561 $this->data = array();1476 $this->set_feed_url($this->data['feed_url']); 1477 return $this->init(); 1562 1478 } 1563 // If we've hit a collision just rerun it with caching disabled 1564 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) 1565 { 1566 $cache = false; 1567 $this->data = array(); 1568 } 1569 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. 1570 elseif (isset($this->data['feed_url'])) 1571 { 1572 // If the autodiscovery cache is still valid use it. 1573 if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) 1574 { 1575 // Do not need to do feed autodiscovery yet. 1576 if ($this->data['feed_url'] === $this->data['url']) 1577 { 1578 $cache->unlink(); 1579 $this->data = array(); 1580 } 1581 else 1582 { 1583 $this->set_feed_url($this->data['feed_url']); 1584 return $this->init(); 1585 } 1586 } 1587 } 1588 // Check if the cache has been updated 1589 elseif ($cache->mtime() + $this->cache_duration < time()) 1590 { 1591 // If we have last-modified and/or etag set 1592 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) 1593 { 1594 $headers = array(); 1595 if (isset($this->data['headers']['last-modified'])) 1596 { 1597 $headers['if-modified-since'] = $this->data['headers']['last-modified']; 1598 } 1599 if (isset($this->data['headers']['etag'])) 1600 { 1601 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; 1602 } 1603 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); 1604 if ($file->success) 1605 { 1606 if ($file->status_code === 304) 1607 { 1608 $cache->touch(); 1609 return true; 1610 } 1611 else 1612 { 1613 $headers = $file->headers; 1614 } 1615 } 1616 else 1617 { 1618 unset($file); 1619 } 1620 } 1621 } 1622 // If the cache is still valid, just return true 1623 else 1624 { 1625 return true; 1626 } 1627 } 1628 // If the cache is empty, delete it 1629 else 1630 { 1479 1631 1480 $cache->unlink(); 1632 1481 $this->data = array(); 1633 1482 } 1634 1483 } 1635 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. 1636 if (!isset($file)) 1637 { 1638 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url) 1484 // Check if the cache has been updated 1485 elseif ($cache->mtime() + $this->cache_duration < time()) 1486 { 1487 // If we have last-modified and/or etag set 1488 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) 1639 1489 { 1640 $file =& $this->file; 1641 } 1642 else 1643 { 1644 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); 1645 } 1646 } 1647 // If the file connection has an error, set SimplePie::error to that and quit 1648 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 1649 { 1650 $this->error = $file->error; 1651 if (!empty($this->data)) 1652 { 1653 return true; 1654 } 1655 else 1656 { 1657 return false; 1658 } 1659 } 1660 1661 if (!$this->force_feed) 1662 { 1663 // Check if the supplied URL is a feed, if it isn't, look for it. 1664 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); 1665 if (!$locate->is_feed($file)) 1666 { 1667 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1668 unset($file); 1669 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)) 1490 $headers = array( 1491 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', 1492 ); 1493 if (isset($this->data['headers']['last-modified'])) 1670 1494 { 1671 if ($cache) 1495 $headers['if-modified-since'] = $this->data['headers']['last-modified']; 1496 } 1497 if (isset($this->data['headers']['etag'])) 1498 { 1499 $headers['if-none-match'] = $this->data['headers']['etag']; 1500 } 1501 1502 $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen)); 1503 1504 if ($file->success) 1505 { 1506 if ($file->status_code === 304) 1672 1507 { 1673 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); 1674 if (!$cache->save($this)) 1675 { 1676 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1677 } 1678 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); 1508 $cache->touch(); 1509 return true; 1679 1510 } 1680 $this->feed_url = $file->url;1681 1511 } 1682 1512 else 1683 1513 { 1684 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed."; 1685 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1686 return false; 1514 unset($file); 1687 1515 } 1688 1516 } 1689 $locate = null; 1690 } 1691 1692 $headers = $file->headers; 1693 $data = $file->body; 1694 $sniffer =& new $this->content_type_sniffer_class($file); 1695 $sniffed = $sniffer->get_type(); 1696 } 1517 } 1518 // If the cache is still valid, just return true 1519 else 1520 { 1521 $this->raw_data = false; 1522 return true; 1523 } 1524 } 1525 // If the cache is empty, delete it 1697 1526 else 1698 1527 { 1699 $data = $this->raw_data; 1700 } 1701 1702 // Set up array of possible encodings 1703 $encodings = array(); 1704 1705 // First check to see if input has been overridden. 1706 if ($this->input_encoding !== false) 1707 { 1708 $encodings[] = $this->input_encoding; 1709 } 1710 1711 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); 1712 $text_types = array('text/xml', 'text/xml-external-parsed-entity'); 1713 1714 // RFC 3023 (only applies to sniffed content) 1715 if (isset($sniffed)) 1716 { 1717 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') 1718 { 1719 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1528 $cache->unlink(); 1529 $this->data = array(); 1530 } 1531 } 1532 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. 1533 if (!isset($file)) 1534 { 1535 if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url) 1536 { 1537 $file =& $this->file; 1538 } 1539 else 1540 { 1541 $headers = array( 1542 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1', 1543 ); 1544 $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen)); 1545 } 1546 } 1547 // If the file connection has an error, set SimplePie::error to that and quit 1548 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 1549 { 1550 $this->error = $file->error; 1551 return !empty($this->data); 1552 } 1553 1554 if (!$this->force_feed) 1555 { 1556 // Check if the supplied URL is a feed, if it isn't, look for it. 1557 $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds)); 1558 1559 if (!$locate->is_feed($file)) 1560 { 1561 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1562 unset($file); 1563 if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))) 1564 { 1565 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed."; 1566 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); 1567 return false; 1568 } 1569 if ($cache) 1570 { 1571 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); 1572 if (!$cache->save($this)) 1720 1573 { 1721 $encodings[] = strtoupper($charset[1]);1574 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1722 1575 } 1723 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1724 $encodings[] = 'UTF-8'; 1725 } 1726 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') 1727 { 1728 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1729 { 1730 $encodings[] = $charset[1]; 1731 } 1732 $encodings[] = 'US-ASCII'; 1733 } 1734 // Text MIME-type default 1735 elseif (substr($sniffed, 0, 5) === 'text/') 1736 { 1737 $encodings[] = 'US-ASCII'; 1738 } 1739 } 1740 1741 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 1742 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1743 $encodings[] = 'UTF-8'; 1744 $encodings[] = 'ISO-8859-1'; 1745 1746 // There's no point in trying an encoding twice 1747 $encodings = array_unique($encodings); 1748 1749 // If we want the XML, just output that with the most likely encoding and quit 1750 if ($this->xml_dump) 1751 { 1752 header('Content-type: text/xml; charset=' . $encodings[0]); 1753 echo $data; 1754 exit; 1755 } 1756 1757 // Loop through each possible encoding, till we return something, or run out of possibilities 1758 foreach ($encodings as $encoding) 1759 { 1760 // Change the encoding to UTF-8 (as we always use UTF-8 internally) 1761 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8')) 1762 { 1763 // Create new parser 1764 $parser =& new $this->parser_class(); 1765 1766 // If it's parsed fine 1767 if ($parser->parse($utf8_data, 'UTF-8')) 1768 { 1769 $this->data = $parser->get_data(); 1770 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE) 1771 { 1772 if (isset($headers)) 1773 { 1774 $this->data['headers'] = $headers; 1775 } 1776 $this->data['build'] = SIMPLEPIE_BUILD; 1777 1778 // Cache the file if caching is enabled 1779 if ($cache && !$cache->save($this)) 1780 { 1781 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1782 } 1783 return true; 1784 } 1785 else 1786 { 1787 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed."; 1788 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1789 return false; 1790 } 1791 } 1792 } 1793 } 1794 if (isset($parser)) 1795 { 1796 // We have an error, just set SimplePie_Misc::error to it and quit 1797 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); 1798 } 1799 else 1800 { 1801 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.'; 1802 } 1803 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1804 return false; 1805 } 1806 elseif (!empty($this->multifeed_url)) 1807 { 1808 $i = 0; 1809 $success = 0; 1810 $this->multifeed_objects = array(); 1811 foreach ($this->multifeed_url as $url) 1812 { 1813 if (SIMPLEPIE_PHP5) 1814 { 1815 // This keyword needs to defy coding standards for PHP4 compatibility 1816 $this->multifeed_objects[$i] = clone($this); 1817 } 1818 else 1819 { 1820 $this->multifeed_objects[$i] = $this; 1821 } 1822 $this->multifeed_objects[$i]->set_feed_url($url); 1823 $success |= $this->multifeed_objects[$i]->init(); 1824 $i++; 1825 } 1826 return (bool) $success; 1827 } 1828 else 1829 { 1830 return false; 1831 } 1832 } 1833 1834 /** 1835 * Return the error message for the occured error 1836 * 1837 * @access public 1838 * @return string Error message 1839 */ 1840 function error() 1576 $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc')); 1577 } 1578 $this->feed_url = $file->url; 1579 } 1580 $locate = null; 1581 } 1582 1583 $this->raw_data = $file->body; 1584 1585 $headers = $file->headers; 1586 $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file)); 1587 $sniffed = $sniffer->get_type(); 1588 1589 return array($headers, $sniffed); 1590 } 1591 1592 /** 1593 * Get the error message for the occured error 1594 * 1595 * @return string|array Error message, or array of messages for multifeeds 1596 */ 1597 public function error() 1841 1598 { 1842 1599 return $this->error; 1843 1600 } 1844 1601 1845 function get_encoding() 1602 /** 1603 * Get the raw XML 1604 * 1605 * This is the same as the old `$feed->enable_xml_dump(true)`, but returns 1606 * the data instead of printing it. 1607 * 1608 * @return string|boolean Raw XML data, false if the cache is used 1609 */ 1610 public function get_raw_data() 1611 { 1612 return $this->raw_data; 1613 } 1614 1615 /** 1616 * Get the character encoding used for output 1617 * 1618 * @since Preview Release 1619 * @return string 1620 */ 1621 public function get_encoding() 1846 1622 { 1847 1623 return $this->sanitize->output_encoding; 1848 1624 } 1849 1625 1850 function handle_content_type($mime = 'text/html') 1626 /** 1627 * Send the content-type header with correct encoding 1628 * 1629 * This method ensures that the SimplePie-enabled page is being served with 1630 * the correct {@link http://www.iana.org/assignments/media-types/ mime-type} 1631 * and character encoding HTTP headers (character encoding determined by the 1632 * {@see set_output_encoding} config option). 1633 * 1634 * This won't work properly if any content or whitespace has already been 1635 * sent to the browser, because it relies on PHP's 1636 * {@link http://php.net/header header()} function, and these are the 1637 * circumstances under which the function works. 1638 * 1639 * Because it's setting these settings for the entire page (as is the nature 1640 * of HTTP headers), this should only be used once per page (again, at the 1641 * top). 1642 * 1643 * @param string $mime MIME type to serve the page as 1644 */ 1645 public function handle_content_type($mime = 'text/html') 1851 1646 { 1852 1647 if (!headers_sent()) … … 1865 1660 } 1866 1661 1867 function get_type() 1662 /** 1663 * Get the type of the feed 1664 * 1665 * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against 1666 * using {@link http://php.net/language.operators.bitwise bitwise operators} 1667 * 1668 * @since 0.8 (usage changed to using constants in 1.0) 1669 * @see SIMPLEPIE_TYPE_NONE Unknown. 1670 * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90. 1671 * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape). 1672 * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland). 1673 * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91. 1674 * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92. 1675 * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93. 1676 * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94. 1677 * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0. 1678 * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x. 1679 * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS. 1680 * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format). 1681 * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS. 1682 * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3. 1683 * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0. 1684 * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom. 1685 * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type. 1686 * @return int SIMPLEPIE_TYPE_* constant 1687 */ 1688 public function get_type() 1868 1689 { 1869 1690 if (!isset($this->data['type'])) … … 1946 1767 1947 1768 /** 1948 * Returns the URL for the favicon of the feed's website. 1949 * 1950 * @todo Cache atom:icon 1951 * @access public 1952 * @since 1.0 1953 */ 1954 function get_favicon() 1955 { 1956 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 1957 { 1958 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 1959 } 1960 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) 1961 { 1962 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); 1963 1964 if ($this->cache && $this->favicon_handler) 1965 { 1966 $favicon_filename = call_user_func($this->cache_name_function, $favicon); 1967 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); 1968 1969 if ($cache->load()) 1970 { 1971 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1972 } 1973 else 1974 { 1975 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 1976 1977 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0) 1978 { 1979 $sniffer =& new $this->content_type_sniffer_class($file); 1980 if (substr($sniffer->get_type(), 0, 6) === 'image/') 1981 { 1982 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 1983 { 1984 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1985 } 1986 else 1987 { 1988 trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1989 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 1990 } 1991 } 1992 // not an image 1993 else 1994 { 1995 return false; 1996 } 1997 } 1998 } 1999 } 2000 else 2001 { 2002 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 2003 } 2004 } 2005 return false; 2006 } 2007 2008 /** 1769 * Get the URL for the feed 1770 * 1771 * May or may not be different from the URL passed to {@see set_feed_url()}, 1772 * depending on whether auto-discovery was used. 1773 * 1774 * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.) 2009 1775 * @todo If we have a perm redirect we should return the new URL 2010 1776 * @todo When we make the above change, let's support <itunes:new-feed-url> as well 2011 1777 * @todo Also, |atom:link|@rel=self 2012 */ 2013 function subscribe_url() 1778 * @return string|null 1779 */ 1780 public function subscribe_url() 2014 1781 { 2015 1782 if ($this->feed_url !== null) … … 2023 1790 } 2024 1791 2025 function subscribe_feed() 2026 { 2027 if ($this->feed_url !== null) 2028 { 2029 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2030 } 2031 else 2032 { 2033 return null; 2034 } 2035 } 2036 2037 function subscribe_outlook() 2038 { 2039 if ($this->feed_url !== null) 2040 { 2041 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2042 } 2043 else 2044 { 2045 return null; 2046 } 2047 } 2048 2049 function subscribe_podcast() 2050 { 2051 if ($this->feed_url !== null) 2052 { 2053 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); 2054 } 2055 else 2056 { 2057 return null; 2058 } 2059 } 2060 2061 function subscribe_itunes() 2062 { 2063 if ($this->feed_url !== null) 2064 { 2065 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); 2066 } 2067 else 2068 { 2069 return null; 2070 } 2071 } 2072 2073 /** 2074 * Creates the subscribe_* methods' return data 2075 * 2076 * @access private 2077 * @param string $feed_url String to prefix to the feed URL 2078 * @param string $site_url String to prefix to the site URL (and 2079 * suffix to the feed URL) 2080 * @return mixed URL if feed exists, false otherwise 2081 */ 2082 function subscribe_service($feed_url, $site_url = null) 2083 { 2084 if ($this->subscribe_url()) 2085 { 2086 $return = $feed_url . rawurlencode($this->feed_url); 2087 if ($site_url !== null && $this->get_link() !== null) 2088 { 2089 $return .= $site_url . rawurlencode($this->get_link()); 2090 } 2091 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 2092 } 2093 else 2094 { 2095 return null; 2096 } 2097 } 2098 2099 function subscribe_aol() 2100 { 2101 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); 2102 } 2103 2104 function subscribe_bloglines() 2105 { 2106 return $this->subscribe_service('http://www.bloglines.com/sub/'); 2107 } 2108 2109 function subscribe_eskobo() 2110 { 2111 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); 2112 } 2113 2114 function subscribe_feedfeeds() 2115 { 2116 return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); 2117 } 2118 2119 function subscribe_feedster() 2120 { 2121 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); 2122 } 2123 2124 function subscribe_google() 2125 { 2126 return $this->subscribe_service('http://fusion.google.com/add?feedurl='); 2127 } 2128 2129 function subscribe_gritwire() 2130 { 2131 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); 2132 } 2133 2134 function subscribe_msn() 2135 { 2136 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); 2137 } 2138 2139 function subscribe_netvibes() 2140 { 2141 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); 2142 } 2143 2144 function subscribe_newsburst() 2145 { 2146 return $this->subscribe_service('http://www.newsburst.com/Source/?add='); 2147 } 2148 2149 function subscribe_newsgator() 2150 { 2151 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); 2152 } 2153 2154 function subscribe_odeo() 2155 { 2156 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); 2157 } 2158 2159 function subscribe_podnova() 2160 { 2161 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); 2162 } 2163 2164 function subscribe_rojo() 2165 { 2166 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); 2167 } 2168 2169 function subscribe_yahoo() 2170 { 2171 return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); 2172 } 2173 2174 function get_feed_tags($namespace, $tag) 1792 /** 1793 * Get data for an feed-level element 1794 * 1795 * This method allows you to get access to ANY element/attribute that is a 1796 * sub-element of the opening feed tag. 1797 * 1798 * The return value is an indexed array of elements matching the given 1799 * namespace and tag name. Each element has `attribs`, `data` and `child` 1800 * subkeys. For `attribs` and `child`, these contain namespace subkeys. 1801 * `attribs` then has one level of associative name => value data (where 1802 * `value` is a string) after the namespace. `child` has tag-indexed keys 1803 * after the namespace, each member of which is an indexed array matching 1804 * this same format. 1805 * 1806 * For example: 1807 * <pre> 1808 * // This is probably a bad example because we already support 1809 * // <media:content> natively, but it shows you how to parse through 1810 * // the nodes. 1811 * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group'); 1812 * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']; 1813 * $file = $content[0]['attribs']['']['url']; 1814 * echo $file; 1815 * </pre> 1816 * 1817 * @since 1.0 1818 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces 1819 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 1820 * @param string $tag Tag name 1821 * @return array 1822 */ 1823 public function get_feed_tags($namespace, $tag) 2175 1824 { 2176 1825 $type = $this->get_type(); … … 2206 1855 } 2207 1856 2208 function get_channel_tags($namespace, $tag) 1857 /** 1858 * Get data for an channel-level element 1859 * 1860 * This method allows you to get access to ANY element/attribute in the 1861 * channel/header section of the feed. 1862 * 1863 * See {@see SimplePie::get_feed_tags()} for a description of the return value 1864 * 1865 * @since 1.0 1866 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces 1867 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 1868 * @param string $tag Tag name 1869 * @return array 1870 */ 1871 public function get_channel_tags($namespace, $tag) 2209 1872 { 2210 1873 $type = $this->get_type(); … … 2249 1912 } 2250 1913 2251 function get_image_tags($namespace, $tag) 1914 /** 1915 * Get data for an channel-level element 1916 * 1917 * This method allows you to get access to ANY element/attribute in the 1918 * image/logo section of the feed. 1919 * 1920 * See {@see SimplePie::get_feed_tags()} for a description of the return value 1921 * 1922 * @since 1.0 1923 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces 1924 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 1925 * @param string $tag Tag name 1926 * @return array 1927 */ 1928 public function get_image_tags($namespace, $tag) 2252 1929 { 2253 1930 $type = $this->get_type(); … … 2285 1962 } 2286 1963 2287 function get_base($element = array()) 1964 /** 1965 * Get the base URL value from the feed 1966 * 1967 * Uses `<xml:base>` if available, otherwise uses the first link in the 1968 * feed, or failing that, the URL of the feed itself. 1969 * 1970 * @see get_link 1971 * @see subscribe_url 1972 * 1973 * @param array $element 1974 * @return string 1975 */ 1976 public function get_base($element = array()) 2288 1977 { 2289 1978 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) … … 2301 1990 } 2302 1991 2303 function sanitize($data, $type, $base = '') 1992 /** 1993 * Sanitize feed data 1994 * 1995 * @access private 1996 * @see SimplePie_Sanitize::sanitize() 1997 * @param string $data Data to sanitize 1998 * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants 1999 * @param string $base Base URL to resolve URLs against 2000 * @return string Sanitized data 2001 */ 2002 public function sanitize($data, $type, $base = '') 2304 2003 { 2305 2004 return $this->sanitize->sanitize($data, $type, $base); 2306 2005 } 2307 2006 2308 function get_title() 2007 /** 2008 * Get the title of the feed 2009 * 2010 * Uses `<atom:title>`, `<title>` or `<dc:title>` 2011 * 2012 * @since 1.0 (previously called `get_feed_title` since 0.8) 2013 * @return string|null 2014 */ 2015 public function get_title() 2309 2016 { 2310 2017 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 2311 2018 { 2312 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));2019 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2313 2020 } 2314 2021 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 2315 2022 { 2316 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));2023 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2317 2024 } 2318 2025 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) … … 2342 2049 } 2343 2050 2344 function get_category($key = 0) 2051 /** 2052 * Get a category for the feed 2053 * 2054 * @since Unknown 2055 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1 2056 * @return SimplePie_Category|null 2057 */ 2058 public function get_category($key = 0) 2345 2059 { 2346 2060 $categories = $this->get_categories(); … … 2355 2069 } 2356 2070 2357 function get_categories() 2071 /** 2072 * Get all categories for the feed 2073 * 2074 * Uses `<atom:category>`, `<category>` or `<dc:subject>` 2075 * 2076 * @since Unknown 2077 * @return array|null List of {@see SimplePie_Category} objects 2078 */ 2079 public function get_categories() 2358 2080 { 2359 2081 $categories = array(); … … 2376 2098 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 2377 2099 } 2378 $categories[] = & new $this->category_class($term, $scheme, $label);2100 $categories[] = $this->registry->create('Category', array($term, $scheme, $label)); 2379 2101 } 2380 2102 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) … … 2391 2113 $scheme = null; 2392 2114 } 2393 $categories[] = & new $this->category_class($term, $scheme, null);2115 $categories[] = $this->registry->create('Category', array($term, $scheme, null)); 2394 2116 } 2395 2117 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 2396 2118 { 2397 $categories[] = & new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);2119 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); 2398 2120 } 2399 2121 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 2400 2122 { 2401 $categories[] = & new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);2123 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); 2402 2124 } 2403 2125 2404 2126 if (!empty($categories)) 2405 2127 { 2406 return SimplePie_Misc::array_unique($categories);2128 return array_unique($categories); 2407 2129 } 2408 2130 else … … 2412 2134 } 2413 2135 2414 function get_author($key = 0) 2136 /** 2137 * Get an author for the feed 2138 * 2139 * @since 1.1 2140 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1 2141 * @return SimplePie_Author|null 2142 */ 2143 public function get_author($key = 0) 2415 2144 { 2416 2145 $authors = $this->get_authors(); … … 2425 2154 } 2426 2155 2427 function get_authors() 2156 /** 2157 * Get all authors for the feed 2158 * 2159 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>` 2160 * 2161 * @since 1.1 2162 * @return array|null List of {@see SimplePie_Author} objects 2163 */ 2164 public function get_authors() 2428 2165 { 2429 2166 $authors = array(); … … 2447 2184 if ($name !== null || $email !== null || $uri !== null) 2448 2185 { 2449 $authors[] = & new $this->author_class($name, $uri, $email);2186 $authors[] = $this->registry->create('Author', array($name, $uri, $email)); 2450 2187 } 2451 2188 } … … 2469 2206 if ($name !== null || $email !== null || $url !== null) 2470 2207 { 2471 $authors[] = & new $this->author_class($name, $url, $email);2208 $authors[] = $this->registry->create('Author', array($name, $url, $email)); 2472 2209 } 2473 2210 } 2474 2211 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 2475 2212 { 2476 $authors[] = & new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);2213 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); 2477 2214 } 2478 2215 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 2479 2216 { 2480 $authors[] = & new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);2217 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); 2481 2218 } 2482 2219 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 2483 2220 { 2484 $authors[] = & new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);2221 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); 2485 2222 } 2486 2223 2487 2224 if (!empty($authors)) 2488 2225 { 2489 return SimplePie_Misc::array_unique($authors);2226 return array_unique($authors); 2490 2227 } 2491 2228 else … … 2495 2232 } 2496 2233 2497 function get_contributor($key = 0) 2234 /** 2235 * Get a contributor for the feed 2236 * 2237 * @since 1.1 2238 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1 2239 * @return SimplePie_Author|null 2240 */ 2241 public function get_contributor($key = 0) 2498 2242 { 2499 2243 $contributors = $this->get_contributors(); … … 2508 2252 } 2509 2253 2510 function get_contributors() 2254 /** 2255 * Get all contributors for the feed 2256 * 2257 * Uses `<atom:contributor>` 2258 * 2259 * @since 1.1 2260 * @return array|null List of {@see SimplePie_Author} objects 2261 */ 2262 public function get_contributors() 2511 2263 { 2512 2264 $contributors = array(); … … 2530 2282 if ($name !== null || $email !== null || $uri !== null) 2531 2283 { 2532 $contributors[] = & new $this->author_class($name, $uri, $email);2284 $contributors[] = $this->registry->create('Author', array($name, $uri, $email)); 2533 2285 } 2534 2286 } … … 2552 2304 if ($name !== null || $email !== null || $url !== null) 2553 2305 { 2554 $contributors[] = & new $this->author_class($name, $url, $email);2306 $contributors[] = $this->registry->create('Author', array($name, $url, $email)); 2555 2307 } 2556 2308 } … … 2558 2310 if (!empty($contributors)) 2559 2311 { 2560 return SimplePie_Misc::array_unique($contributors);2312 return array_unique($contributors); 2561 2313 } 2562 2314 else … … 2566 2318 } 2567 2319 2568 function get_link($key = 0, $rel = 'alternate') 2320 /** 2321 * Get a single link for the feed 2322 * 2323 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8) 2324 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1 2325 * @param string $rel The relationship of the link to return 2326 * @return string|null Link URL 2327 */ 2328 public function get_link($key = 0, $rel = 'alternate') 2569 2329 { 2570 2330 $links = $this->get_links($rel); … … 2580 2340 2581 2341 /** 2582 * Added for parity between the parent-level and the item/entry-level. 2583 */ 2584 function get_permalink() 2342 * Get the permalink for the item 2343 * 2344 * Returns the first link available with a relationship of "alternate". 2345 * Identical to {@see get_link()} with key 0 2346 * 2347 * @see get_link 2348 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8) 2349 * @internal Added for parity between the parent-level and the item/entry-level. 2350 * @return string|null Link URL 2351 */ 2352 public function get_permalink() 2585 2353 { 2586 2354 return $this->get_link(0); 2587 2355 } 2588 2356 2589 function get_links($rel = 'alternate') 2357 /** 2358 * Get all links for the feed 2359 * 2360 * Uses `<atom:link>` or `<link>` 2361 * 2362 * @since Beta 2 2363 * @param string $rel The relationship of links to return 2364 * @return array|null Links found for the feed (strings) 2365 */ 2366 public function get_links($rel = 'alternate') 2590 2367 { 2591 2368 if (!isset($this->data['links'])) … … 2631 2408 foreach ($keys as $key) 2632 2409 { 2633 if ( SimplePie_Misc::is_isegment_nz_nc($key))2410 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key))) 2634 2411 { 2635 2412 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) … … 2661 2438 } 2662 2439 2663 function get_all_discovered_feeds()2440 public function get_all_discovered_feeds() 2664 2441 { 2665 2442 return $this->all_discovered_feeds; 2666 2443 } 2667 2444 2668 function get_description() 2445 /** 2446 * Get the content for the item 2447 * 2448 * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`, 2449 * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>` 2450 * 2451 * @since 1.0 (previously called `get_feed_description()` since 0.8) 2452 * @return string|null 2453 */ 2454 public function get_description() 2669 2455 { 2670 2456 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 2671 2457 { 2672 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));2458 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2673 2459 } 2674 2460 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 2675 2461 { 2676 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));2462 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2677 2463 } 2678 2464 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) … … 2710 2496 } 2711 2497 2712 function get_copyright() 2498 /** 2499 * Get the copyright info for the feed 2500 * 2501 * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>` 2502 * 2503 * @since 1.0 (previously called `get_feed_copyright()` since 0.8) 2504 * @return string|null 2505 */ 2506 public function get_copyright() 2713 2507 { 2714 2508 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 2715 2509 { 2716 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));2510 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2717 2511 } 2718 2512 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 2719 2513 { 2720 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));2514 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); 2721 2515 } 2722 2516 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) … … 2738 2532 } 2739 2533 2740 function get_language() 2534 /** 2535 * Get the language for the feed 2536 * 2537 * Uses `<language>`, `<dc:language>`, or @xml_lang 2538 * 2539 * @since 1.0 (previously called `get_feed_language()` since 0.8) 2540 * @return string|null 2541 */ 2542 public function get_language() 2741 2543 { 2742 2544 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) … … 2774 2576 } 2775 2577 2776 function get_latitude() 2578 /** 2579 * Get the latitude coordinates for the item 2580 * 2581 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications 2582 * 2583 * Uses `<geo:lat>` or `<georss:point>` 2584 * 2585 * @since 1.0 2586 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo 2587 * @link http://www.georss.org/ GeoRSS 2588 * @return string|null 2589 */ 2590 public function get_latitude() 2777 2591 { 2778 2592 … … 2791 2605 } 2792 2606 2793 function get_longitude() 2607 /** 2608 * Get the longitude coordinates for the feed 2609 * 2610 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications 2611 * 2612 * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>` 2613 * 2614 * @since 1.0 2615 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo 2616 * @link http://www.georss.org/ GeoRSS 2617 * @return string|null 2618 */ 2619 public function get_longitude() 2794 2620 { 2795 2621 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) … … 2811 2637 } 2812 2638 2813 function get_image_title() 2639 /** 2640 * Get the feed logo's title 2641 * 2642 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title. 2643 * 2644 * Uses `<image><title>` or `<image><dc:title>` 2645 * 2646 * @return string|null 2647 */ 2648 public function get_image_title() 2814 2649 { 2815 2650 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) … … 2839 2674 } 2840 2675 2841 function get_image_url() 2676 /** 2677 * Get the feed logo's URL 2678 * 2679 * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to 2680 * have a "feed logo" URL. This points directly to the image itself. 2681 * 2682 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`, 2683 * `<image><title>` or `<image><dc:title>` 2684 * 2685 * @return string|null 2686 */ 2687 public function get_image_url() 2842 2688 { 2843 2689 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) … … 2871 2717 } 2872 2718 2873 function get_image_link() 2719 2720 /** 2721 * Get the feed logo's link 2722 * 2723 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This 2724 * points to a human-readable page that the image should link to. 2725 * 2726 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`, 2727 * `<image><title>` or `<image><dc:title>` 2728 * 2729 * @return string|null 2730 */ 2731 public function get_image_link() 2874 2732 { 2875 2733 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) … … 2891 2749 } 2892 2750 2893 function get_image_width() 2751 /** 2752 * Get the feed logo's link 2753 * 2754 * RSS 2.0 feeds are allowed to have a "feed logo" width. 2755 * 2756 * Uses `<image><width>` or defaults to 88.0 if no width is specified and 2757 * the feed is an RSS 2.0 feed. 2758 * 2759 * @return int|float|null 2760 */ 2761 public function get_image_width() 2894 2762 { 2895 2763 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width')) … … 2907 2775 } 2908 2776 2909 function get_image_height() 2777 /** 2778 * Get the feed logo's height 2779 * 2780 * RSS 2.0 feeds are allowed to have a "feed logo" height. 2781 * 2782 * Uses `<image><height>` or defaults to 31.0 if no height is specified and 2783 * the feed is an RSS 2.0 feed. 2784 * 2785 * @return int|float|null 2786 */ 2787 public function get_image_height() 2910 2788 { 2911 2789 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height')) … … 2923 2801 } 2924 2802 2925 function get_item_quantity($max = 0) 2803 /** 2804 * Get the number of items in the feed 2805 * 2806 * This is well-suited for {@link http://php.net/for for()} loops with 2807 * {@see get_item()} 2808 * 2809 * @param int $max Maximum value to return. 0 for no limit 2810 * @return int Number of items in the feed 2811 */ 2812 public function get_item_quantity($max = 0) 2926 2813 { 2927 2814 $max = (int) $max; … … 2937 2824 } 2938 2825 2939 function get_item($key = 0) 2826 /** 2827 * Get a single item from the feed 2828 * 2829 * This is better suited for {@link http://php.net/for for()} loops, whereas 2830 * {@see get_items()} is better suited for 2831 * {@link http://php.net/foreach foreach()} loops. 2832 * 2833 * @see get_item_quantity() 2834 * @since Beta 2 2835 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1 2836 * @return SimplePie_Item|null 2837 */ 2838 public function get_item($key = 0) 2940 2839 { 2941 2840 $items = $this->get_items(); … … 2950 2849 } 2951 2850 2952 function get_items($start = 0, $end = 0) 2851 /** 2852 * Get all items from the feed 2853 * 2854 * This is better suited for {@link http://php.net/for for()} loops, whereas 2855 * {@see get_items()} is better suited for 2856 * {@link http://php.net/foreach foreach()} loops. 2857 * 2858 * @see get_item_quantity 2859 * @since Beta 2 2860 * @param int $start Index to start at 2861 * @param int $end Number of items to return. 0 for all items after `$start` 2862 * @return array|null List of {@see SimplePie_Item} objects 2863 */ 2864 public function get_items($start = 0, $end = 0) 2953 2865 { 2954 2866 if (!isset($this->data['items'])) … … 2966 2878 foreach ($keys as $key) 2967 2879 { 2968 $this->data['items'][] = & new $this->item_class($this, $items[$key]);2880 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); 2969 2881 } 2970 2882 } … … 2974 2886 foreach ($keys as $key) 2975 2887 { 2976 $this->data['items'][] = & new $this->item_class($this, $items[$key]);2888 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); 2977 2889 } 2978 2890 } … … 2982 2894 foreach ($keys as $key) 2983 2895 { 2984 $this->data['items'][] = & new $this->item_class($this, $items[$key]);2896 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); 2985 2897 } 2986 2898 } … … 2990 2902 foreach ($keys as $key) 2991 2903 { 2992 $this->data['items'][] = & new $this->item_class($this, $items[$key]);2904 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); 2993 2905 } 2994 2906 } … … 2998 2910 foreach ($keys as $key) 2999 2911 { 3000 $this->data['items'][] = & new $this->item_class($this, $items[$key]);2912 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); 3001 2913 } 3002 2914 } … … 3024 2936 if ($do_sort) 3025 2937 { 3026 usort($this->data['ordered_items'], array( &$this, 'sort_items'));2938 usort($this->data['ordered_items'], array(get_class($this), 'sort_items')); 3027 2939 } 3028 2940 } … … 3051 2963 3052 2964 /** 3053 * @static 3054 */ 3055 function sort_items($a, $b) 2965 * Sorting callback for items 2966 * 2967 * @access private 2968 * @param SimplePie $a 2969 * @param SimplePie $b 2970 * @return boolean 2971 */ 2972 public static function sort_items($a, $b) 3056 2973 { 3057 2974 return $a->get_date('U') <= $b->get_date('U'); … … 3059 2976 3060 2977 /** 3061 * @static 3062 */ 3063 function merge_items($urls, $start = 0, $end = 0, $limit = 0) 2978 * Merge items from several feeds into one 2979 * 2980 * If you're merging multiple feeds together, they need to all have dates 2981 * for the items or else SimplePie will refuse to sort them. 2982 * 2983 * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings 2984 * @param array $urls List of SimplePie feed objects to merge 2985 * @param int $start Starting item 2986 * @param int $end Number of items to return 2987 * @param int $limit Maximum number of items per feed 2988 * @return array 2989 */ 2990 public static function merge_items($urls, $start = 0, $end = 0, $limit = 0) 3064 2991 { 3065 2992 if (is_array($urls) && sizeof($urls) > 0) … … 3068 2995 foreach ($urls as $arg) 3069 2996 { 3070 if ( is_a($arg, 'SimplePie'))2997 if ($arg instanceof SimplePie) 3071 2998 { 3072 2999 $items = array_merge($items, $arg->get_items(0, $limit)); … … 3090 3017 if ($do_sort) 3091 3018 { 3092 usort($items, array( 'SimplePie', 'sort_items'));3019 usort($items, array(get_class($urls[0]), 'sort_items')); 3093 3020 } 3094 3021 … … 3109 3036 } 3110 3037 } 3111 3112 class SimplePie_Item3113 {3114 var $feed;3115 var $data = array();3116 3117 function SimplePie_Item($feed, $data)3118 {3119 $this->feed = $feed;3120 $this->data = $data;3121 }3122 3123 function __toString()3124 {3125 return md5(serialize($this->data));3126 }3127 3128 /**3129 * Remove items that link back to this before destroying this object3130 */3131 function __destruct()3132 {3133 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))3134 {3135 unset($this->feed);3136 }3137 }3138 3139 function get_item_tags($namespace, $tag)3140 {3141 if (isset($this->data['child'][$namespace][$tag]))3142 {3143 return $this->data['child'][$namespace][$tag];3144 }3145 else3146 {3147 return null;3148 }3149 }3150 3151 function get_base($element = array())3152 {3153 return $this->feed->get_base($element);3154 }3155 3156 function sanitize($data, $type, $base = '')3157 {3158 return $this->feed->sanitize($data, $type, $base);3159 }3160 3161 function get_feed()3162 {3163 return $this->feed;3164 }3165 3166 function get_id($hash = false)3167 {3168 if (!$hash)3169 {3170 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))3171 {3172 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3173 }3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))3175 {3176 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3177 }3178 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))3179 {3180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3181 }3182 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))3183 {3184 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3185 }3186 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))3187 {3188 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3189 }3190 elseif (($return = $this->get_permalink()) !== null)3191 {3192 return $return;3193 }3194 elseif (($return = $this->get_title()) !== null)3195 {3196 return $return;3197 }3198 }3199 if ($this->get_permalink() !== null || $this->get_title() !== null)3200 {3201 return md5($this->get_permalink() . $this->get_title());3202 }3203 else3204 {3205 return md5(serialize($this->data));3206 }3207 }3208 3209 function get_title()3210 {3211 if (!isset($this->data['title']))3212 {3213 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))3214 {3215 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));3216 }3217 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))3218 {3219 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));3220 }3221 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))3222 {3223 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));3224 }3225 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))3226 {3227 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));3228 }3229 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))3230 {3231 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));3232 }3233 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))3234 {3235 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3236 }3237 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))3238 {3239 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3240 }3241 else3242 {3243 $this->data['title'] = null;3244 }3245 }3246 return $this->data['title'];3247 }3248 3249 function get_description($description_only = false)3250 {3251 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))3252 {3253 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));3254 }3255 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))3256 {3257 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));3258 }3259 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))3260 {3261 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));3262 }3263 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))3264 {3265 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));3266 }3267 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))3268 {3269 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3270 }3271 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))3272 {3273 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3274 }3275 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))3276 {3277 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));3278 }3279 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))3280 {3281 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3282 }3283 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))3284 {3285 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);3286 }3287 3288 elseif (!$description_only)3289 {3290 return $this->get_content(true);3291 }3292 else3293 {3294 return null;3295 }3296 }3297 3298 function get_content($content_only = false)3299 {3300 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))3301 {3302 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));3303 }3304 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))3305 {3306 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));3307 }3308 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))3309 {3310 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));3311 }3312 elseif (!$content_only)3313 {3314 return $this->get_description(true);3315 }3316 else3317 {3318 return null;3319 }3320 }3321 3322 function get_category($key = 0)3323 {3324 $categories = $this->get_categories();3325 if (isset($categories[$key]))3326 {3327 return $categories[$key];3328 }3329 else3330 {3331 return null;3332 }3333 }3334 3335 function get_categories()3336 {3337 $categories = array();3338 3339 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)3340 {3341 $term = null;3342 $scheme = null;3343 $label = null;3344 if (isset($category['attribs']['']['term']))3345 {3346 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);3347 }3348 if (isset($category['attribs']['']['scheme']))3349 {3350 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);3351 }3352 if (isset($category['attribs']['']['label']))3353 {3354 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);3355 }3356 $categories[] =& new $this->feed->category_class($term, $scheme, $label);3357 }3358 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)3359 {3360 // This is really the label, but keep this as the term also for BC.3361 // Label will also work on retrieving because that falls back to term.3362 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);3363 if (isset($category['attribs']['']['domain']))3364 {3365 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);3366 }3367 else3368 {3369 $scheme = null;3370 }3371 $categories[] =& new $this->feed->category_class($term, $scheme, null);3372 }3373 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)3374 {3375 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);3376 }3377 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)3378 {3379 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);3380 }3381 3382 if (!empty($categories))3383 {3384 return SimplePie_Misc::array_unique($categories);3385 }3386 else3387 {3388 return null;3389 }3390 }3391 3392 function get_author($key = 0)3393 {3394 $authors = $this->get_authors();3395 if (isset($authors[$key]))3396 {3397 return $authors[$key];3398 }3399 else3400 {3401 return null;3402 }3403 }3404 3405 function get_contributor($key = 0)3406 {3407 $contributors = $this->get_contributors();3408 if (isset($contributors[$key]))3409 {3410 return $contributors[$key];3411 }3412 else3413 {3414 return null;3415 }3416 }3417 3418 function get_contributors()3419 {3420 $contributors = array();3421 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)3422 {3423 $name = null;3424 $uri = null;3425 $email = null;3426 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))3427 {3428 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3429 }3430 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))3431 {3432 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));3433 }3434 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))3435 {3436 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3437 }3438 if ($name !== null || $email !== null || $uri !== null)3439 {3440 $contributors[] =& new $this->feed->author_class($name, $uri, $email);3441 }3442 }3443 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)3444 {3445 $name = null;3446 $url = null;3447 $email = null;3448 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))3449 {3450 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3451 }3452 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))3453 {3454 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));3455 }3456 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))3457 {3458 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3459 }3460 if ($name !== null || $email !== null || $url !== null)3461 {3462 $contributors[] =& new $this->feed->author_class($name, $url, $email);3463 }3464 }3465 3466 if (!empty($contributors))3467 {3468 return SimplePie_Misc::array_unique($contributors);3469 }3470 else3471 {3472 return null;3473 }3474 }3475 3476 function get_authors()3477 {3478 $authors = array();3479 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)3480 {3481 $name = null;3482 $uri = null;3483 $email = null;3484 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))3485 {3486 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3487 }3488 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))3489 {3490 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));3491 }3492 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))3493 {3494 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3495 }3496 if ($name !== null || $email !== null || $uri !== null)3497 {3498 $authors[] =& new $this->feed->author_class($name, $uri, $email);3499 }3500 }3501 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))3502 {3503 $name = null;3504 $url = null;3505 $email = null;3506 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))3507 {3508 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3509 }3510 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))3511 {3512 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));3513 }3514 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))3515 {3516 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3517 }3518 if ($name !== null || $email !== null || $url !== null)3519 {3520 $authors[] =& new $this->feed->author_class($name, $url, $email);3521 }3522 }3523 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))3524 {3525 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));3526 }3527 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)3528 {3529 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);3530 }3531 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)3532 {3533 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);3534 }3535 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)3536 {3537 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);3538 }3539 3540 if (!empty($authors))3541 {3542 return SimplePie_Misc::array_unique($authors);3543 }3544 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))3545 {3546 return $authors;3547 }3548 elseif ($authors = $this->feed->get_authors())3549 {3550 return $authors;3551 }3552 else3553 {3554 return null;3555 }3556 }3557 3558 function get_copyright()3559 {3560 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))3561 {3562 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));3563 }3564 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))3565 {3566 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3567 }3568 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))3569 {3570 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3571 }3572 else3573 {3574 return null;3575 }3576 }3577 3578 function get_date($date_format = 'j F Y, g:i a')3579 {3580 if (!isset($this->data['date']))3581 {3582 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))3583 {3584 $this->data['date']['raw'] = $return[0]['data'];3585 }3586 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))3587 {3588 $this->data['date']['raw'] = $return[0]['data'];3589 }3590 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))3591 {3592 $this->data['date']['raw'] = $return[0]['data'];3593 }3594 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))3595 {3596 $this->data['date']['raw'] = $return[0]['data'];3597 }3598 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))3599 {3600 $this->data['date']['raw'] = $return[0]['data'];3601 }3602 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))3603 {3604 $this->data['date']['raw'] = $return[0]['data'];3605 }3606 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))3607 {3608 $this->data['date']['raw'] = $return[0]['data'];3609 }3610 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))3611 {3612 $this->data['date']['raw'] = $return[0]['data'];3613 }3614 3615 if (!empty($this->data['date']['raw']))3616 {3617 $parser = SimplePie_Parse_Date::get();3618 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);3619 }3620 else3621 {3622 $this->data['date'] = null;3623 }3624 }3625 if ($this->data['date'])3626 {3627 $date_format = (string) $date_format;3628 switch ($date_format)3629 {3630 case '':3631 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);3632 3633 case 'U':3634 return $this->data['date']['parsed'];3635 3636 default:3637 return date($date_format, $this->data['date']['parsed']);3638 }3639 }3640 else3641 {3642 return null;3643 }3644 }3645 3646 function get_local_date($date_format = '%c')3647 {3648 if (!$date_format)3649 {3650 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);3651 }3652 elseif (($date = $this->get_date('U')) !== null && $date !== false)3653 {3654 return strftime($date_format, $date);3655 }3656 else3657 {3658 return null;3659 }3660 }3661 3662 function get_permalink()3663 {3664 $link = $this->get_link();3665 $enclosure = $this->get_enclosure(0);3666 if ($link !== null)3667 {3668 return $link;3669 }3670 elseif ($enclosure !== null)3671 {3672 return $enclosure->get_link();3673 }3674 else3675 {3676 return null;3677 }3678 }3679 3680 function get_link($key = 0, $rel = 'alternate')3681 {3682 $links = $this->get_links($rel);3683 if ($links[$key] !== null)3684 {3685 return $links[$key];3686 }3687 else3688 {3689 return null;3690 }3691 }3692 3693 function get_links($rel = 'alternate')3694 {3695 if (!isset($this->data['links']))3696 {3697 $this->data['links'] = array();3698 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)3699 {3700 if (isset($link['attribs']['']['href']))3701 {3702 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';3703 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));3704 3705 }3706 }3707 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)3708 {3709 if (isset($link['attribs']['']['href']))3710 {3711 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';3712 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));3713 }3714 }3715 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))3716 {3717 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));3718 }3719 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))3720 {3721 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));3722 }3723 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))3724 {3725 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));3726 }3727 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))3728 {3729 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')3730 {3731 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));3732 }3733 }3734 3735 $keys = array_keys($this->data['links']);3736 foreach ($keys as $key)3737 {3738 if (SimplePie_Misc::is_isegment_nz_nc($key))3739 {3740 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))3741 {3742 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);3743 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];3744 }3745 else3746 {3747 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];3748 }3749 }3750 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)3751 {3752 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];3753 }3754 $this->data['links'][$key] = array_unique($this->data['links'][$key]);3755 }3756 }3757 if (isset($this->data['links'][$rel]))3758 {3759 return $this->data['links'][$rel];3760 }3761 else3762 {3763 return null;3764 }3765 }3766 3767 /**3768 * @todo Add ability to prefer one type of content over another (in a media group).3769 */3770 function get_enclosure($key = 0, $prefer = null)3771 {3772 $enclosures = $this->get_enclosures();3773 if (isset($enclosures[$key]))3774 {3775 return $enclosures[$key];3776 }3777 else3778 {3779 return null;3780 }3781 }3782 3783 /**3784 * Grabs all available enclosures (podcasts, etc.)3785 *3786 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.3787 *3788 * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support.3789 *3790 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).3791 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).3792 */3793 function get_enclosures()3794 {3795 if (!isset($this->data['enclosures']))3796 {3797 $this->data['enclosures'] = array();3798 3799 // Elements3800 $captions_parent = null;3801 $categories_parent = null;3802 $copyrights_parent = null;3803 $credits_parent = null;3804 $description_parent = null;3805 $duration_parent = null;3806 $hashes_parent = null;3807 $keywords_parent = null;3808 $player_parent = null;3809 $ratings_parent = null;3810 $restrictions_parent = null;3811 $thumbnails_parent = null;3812 $title_parent = null;3813 3814 // Let's do the channel and item-level ones first, and just re-use them if we need to.3815 $parent = $this->get_feed();3816 3817 // CAPTIONS3818 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))3819 {3820 foreach ($captions as $caption)3821 {3822 $caption_type = null;3823 $caption_lang = null;3824 $caption_startTime = null;3825 $caption_endTime = null;3826 $caption_text = null;3827 if (isset($caption['attribs']['']['type']))3828 {3829 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);3830 }3831 if (isset($caption['attribs']['']['lang']))3832 {3833 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);3834 }3835 if (isset($caption['attribs']['']['start']))3836 {3837 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);3838 }3839 if (isset($caption['attribs']['']['end']))3840 {3841 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);3842 }3843 if (isset($caption['data']))3844 {3845 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);3846 }3847 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);3848 }3849 }3850 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))3851 {3852 foreach ($captions as $caption)3853 {3854 $caption_type = null;3855 $caption_lang = null;3856 $caption_startTime = null;3857 $caption_endTime = null;3858 $caption_text = null;3859 if (isset($caption['attribs']['']['type']))3860 {3861 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);3862 }3863 if (isset($caption['attribs']['']['lang']))3864 {3865 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);3866 }3867 if (isset($caption['attribs']['']['start']))3868 {3869 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);3870 }3871 if (isset($caption['attribs']['']['end']))3872 {3873 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);3874 }3875 if (isset($caption['data']))3876 {3877 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);3878 }3879 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);3880 }3881 }3882 if (is_array($captions_parent))3883 {3884 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));3885 }3886 3887 // CATEGORIES3888 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)3889 {3890 $term = null;3891 $scheme = null;3892 $label = null;3893 if (isset($category['data']))3894 {3895 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);3896 }3897 if (isset($category['attribs']['']['scheme']))3898 {3899 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);3900 }3901 else3902 {3903 $scheme = 'http://search.yahoo.com/mrss/category_schema';3904 }3905 if (isset($category['attribs']['']['label']))3906 {3907 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);3908 }3909 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);3910 }3911 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)3912 {3913 $term = null;3914 $scheme = null;3915 $label = null;3916 if (isset($category['data']))3917 {3918 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);3919 }3920 if (isset($category['attribs']['']['scheme']))3921 {3922 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);3923 }3924 else3925 {3926 $scheme = 'http://search.yahoo.com/mrss/category_schema';3927 }3928 if (isset($category['attribs']['']['label']))3929 {3930 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);3931 }3932 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);3933 }3934 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)3935 {3936 $term = null;3937 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';3938 $label = null;3939 if (isset($category['attribs']['']['text']))3940 {3941 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);3942 }3943 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);3944 3945 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))3946 {3947 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)3948 {3949 if (isset($subcategory['attribs']['']['text']))3950 {3951 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);3952 }3953 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);3954 }3955 }3956 }3957 if (is_array($categories_parent))3958 {3959 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));3960 }3961 3962 // COPYRIGHT3963 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))3964 {3965 $copyright_url = null;3966 $copyright_label = null;3967 if (isset($copyright[0]['attribs']['']['url']))3968 {3969 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);3970 }3971 if (isset($copyright[0]['data']))3972 {3973 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3974 }3975 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);3976 }3977 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))3978 {3979 $copyright_url = null;3980 $copyright_label = null;3981 if (isset($copyright[0]['attribs']['']['url']))3982 {3983 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);3984 }3985 if (isset($copyright[0]['data']))3986 {3987 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);3988 }3989 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);3990 }3991 3992 // CREDITS3993 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))3994 {3995 foreach ($credits as $credit)3996 {3997 $credit_role = null;3998 $credit_scheme = null;3999 $credit_name = null;4000 if (isset($credit['attribs']['']['role']))4001 {4002 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);4003 }4004 if (isset($credit['attribs']['']['scheme']))4005 {4006 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4007 }4008 else4009 {4010 $credit_scheme = 'urn:ebu';4011 }4012 if (isset($credit['data']))4013 {4014 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);4015 }4016 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);4017 }4018 }4019 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))4020 {4021 foreach ($credits as $credit)4022 {4023 $credit_role = null;4024 $credit_scheme = null;4025 $credit_name = null;4026 if (isset($credit['attribs']['']['role']))4027 {4028 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);4029 }4030 if (isset($credit['attribs']['']['scheme']))4031 {4032 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4033 }4034 else4035 {4036 $credit_scheme = 'urn:ebu';4037 }4038 if (isset($credit['data']))4039 {4040 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);4041 }4042 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);4043 }4044 }4045 if (is_array($credits_parent))4046 {4047 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));4048 }4049 4050 // DESCRIPTION4051 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))4052 {4053 if (isset($description_parent[0]['data']))4054 {4055 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4056 }4057 }4058 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))4059 {4060 if (isset($description_parent[0]['data']))4061 {4062 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4063 }4064 }4065 4066 // DURATION4067 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))4068 {4069 $seconds = null;4070 $minutes = null;4071 $hours = null;4072 if (isset($duration_parent[0]['data']))4073 {4074 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4075 if (sizeof($temp) > 0)4076 {4077 $seconds = (int) array_pop($temp);4078 }4079 if (sizeof($temp) > 0)4080 {4081 $minutes = (int) array_pop($temp);4082 $seconds += $minutes * 60;4083 }4084 if (sizeof($temp) > 0)4085 {4086 $hours = (int) array_pop($temp);4087 $seconds += $hours * 3600;4088 }4089 unset($temp);4090 $duration_parent = $seconds;4091 }4092 }4093 4094 // HASHES4095 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))4096 {4097 foreach ($hashes_iterator as $hash)4098 {4099 $value = null;4100 $algo = null;4101 if (isset($hash['data']))4102 {4103 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);4104 }4105 if (isset($hash['attribs']['']['algo']))4106 {4107 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);4108 }4109 else4110 {4111 $algo = 'md5';4112 }4113 $hashes_parent[] = $algo.':'.$value;4114 }4115 }4116 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))4117 {4118 foreach ($hashes_iterator as $hash)4119 {4120 $value = null;4121 $algo = null;4122 if (isset($hash['data']))4123 {4124 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);4125 }4126 if (isset($hash['attribs']['']['algo']))4127 {4128 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);4129 }4130 else4131 {4132 $algo = 'md5';4133 }4134 $hashes_parent[] = $algo.':'.$value;4135 }4136 }4137 if (is_array($hashes_parent))4138 {4139 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));4140 }4141 4142 // KEYWORDS4143 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))4144 {4145 if (isset($keywords[0]['data']))4146 {4147 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4148 foreach ($temp as $word)4149 {4150 $keywords_parent[] = trim($word);4151 }4152 }4153 unset($temp);4154 }4155 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))4156 {4157 if (isset($keywords[0]['data']))4158 {4159 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4160 foreach ($temp as $word)4161 {4162 $keywords_parent[] = trim($word);4163 }4164 }4165 unset($temp);4166 }4167 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))4168 {4169 if (isset($keywords[0]['data']))4170 {4171 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4172 foreach ($temp as $word)4173 {4174 $keywords_parent[] = trim($word);4175 }4176 }4177 unset($temp);4178 }4179 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))4180 {4181 if (isset($keywords[0]['data']))4182 {4183 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4184 foreach ($temp as $word)4185 {4186 $keywords_parent[] = trim($word);4187 }4188 }4189 unset($temp);4190 }4191 if (is_array($keywords_parent))4192 {4193 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));4194 }4195 4196 // PLAYER4197 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))4198 {4199 if (isset($player_parent[0]['attribs']['']['url']))4200 {4201 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4202 }4203 }4204 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))4205 {4206 if (isset($player_parent[0]['attribs']['']['url']))4207 {4208 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4209 }4210 }4211 4212 // RATINGS4213 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))4214 {4215 foreach ($ratings as $rating)4216 {4217 $rating_scheme = null;4218 $rating_value = null;4219 if (isset($rating['attribs']['']['scheme']))4220 {4221 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4222 }4223 else4224 {4225 $rating_scheme = 'urn:simple';4226 }4227 if (isset($rating['data']))4228 {4229 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4230 }4231 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4232 }4233 }4234 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))4235 {4236 foreach ($ratings as $rating)4237 {4238 $rating_scheme = 'urn:itunes';4239 $rating_value = null;4240 if (isset($rating['data']))4241 {4242 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4243 }4244 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4245 }4246 }4247 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))4248 {4249 foreach ($ratings as $rating)4250 {4251 $rating_scheme = null;4252 $rating_value = null;4253 if (isset($rating['attribs']['']['scheme']))4254 {4255 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4256 }4257 else4258 {4259 $rating_scheme = 'urn:simple';4260 }4261 if (isset($rating['data']))4262 {4263 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4264 }4265 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4266 }4267 }4268 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))4269 {4270 foreach ($ratings as $rating)4271 {4272 $rating_scheme = 'urn:itunes';4273 $rating_value = null;4274 if (isset($rating['data']))4275 {4276 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4277 }4278 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4279 }4280 }4281 if (is_array($ratings_parent))4282 {4283 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));4284 }4285 4286 // RESTRICTIONS4287 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))4288 {4289 foreach ($restrictions as $restriction)4290 {4291 $restriction_relationship = null;4292 $restriction_type = null;4293 $restriction_value = null;4294 if (isset($restriction['attribs']['']['relationship']))4295 {4296 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);4297 }4298 if (isset($restriction['attribs']['']['type']))4299 {4300 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4301 }4302 if (isset($restriction['data']))4303 {4304 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);4305 }4306 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);4307 }4308 }4309 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))4310 {4311 foreach ($restrictions as $restriction)4312 {4313 $restriction_relationship = 'allow';4314 $restriction_type = null;4315 $restriction_value = 'itunes';4316 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')4317 {4318 $restriction_relationship = 'deny';4319 }4320 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);4321 }4322 }4323 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))4324 {4325 foreach ($restrictions as $restriction)4326 {4327 $restriction_relationship = null;4328 $restriction_type = null;4329 $restriction_value = null;4330 if (isset($restriction['attribs']['']['relationship']))4331 {4332 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);4333 }4334 if (isset($restriction['attribs']['']['type']))4335 {4336 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4337 }4338 if (isset($restriction['data']))4339 {4340 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);4341 }4342 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);4343 }4344 }4345 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))4346 {4347 foreach ($restrictions as $restriction)4348 {4349 $restriction_relationship = 'allow';4350 $restriction_type = null;4351 $restriction_value = 'itunes';4352 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')4353 {4354 $restriction_relationship = 'deny';4355 }4356 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);4357 }4358 }4359 if (is_array($restrictions_parent))4360 {4361 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));4362 }4363 4364 // THUMBNAILS4365 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))4366 {4367 foreach ($thumbnails as $thumbnail)4368 {4369 if (isset($thumbnail['attribs']['']['url']))4370 {4371 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4372 }4373 }4374 }4375 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))4376 {4377 foreach ($thumbnails as $thumbnail)4378 {4379 if (isset($thumbnail['attribs']['']['url']))4380 {4381 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4382 }4383 }4384 }4385 4386 // TITLES4387 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))4388 {4389 if (isset($title_parent[0]['data']))4390 {4391 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4392 }4393 }4394 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))4395 {4396 if (isset($title_parent[0]['data']))4397 {4398 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4399 }4400 }4401 4402 // Clear the memory4403 unset($parent);4404 4405 // Attributes4406 $bitrate = null;4407 $channels = null;4408 $duration = null;4409 $expression = null;4410 $framerate = null;4411 $height = null;4412 $javascript = null;4413 $lang = null;4414 $length = null;4415 $medium = null;4416 $samplingrate = null;4417 $type = null;4418 $url = null;4419 $width = null;4420 4421 // Elements4422 $captions = null;4423 $categories = null;4424 $copyrights = null;4425 $credits = null;4426 $description = null;4427 $hashes = null;4428 $keywords = null;4429 $player = null;4430 $ratings = null;4431 $restrictions = null;4432 $thumbnails = null;4433 $title = null;4434 4435 // If we have media:group tags, loop through them.4436 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)4437 {4438 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))4439 {4440 // If we have media:content tags, loop through them.4441 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)4442 {4443 if (isset($content['attribs']['']['url']))4444 {4445 // Attributes4446 $bitrate = null;4447 $channels = null;4448 $duration = null;4449 $expression = null;4450 $framerate = null;4451 $height = null;4452 $javascript = null;4453 $lang = null;4454 $length = null;4455 $medium = null;4456 $samplingrate = null;4457 $type = null;4458 $url = null;4459 $width = null;4460 4461 // Elements4462 $captions = null;4463 $categories = null;4464 $copyrights = null;4465 $credits = null;4466 $description = null;4467 $hashes = null;4468 $keywords = null;4469 $player = null;4470 $ratings = null;4471 $restrictions = null;4472 $thumbnails = null;4473 $title = null;4474 4475 // Start checking the attributes of media:content4476 if (isset($content['attribs']['']['bitrate']))4477 {4478 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);4479 }4480 if (isset($content['attribs']['']['channels']))4481 {4482 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);4483 }4484 if (isset($content['attribs']['']['duration']))4485 {4486 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);4487 }4488 else4489 {4490 $duration = $duration_parent;4491 }4492 if (isset($content['attribs']['']['expression']))4493 {4494 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);4495 }4496 if (isset($content['attribs']['']['framerate']))4497 {4498 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);4499 }4500 if (isset($content['attribs']['']['height']))4501 {4502 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);4503 }4504 if (isset($content['attribs']['']['lang']))4505 {4506 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);4507 }4508 if (isset($content['attribs']['']['fileSize']))4509 {4510 $length = ceil($content['attribs']['']['fileSize']);4511 }4512 if (isset($content['attribs']['']['medium']))4513 {4514 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);4515 }4516 if (isset($content['attribs']['']['samplingrate']))4517 {4518 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);4519 }4520 if (isset($content['attribs']['']['type']))4521 {4522 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4523 }4524 if (isset($content['attribs']['']['width']))4525 {4526 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);4527 }4528 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4529 4530 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel4531 4532 // CAPTIONS4533 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))4534 {4535 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)4536 {4537 $caption_type = null;4538 $caption_lang = null;4539 $caption_startTime = null;4540 $caption_endTime = null;4541 $caption_text = null;4542 if (isset($caption['attribs']['']['type']))4543 {4544 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4545 }4546 if (isset($caption['attribs']['']['lang']))4547 {4548 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);4549 }4550 if (isset($caption['attribs']['']['start']))4551 {4552 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);4553 }4554 if (isset($caption['attribs']['']['end']))4555 {4556 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);4557 }4558 if (isset($caption['data']))4559 {4560 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);4561 }4562 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);4563 }4564 if (is_array($captions))4565 {4566 $captions = array_values(SimplePie_Misc::array_unique($captions));4567 }4568 }4569 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))4570 {4571 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)4572 {4573 $caption_type = null;4574 $caption_lang = null;4575 $caption_startTime = null;4576 $caption_endTime = null;4577 $caption_text = null;4578 if (isset($caption['attribs']['']['type']))4579 {4580 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4581 }4582 if (isset($caption['attribs']['']['lang']))4583 {4584 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);4585 }4586 if (isset($caption['attribs']['']['start']))4587 {4588 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);4589 }4590 if (isset($caption['attribs']['']['end']))4591 {4592 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);4593 }4594 if (isset($caption['data']))4595 {4596 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);4597 }4598 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);4599 }4600 if (is_array($captions))4601 {4602 $captions = array_values(SimplePie_Misc::array_unique($captions));4603 }4604 }4605 else4606 {4607 $captions = $captions_parent;4608 }4609 4610 // CATEGORIES4611 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))4612 {4613 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)4614 {4615 $term = null;4616 $scheme = null;4617 $label = null;4618 if (isset($category['data']))4619 {4620 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);4621 }4622 if (isset($category['attribs']['']['scheme']))4623 {4624 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4625 }4626 else4627 {4628 $scheme = 'http://search.yahoo.com/mrss/category_schema';4629 }4630 if (isset($category['attribs']['']['label']))4631 {4632 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);4633 }4634 $categories[] =& new $this->feed->category_class($term, $scheme, $label);4635 }4636 }4637 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))4638 {4639 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)4640 {4641 $term = null;4642 $scheme = null;4643 $label = null;4644 if (isset($category['data']))4645 {4646 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);4647 }4648 if (isset($category['attribs']['']['scheme']))4649 {4650 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4651 }4652 else4653 {4654 $scheme = 'http://search.yahoo.com/mrss/category_schema';4655 }4656 if (isset($category['attribs']['']['label']))4657 {4658 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);4659 }4660 $categories[] =& new $this->feed->category_class($term, $scheme, $label);4661 }4662 }4663 if (is_array($categories) && is_array($categories_parent))4664 {4665 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));4666 }4667 elseif (is_array($categories))4668 {4669 $categories = array_values(SimplePie_Misc::array_unique($categories));4670 }4671 elseif (is_array($categories_parent))4672 {4673 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));4674 }4675 4676 // COPYRIGHTS4677 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))4678 {4679 $copyright_url = null;4680 $copyright_label = null;4681 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))4682 {4683 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);4684 }4685 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))4686 {4687 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4688 }4689 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);4690 }4691 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))4692 {4693 $copyright_url = null;4694 $copyright_label = null;4695 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))4696 {4697 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);4698 }4699 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))4700 {4701 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4702 }4703 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);4704 }4705 else4706 {4707 $copyrights = $copyrights_parent;4708 }4709 4710 // CREDITS4711 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))4712 {4713 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)4714 {4715 $credit_role = null;4716 $credit_scheme = null;4717 $credit_name = null;4718 if (isset($credit['attribs']['']['role']))4719 {4720 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);4721 }4722 if (isset($credit['attribs']['']['scheme']))4723 {4724 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4725 }4726 else4727 {4728 $credit_scheme = 'urn:ebu';4729 }4730 if (isset($credit['data']))4731 {4732 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);4733 }4734 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);4735 }4736 if (is_array($credits))4737 {4738 $credits = array_values(SimplePie_Misc::array_unique($credits));4739 }4740 }4741 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))4742 {4743 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)4744 {4745 $credit_role = null;4746 $credit_scheme = null;4747 $credit_name = null;4748 if (isset($credit['attribs']['']['role']))4749 {4750 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);4751 }4752 if (isset($credit['attribs']['']['scheme']))4753 {4754 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4755 }4756 else4757 {4758 $credit_scheme = 'urn:ebu';4759 }4760 if (isset($credit['data']))4761 {4762 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);4763 }4764 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);4765 }4766 if (is_array($credits))4767 {4768 $credits = array_values(SimplePie_Misc::array_unique($credits));4769 }4770 }4771 else4772 {4773 $credits = $credits_parent;4774 }4775 4776 // DESCRIPTION4777 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))4778 {4779 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4780 }4781 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))4782 {4783 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);4784 }4785 else4786 {4787 $description = $description_parent;4788 }4789 4790 // HASHES4791 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))4792 {4793 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)4794 {4795 $value = null;4796 $algo = null;4797 if (isset($hash['data']))4798 {4799 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);4800 }4801 if (isset($hash['attribs']['']['algo']))4802 {4803 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);4804 }4805 else4806 {4807 $algo = 'md5';4808 }4809 $hashes[] = $algo.':'.$value;4810 }4811 if (is_array($hashes))4812 {4813 $hashes = array_values(SimplePie_Misc::array_unique($hashes));4814 }4815 }4816 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))4817 {4818 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)4819 {4820 $value = null;4821 $algo = null;4822 if (isset($hash['data']))4823 {4824 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);4825 }4826 if (isset($hash['attribs']['']['algo']))4827 {4828 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);4829 }4830 else4831 {4832 $algo = 'md5';4833 }4834 $hashes[] = $algo.':'.$value;4835 }4836 if (is_array($hashes))4837 {4838 $hashes = array_values(SimplePie_Misc::array_unique($hashes));4839 }4840 }4841 else4842 {4843 $hashes = $hashes_parent;4844 }4845 4846 // KEYWORDS4847 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))4848 {4849 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))4850 {4851 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4852 foreach ($temp as $word)4853 {4854 $keywords[] = trim($word);4855 }4856 unset($temp);4857 }4858 if (is_array($keywords))4859 {4860 $keywords = array_values(SimplePie_Misc::array_unique($keywords));4861 }4862 }4863 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))4864 {4865 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))4866 {4867 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));4868 foreach ($temp as $word)4869 {4870 $keywords[] = trim($word);4871 }4872 unset($temp);4873 }4874 if (is_array($keywords))4875 {4876 $keywords = array_values(SimplePie_Misc::array_unique($keywords));4877 }4878 }4879 else4880 {4881 $keywords = $keywords_parent;4882 }4883 4884 // PLAYER4885 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))4886 {4887 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4888 }4889 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))4890 {4891 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);4892 }4893 else4894 {4895 $player = $player_parent;4896 }4897 4898 // RATINGS4899 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))4900 {4901 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)4902 {4903 $rating_scheme = null;4904 $rating_value = null;4905 if (isset($rating['attribs']['']['scheme']))4906 {4907 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4908 }4909 else4910 {4911 $rating_scheme = 'urn:simple';4912 }4913 if (isset($rating['data']))4914 {4915 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4916 }4917 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4918 }4919 if (is_array($ratings))4920 {4921 $ratings = array_values(SimplePie_Misc::array_unique($ratings));4922 }4923 }4924 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))4925 {4926 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)4927 {4928 $rating_scheme = null;4929 $rating_value = null;4930 if (isset($rating['attribs']['']['scheme']))4931 {4932 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);4933 }4934 else4935 {4936 $rating_scheme = 'urn:simple';4937 }4938 if (isset($rating['data']))4939 {4940 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);4941 }4942 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);4943 }4944 if (is_array($ratings))4945 {4946 $ratings = array_values(SimplePie_Misc::array_unique($ratings));4947 }4948 }4949 else4950 {4951 $ratings = $ratings_parent;4952 }4953 4954 // RESTRICTIONS4955 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))4956 {4957 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)4958 {4959 $restriction_relationship = null;4960 $restriction_type = null;4961 $restriction_value = null;4962 if (isset($restriction['attribs']['']['relationship']))4963 {4964 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);4965 }4966 if (isset($restriction['attribs']['']['type']))4967 {4968 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4969 }4970 if (isset($restriction['data']))4971 {4972 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);4973 }4974 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);4975 }4976 if (is_array($restrictions))4977 {4978 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));4979 }4980 }4981 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))4982 {4983 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)4984 {4985 $restriction_relationship = null;4986 $restriction_type = null;4987 $restriction_value = null;4988 if (isset($restriction['attribs']['']['relationship']))4989 {4990 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);4991 }4992 if (isset($restriction['attribs']['']['type']))4993 {4994 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);4995 }4996 if (isset($restriction['data']))4997 {4998 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);4999 }5000 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);5001 }5002 if (is_array($restrictions))5003 {5004 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));5005 }5006 }5007 else5008 {5009 $restrictions = $restrictions_parent;5010 }5011 5012 // THUMBNAILS5013 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))5014 {5015 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)5016 {5017 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);5018 }5019 if (is_array($thumbnails))5020 {5021 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));5022 }5023 }5024 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))5025 {5026 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)5027 {5028 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);5029 }5030 if (is_array($thumbnails))5031 {5032 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));5033 }5034 }5035 else5036 {5037 $thumbnails = $thumbnails_parent;5038 }5039 5040 // TITLES5041 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))5042 {5043 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5044 }5045 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))5046 {5047 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5048 }5049 else5050 {5051 $title = $title_parent;5052 }5053 5054 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);5055 }5056 }5057 }5058 }5059 5060 // If we have standalone media:content tags, loop through them.5061 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))5062 {5063 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)5064 {5065 if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))5066 {5067 // Attributes5068 $bitrate = null;5069 $channels = null;5070 $duration = null;5071 $expression = null;5072 $framerate = null;5073 $height = null;5074 $javascript = null;5075 $lang = null;5076 $length = null;5077 $medium = null;5078 $samplingrate = null;5079 $type = null;5080 $url = null;5081 $width = null;5082 5083 // Elements5084 $captions = null;5085 $categories = null;5086 $copyrights = null;5087 $credits = null;5088 $description = null;5089 $hashes = null;5090 $keywords = null;5091 $player = null;5092 $ratings = null;5093 $restrictions = null;5094 $thumbnails = null;5095 $title = null;5096 5097 // Start checking the attributes of media:content5098 if (isset($content['attribs']['']['bitrate']))5099 {5100 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);5101 }5102 if (isset($content['attribs']['']['channels']))5103 {5104 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);5105 }5106 if (isset($content['attribs']['']['duration']))5107 {5108 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);5109 }5110 else5111 {5112 $duration = $duration_parent;5113 }5114 if (isset($content['attribs']['']['expression']))5115 {5116 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);5117 }5118 if (isset($content['attribs']['']['framerate']))5119 {5120 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);5121 }5122 if (isset($content['attribs']['']['height']))5123 {5124 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);5125 }5126 if (isset($content['attribs']['']['lang']))5127 {5128 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);5129 }5130 if (isset($content['attribs']['']['fileSize']))5131 {5132 $length = ceil($content['attribs']['']['fileSize']);5133 }5134 if (isset($content['attribs']['']['medium']))5135 {5136 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);5137 }5138 if (isset($content['attribs']['']['samplingrate']))5139 {5140 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);5141 }5142 if (isset($content['attribs']['']['type']))5143 {5144 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5145 }5146 if (isset($content['attribs']['']['width']))5147 {5148 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);5149 }5150 if (isset($content['attribs']['']['url']))5151 {5152 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);5153 }5154 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel5155 5156 // CAPTIONS5157 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))5158 {5159 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)5160 {5161 $caption_type = null;5162 $caption_lang = null;5163 $caption_startTime = null;5164 $caption_endTime = null;5165 $caption_text = null;5166 if (isset($caption['attribs']['']['type']))5167 {5168 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5169 }5170 if (isset($caption['attribs']['']['lang']))5171 {5172 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);5173 }5174 if (isset($caption['attribs']['']['start']))5175 {5176 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);5177 }5178 if (isset($caption['attribs']['']['end']))5179 {5180 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);5181 }5182 if (isset($caption['data']))5183 {5184 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);5185 }5186 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);5187 }5188 if (is_array($captions))5189 {5190 $captions = array_values(SimplePie_Misc::array_unique($captions));5191 }5192 }5193 else5194 {5195 $captions = $captions_parent;5196 }5197 5198 // CATEGORIES5199 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))5200 {5201 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)5202 {5203 $term = null;5204 $scheme = null;5205 $label = null;5206 if (isset($category['data']))5207 {5208 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);5209 }5210 if (isset($category['attribs']['']['scheme']))5211 {5212 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);5213 }5214 else5215 {5216 $scheme = 'http://search.yahoo.com/mrss/category_schema';5217 }5218 if (isset($category['attribs']['']['label']))5219 {5220 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);5221 }5222 $categories[] =& new $this->feed->category_class($term, $scheme, $label);5223 }5224 }5225 if (is_array($categories) && is_array($categories_parent))5226 {5227 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));5228 }5229 elseif (is_array($categories))5230 {5231 $categories = array_values(SimplePie_Misc::array_unique($categories));5232 }5233 elseif (is_array($categories_parent))5234 {5235 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));5236 }5237 else5238 {5239 $categories = null;5240 }5241 5242 // COPYRIGHTS5243 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))5244 {5245 $copyright_url = null;5246 $copyright_label = null;5247 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))5248 {5249 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);5250 }5251 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))5252 {5253 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5254 }5255 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);5256 }5257 else5258 {5259 $copyrights = $copyrights_parent;5260 }5261 5262 // CREDITS5263 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))5264 {5265 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)5266 {5267 $credit_role = null;5268 $credit_scheme = null;5269 $credit_name = null;5270 if (isset($credit['attribs']['']['role']))5271 {5272 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);5273 }5274 if (isset($credit['attribs']['']['scheme']))5275 {5276 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);5277 }5278 else5279 {5280 $credit_scheme = 'urn:ebu';5281 }5282 if (isset($credit['data']))5283 {5284 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);5285 }5286 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);5287 }5288 if (is_array($credits))5289 {5290 $credits = array_values(SimplePie_Misc::array_unique($credits));5291 }5292 }5293 else5294 {5295 $credits = $credits_parent;5296 }5297 5298 // DESCRIPTION5299 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))5300 {5301 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5302 }5303 else5304 {5305 $description = $description_parent;5306 }5307 5308 // HASHES5309 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))5310 {5311 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)5312 {5313 $value = null;5314 $algo = null;5315 if (isset($hash['data']))5316 {5317 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);5318 }5319 if (isset($hash['attribs']['']['algo']))5320 {5321 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);5322 }5323 else5324 {5325 $algo = 'md5';5326 }5327 $hashes[] = $algo.':'.$value;5328 }5329 if (is_array($hashes))5330 {5331 $hashes = array_values(SimplePie_Misc::array_unique($hashes));5332 }5333 }5334 else5335 {5336 $hashes = $hashes_parent;5337 }5338 5339 // KEYWORDS5340 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))5341 {5342 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))5343 {5344 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));5345 foreach ($temp as $word)5346 {5347 $keywords[] = trim($word);5348 }5349 unset($temp);5350 }5351 if (is_array($keywords))5352 {5353 $keywords = array_values(SimplePie_Misc::array_unique($keywords));5354 }5355 }5356 else5357 {5358 $keywords = $keywords_parent;5359 }5360 5361 // PLAYER5362 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))5363 {5364 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);5365 }5366 else5367 {5368 $player = $player_parent;5369 }5370 5371 // RATINGS5372 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))5373 {5374 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)5375 {5376 $rating_scheme = null;5377 $rating_value = null;5378 if (isset($rating['attribs']['']['scheme']))5379 {5380 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);5381 }5382 else5383 {5384 $rating_scheme = 'urn:simple';5385 }5386 if (isset($rating['data']))5387 {5388 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);5389 }5390 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);5391 }5392 if (is_array($ratings))5393 {5394 $ratings = array_values(SimplePie_Misc::array_unique($ratings));5395 }5396 }5397 else5398 {5399 $ratings = $ratings_parent;5400 }5401 5402 // RESTRICTIONS5403 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))5404 {5405 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)5406 {5407 $restriction_relationship = null;5408 $restriction_type = null;5409 $restriction_value = null;5410 if (isset($restriction['attribs']['']['relationship']))5411 {5412 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);5413 }5414 if (isset($restriction['attribs']['']['type']))5415 {5416 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5417 }5418 if (isset($restriction['data']))5419 {5420 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);5421 }5422 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);5423 }5424 if (is_array($restrictions))5425 {5426 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));5427 }5428 }5429 else5430 {5431 $restrictions = $restrictions_parent;5432 }5433 5434 // THUMBNAILS5435 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))5436 {5437 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)5438 {5439 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);5440 }5441 if (is_array($thumbnails))5442 {5443 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));5444 }5445 }5446 else5447 {5448 $thumbnails = $thumbnails_parent;5449 }5450 5451 // TITLES5452 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))5453 {5454 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5455 }5456 else5457 {5458 $title = $title_parent;5459 }5460 5461 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);5462 }5463 }5464 }5465 5466 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)5467 {5468 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')5469 {5470 // Attributes5471 $bitrate = null;5472 $channels = null;5473 $duration = null;5474 $expression = null;5475 $framerate = null;5476 $height = null;5477 $javascript = null;5478 $lang = null;5479 $length = null;5480 $medium = null;5481 $samplingrate = null;5482 $type = null;5483 $url = null;5484 $width = null;5485 5486 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));5487 if (isset($link['attribs']['']['type']))5488 {5489 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5490 }5491 if (isset($link['attribs']['']['length']))5492 {5493 $length = ceil($link['attribs']['']['length']);5494 }5495 5496 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor5497 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);5498 }5499 }5500 5501 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)5502 {5503 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')5504 {5505 // Attributes5506 $bitrate = null;5507 $channels = null;5508 $duration = null;5509 $expression = null;5510 $framerate = null;5511 $height = null;5512 $javascript = null;5513 $lang = null;5514 $length = null;5515 $medium = null;5516 $samplingrate = null;5517 $type = null;5518 $url = null;5519 $width = null;5520 5521 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));5522 if (isset($link['attribs']['']['type']))5523 {5524 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5525 }5526 if (isset($link['attribs']['']['length']))5527 {5528 $length = ceil($link['attribs']['']['length']);5529 }5530 5531 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor5532 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);5533 }5534 }5535 5536 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))5537 {5538 if (isset($enclosure[0]['attribs']['']['url']))5539 {5540 // Attributes5541 $bitrate = null;5542 $channels = null;5543 $duration = null;5544 $expression = null;5545 $framerate = null;5546 $height = null;5547 $javascript = null;5548 $lang = null;5549 $length = null;5550 $medium = null;5551 $samplingrate = null;5552 $type = null;5553 $url = null;5554 $width = null;5555 5556 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));5557 if (isset($enclosure[0]['attribs']['']['type']))5558 {5559 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);5560 }5561 if (isset($enclosure[0]['attribs']['']['length']))5562 {5563 $length = ceil($enclosure[0]['attribs']['']['length']);5564 }5565 5566 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor5567 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);5568 }5569 }5570 5571 if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))5572 {5573 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor5574 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);5575 }5576 5577 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));5578 }5579 if (!empty($this->data['enclosures']))5580 {5581 return $this->data['enclosures'];5582 }5583 else5584 {5585 return null;5586 }5587 }5588 5589 function get_latitude()5590 {5591 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))5592 {5593 return (float) $return[0]['data'];5594 }5595 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))5596 {5597 return (float) $match[1];5598 }5599 else5600 {5601 return null;5602 }5603 }5604 5605 function get_longitude()5606 {5607 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))5608 {5609 return (float) $return[0]['data'];5610 }5611 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))5612 {5613 return (float) $return[0]['data'];5614 }5615 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))5616 {5617 return (float) $match[2];5618 }5619 else5620 {5621 return null;5622 }5623 }5624 5625 function get_source()5626 {5627 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))5628 {5629 return new $this->feed->source_class($this, $return[0]);5630 }5631 else5632 {5633 return null;5634 }5635 }5636 5637 /**5638 * Creates the add_to_* methods' return data5639 *5640 * @access private5641 * @param string $item_url String to prefix to the item permalink5642 * @param string $title_url String to prefix to the item title5643 * (and suffix to the item permalink)5644 * @return mixed URL if feed exists, false otherwise5645 */5646 function add_to_service($item_url, $title_url = null, $summary_url = null)5647 {5648 if ($this->get_permalink() !== null)5649 {5650 $return = $item_url . rawurlencode($this->get_permalink());5651 if ($title_url !== null && $this->get_title() !== null)5652 {5653 $return .= $title_url . rawurlencode($this->get_title());5654 }5655 if ($summary_url !== null && $this->get_description() !== null)5656 {5657 $return .= $summary_url . rawurlencode($this->get_description());5658 }5659 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);5660 }5661 else5662 {5663 return null;5664 }5665 }5666 5667 function add_to_blinklist()5668 {5669 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');5670 }5671 5672 function add_to_blogmarks()5673 {5674 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');5675 }5676 5677 function add_to_delicious()5678 {5679 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');5680 }5681 5682 function add_to_digg()5683 {5684 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');5685 }5686 5687 function add_to_furl()5688 {5689 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');5690 }5691 5692 function add_to_magnolia()5693 {5694 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');5695 }5696 5697 function add_to_myweb20()5698 {5699 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');5700 }5701 5702 function add_to_newsvine()5703 {5704 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');5705 }5706 5707 function add_to_reddit()5708 {5709 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');5710 }5711 5712 function add_to_segnalo()5713 {5714 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');5715 }5716 5717 function add_to_simpy()5718 {5719 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');5720 }5721 5722 function add_to_spurl()5723 {5724 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');5725 }5726 5727 function add_to_wists()5728 {5729 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');5730 }5731 5732 function search_technorati()5733 {5734 return $this->add_to_service('http://www.technorati.com/search/');5735 }5736 }5737 5738 class SimplePie_Source5739 {5740 var $item;5741 var $data = array();5742 5743 function SimplePie_Source($item, $data)5744 {5745 $this->item = $item;5746 $this->data = $data;5747 }5748 5749 function __toString()5750 {5751 return md5(serialize($this->data));5752 }5753 5754 function get_source_tags($namespace, $tag)5755 {5756 if (isset($this->data['child'][$namespace][$tag]))5757 {5758 return $this->data['child'][$namespace][$tag];5759 }5760 else5761 {5762 return null;5763 }5764 }5765 5766 function get_base($element = array())5767 {5768 return $this->item->get_base($element);5769 }5770 5771 function sanitize($data, $type, $base = '')5772 {5773 return $this->item->sanitize($data, $type, $base);5774 }5775 5776 function get_item()5777 {5778 return $this->item;5779 }5780 5781 function get_title()5782 {5783 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))5784 {5785 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));5786 }5787 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))5788 {5789 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));5790 }5791 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))5792 {5793 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));5794 }5795 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))5796 {5797 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));5798 }5799 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))5800 {5801 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));5802 }5803 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))5804 {5805 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5806 }5807 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))5808 {5809 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5810 }5811 else5812 {5813 return null;5814 }5815 }5816 5817 function get_category($key = 0)5818 {5819 $categories = $this->get_categories();5820 if (isset($categories[$key]))5821 {5822 return $categories[$key];5823 }5824 else5825 {5826 return null;5827 }5828 }5829 5830 function get_categories()5831 {5832 $categories = array();5833 5834 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)5835 {5836 $term = null;5837 $scheme = null;5838 $label = null;5839 if (isset($category['attribs']['']['term']))5840 {5841 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);5842 }5843 if (isset($category['attribs']['']['scheme']))5844 {5845 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);5846 }5847 if (isset($category['attribs']['']['label']))5848 {5849 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);5850 }5851 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);5852 }5853 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)5854 {5855 // This is really the label, but keep this as the term also for BC.5856 // Label will also work on retrieving because that falls back to term.5857 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);5858 if (isset($category['attribs']['']['domain']))5859 {5860 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);5861 }5862 else5863 {5864 $scheme = null;5865 }5866 $categories[] =& new $this->item->feed->category_class($term, $scheme, null);5867 }5868 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)5869 {5870 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);5871 }5872 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)5873 {5874 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);5875 }5876 5877 if (!empty($categories))5878 {5879 return SimplePie_Misc::array_unique($categories);5880 }5881 else5882 {5883 return null;5884 }5885 }5886 5887 function get_author($key = 0)5888 {5889 $authors = $this->get_authors();5890 if (isset($authors[$key]))5891 {5892 return $authors[$key];5893 }5894 else5895 {5896 return null;5897 }5898 }5899 5900 function get_authors()5901 {5902 $authors = array();5903 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)5904 {5905 $name = null;5906 $uri = null;5907 $email = null;5908 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))5909 {5910 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5911 }5912 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))5913 {5914 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));5915 }5916 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))5917 {5918 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5919 }5920 if ($name !== null || $email !== null || $uri !== null)5921 {5922 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);5923 }5924 }5925 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))5926 {5927 $name = null;5928 $url = null;5929 $email = null;5930 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))5931 {5932 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5933 }5934 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))5935 {5936 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));5937 }5938 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))5939 {5940 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5941 }5942 if ($name !== null || $email !== null || $url !== null)5943 {5944 $authors[] =& new $this->item->feed->author_class($name, $url, $email);5945 }5946 }5947 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)5948 {5949 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);5950 }5951 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)5952 {5953 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);5954 }5955 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)5956 {5957 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);5958 }5959 5960 if (!empty($authors))5961 {5962 return SimplePie_Misc::array_unique($authors);5963 }5964 else5965 {5966 return null;5967 }5968 }5969 5970 function get_contributor($key = 0)5971 {5972 $contributors = $this->get_contributors();5973 if (isset($contributors[$key]))5974 {5975 return $contributors[$key];5976 }5977 else5978 {5979 return null;5980 }5981 }5982 5983 function get_contributors()5984 {5985 $contributors = array();5986 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)5987 {5988 $name = null;5989 $uri = null;5990 $email = null;5991 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))5992 {5993 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);5994 }5995 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))5996 {5997 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));5998 }5999 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))6000 {6001 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6002 }6003 if ($name !== null || $email !== null || $uri !== null)6004 {6005 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);6006 }6007 }6008 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)6009 {6010 $name = null;6011 $url = null;6012 $email = null;6013 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))6014 {6015 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6016 }6017 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))6018 {6019 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));6020 }6021 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))6022 {6023 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6024 }6025 if ($name !== null || $email !== null || $url !== null)6026 {6027 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);6028 }6029 }6030 6031 if (!empty($contributors))6032 {6033 return SimplePie_Misc::array_unique($contributors);6034 }6035 else6036 {6037 return null;6038 }6039 }6040 6041 function get_link($key = 0, $rel = 'alternate')6042 {6043 $links = $this->get_links($rel);6044 if (isset($links[$key]))6045 {6046 return $links[$key];6047 }6048 else6049 {6050 return null;6051 }6052 }6053 6054 /**6055 * Added for parity between the parent-level and the item/entry-level.6056 */6057 function get_permalink()6058 {6059 return $this->get_link(0);6060 }6061 6062 function get_links($rel = 'alternate')6063 {6064 if (!isset($this->data['links']))6065 {6066 $this->data['links'] = array();6067 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))6068 {6069 foreach ($links as $link)6070 {6071 if (isset($link['attribs']['']['href']))6072 {6073 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';6074 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));6075 }6076 }6077 }6078 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))6079 {6080 foreach ($links as $link)6081 {6082 if (isset($link['attribs']['']['href']))6083 {6084 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';6085 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));6086 6087 }6088 }6089 }6090 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))6091 {6092 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));6093 }6094 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))6095 {6096 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));6097 }6098 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))6099 {6100 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));6101 }6102 6103 $keys = array_keys($this->data['links']);6104 foreach ($keys as $key)6105 {6106 if (SimplePie_Misc::is_isegment_nz_nc($key))6107 {6108 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))6109 {6110 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);6111 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];6112 }6113 else6114 {6115 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];6116 }6117 }6118 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)6119 {6120 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];6121 }6122 $this->data['links'][$key] = array_unique($this->data['links'][$key]);6123 }6124 }6125 6126 if (isset($this->data['links'][$rel]))6127 {6128 return $this->data['links'][$rel];6129 }6130 else6131 {6132 return null;6133 }6134 }6135 6136 function get_description()6137 {6138 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))6139 {6140 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));6141 }6142 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))6143 {6144 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));6145 }6146 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))6147 {6148 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));6149 }6150 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))6151 {6152 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));6153 }6154 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))6155 {6156 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));6157 }6158 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))6159 {6160 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6161 }6162 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))6163 {6164 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6165 }6166 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))6167 {6168 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));6169 }6170 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))6171 {6172 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));6173 }6174 else6175 {6176 return null;6177 }6178 }6179 6180 function get_copyright()6181 {6182 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))6183 {6184 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));6185 }6186 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))6187 {6188 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));6189 }6190 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))6191 {6192 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6193 }6194 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))6195 {6196 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6197 }6198 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))6199 {6200 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6201 }6202 else6203 {6204 return null;6205 }6206 }6207 6208 function get_language()6209 {6210 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))6211 {6212 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6213 }6214 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))6215 {6216 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6217 }6218 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))6219 {6220 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);6221 }6222 elseif (isset($this->data['xml_lang']))6223 {6224 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);6225 }6226 else6227 {6228 return null;6229 }6230 }6231 6232 function get_latitude()6233 {6234 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))6235 {6236 return (float) $return[0]['data'];6237 }6238 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))6239 {6240 return (float) $match[1];6241 }6242 else6243 {6244 return null;6245 }6246 }6247 6248 function get_longitude()6249 {6250 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))6251 {6252 return (float) $return[0]['data'];6253 }6254 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))6255 {6256 return (float) $return[0]['data'];6257 }6258 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))6259 {6260 return (float) $match[2];6261 }6262 else6263 {6264 return null;6265 }6266 }6267 6268 function get_image_url()6269 {6270 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))6271 {6272 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);6273 }6274 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))6275 {6276 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));6277 }6278 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))6279 {6280 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));6281 }6282 else6283 {6284 return null;6285 }6286 }6287 }6288 6289 class SimplePie_Author6290 {6291 var $name;6292 var $link;6293 var $email;6294 6295 // Constructor, used to input the data6296 function SimplePie_Author($name = null, $link = null, $email = null)6297 {6298 $this->name = $name;6299 $this->link = $link;6300 $this->email = $email;6301 }6302 6303 function __toString()6304 {6305 // There is no $this->data here6306 return md5(serialize($this));6307 }6308 6309 function get_name()6310 {6311 if ($this->name !== null)6312 {6313 return $this->name;6314 }6315 else6316 {6317 return null;6318 }6319 }6320 6321 function get_link()6322 {6323 if ($this->link !== null)6324 {6325 return $this->link;6326 }6327 else6328 {6329 return null;6330 }6331 }6332 6333 function get_email()6334 {6335 if ($this->email !== null)6336 {6337 return $this->email;6338 }6339 else6340 {6341 return null;6342 }6343 }6344 }6345 6346 class SimplePie_Category6347 {6348 var $term;6349 var $scheme;6350 var $label;6351 6352 // Constructor, used to input the data6353 function SimplePie_Category($term = null, $scheme = null, $label = null)6354 {6355 $this->term = $term;6356 $this->scheme = $scheme;6357 $this->label = $label;6358 }6359 6360 function __toString()6361 {6362 // There is no $this->data here6363 return md5(serialize($this));6364 }6365 6366 function get_term()6367 {6368 if ($this->term !== null)6369 {6370 return $this->term;6371 }6372 else6373 {6374 return null;6375 }6376 }6377 6378 function get_scheme()6379 {6380 if ($this->scheme !== null)6381 {6382 return $this->scheme;6383 }6384 else6385 {6386 return null;6387 }6388 }6389 6390 function get_label()6391 {6392 if ($this->label !== null)6393 {6394 return $this->label;6395 }6396 else6397 {6398 return $this->get_term();6399 }6400 }6401 }6402 6403 class SimplePie_Enclosure6404 {6405 var $bitrate;6406 var $captions;6407 var $categories;6408 var $channels;6409 var $copyright;6410 var $credits;6411 var $description;6412 var $duration;6413 var $expression;6414 var $framerate;6415 var $handler;6416 var $hashes;6417 var $height;6418 var $javascript;6419 var $keywords;6420 var $lang;6421 var $length;6422 var $link;6423 var $medium;6424 var $player;6425 var $ratings;6426 var $restrictions;6427 var $samplingrate;6428 var $thumbnails;6429 var $title;6430 var $type;6431 var $width;6432 6433 // Constructor, used to input the data6434 function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)6435 {6436 $this->bitrate = $bitrate;6437 $this->captions = $captions;6438 $this->categories = $categories;6439 $this->channels = $channels;6440 $this->copyright = $copyright;6441 $this->credits = $credits;6442 $this->description = $description;6443 $this->duration = $duration;6444 $this->expression = $expression;6445 $this->framerate = $framerate;6446 $this->hashes = $hashes;6447 $this->height = $height;6448 $this->javascript = $javascript;6449 $this->keywords = $keywords;6450 $this->lang = $lang;6451 $this->length = $length;6452 $this->link = $link;6453 $this->medium = $medium;6454 $this->player = $player;6455 $this->ratings = $ratings;6456 $this->restrictions = $restrictions;6457 $this->samplingrate = $samplingrate;6458 $this->thumbnails = $thumbnails;6459 $this->title = $title;6460 $this->type = $type;6461 $this->width = $width;6462 if (class_exists('idna_convert'))6463 {6464 $idn =& new idna_convert;6465 $parsed = SimplePie_Misc::parse_url($link);6466 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);6467 }6468 $this->handler = $this->get_handler(); // Needs to load last6469 }6470 6471 function __toString()6472 {6473 // There is no $this->data here6474 return md5(serialize($this));6475 }6476 6477 function get_bitrate()6478 {6479 if ($this->bitrate !== null)6480 {6481 return $this->bitrate;6482 }6483 else6484 {6485 return null;6486 }6487 }6488 6489 function get_caption($key = 0)6490 {6491 $captions = $this->get_captions();6492 if (isset($captions[$key]))6493 {6494 return $captions[$key];6495 }6496 else6497 {6498 return null;6499 }6500 }6501 6502 function get_captions()6503 {6504 if ($this->captions !== null)6505 {6506 return $this->captions;6507 }6508 else6509 {6510 return null;6511 }6512 }6513 6514 function get_category($key = 0)6515 {6516 $categories = $this->get_categories();6517 if (isset($categories[$key]))6518 {6519 return $categories[$key];6520 }6521 else6522 {6523 return null;6524 }6525 }6526 6527 function get_categories()6528 {6529 if ($this->categories !== null)6530 {6531 return $this->categories;6532 }6533 else6534 {6535 return null;6536 }6537 }6538 6539 function get_channels()6540 {6541 if ($this->channels !== null)6542 {6543 return $this->channels;6544 }6545 else6546 {6547 return null;6548 }6549 }6550 6551 function get_copyright()6552 {6553 if ($this->copyright !== null)6554 {6555 return $this->copyright;6556 }6557 else6558 {6559 return null;6560 }6561 }6562 6563 function get_credit($key = 0)6564 {6565 $credits = $this->get_credits();6566 if (isset($credits[$key]))6567 {6568 return $credits[$key];6569 }6570 else6571 {6572 return null;6573 }6574 }6575 6576 function get_credits()6577 {6578 if ($this->credits !== null)6579 {6580 return $this->credits;6581 }6582 else6583 {6584 return null;6585 }6586 }6587 6588 function get_description()6589 {6590 if ($this->description !== null)6591 {6592 return $this->description;6593 }6594 else6595 {6596 return null;6597 }6598 }6599 6600 function get_duration($convert = false)6601 {6602 if ($this->duration !== null)6603 {6604 if ($convert)6605 {6606 $time = SimplePie_Misc::time_hms($this->duration);6607 return $time;6608 }6609 else6610 {6611 return $this->duration;6612 }6613 }6614 else6615 {6616 return null;6617 }6618 }6619 6620 function get_expression()6621 {6622 if ($this->expression !== null)6623 {6624 return $this->expression;6625 }6626 else6627 {6628 return 'full';6629 }6630 }6631 6632 function get_extension()6633 {6634 if ($this->link !== null)6635 {6636 $url = SimplePie_Misc::parse_url($this->link);6637 if ($url['path'] !== '')6638 {6639 return pathinfo($url['path'], PATHINFO_EXTENSION);6640 }6641 }6642 return null;6643 }6644 6645 function get_framerate()6646 {6647 if ($this->framerate !== null)6648 {6649 return $this->framerate;6650 }6651 else6652 {6653 return null;6654 }6655 }6656 6657 function get_handler()6658 {6659 return $this->get_real_type(true);6660 }6661 6662 function get_hash($key = 0)6663 {6664 $hashes = $this->get_hashes();6665 if (isset($hashes[$key]))6666 {6667 return $hashes[$key];6668 }6669 else6670 {6671 return null;6672 }6673 }6674 6675 function get_hashes()6676 {6677 if ($this->hashes !== null)6678 {6679 return $this->hashes;6680 }6681 else6682 {6683 return null;6684 }6685 }6686 6687 function get_height()6688 {6689 if ($this->height !== null)6690 {6691 return $this->height;6692 }6693 else6694 {6695 return null;6696 }6697 }6698 6699 function get_language()6700 {6701 if ($this->lang !== null)6702 {6703 return $this->lang;6704 }6705 else6706 {6707 return null;6708 }6709 }6710 6711 function get_keyword($key = 0)6712 {6713 $keywords = $this->get_keywords();6714 if (isset($keywords[$key]))6715 {6716 return $keywords[$key];6717 }6718 else6719 {6720 return null;6721 }6722 }6723 6724 function get_keywords()6725 {6726 if ($this->keywords !== null)6727 {6728 return $this->keywords;6729 }6730 else6731 {6732 return null;6733 }6734 }6735 6736 function get_length()6737 {6738 if ($this->length !== null)6739 {6740 return $this->length;6741 }6742 else6743 {6744 return null;6745 }6746 }6747 6748 function get_link()6749 {6750 if ($this->link !== null)6751 {6752 return urldecode($this->link);6753 }6754 else6755 {6756 return null;6757 }6758 }6759 6760 function get_medium()6761 {6762 if ($this->medium !== null)6763 {6764 return $this->medium;6765 }6766 else6767 {6768 return null;6769 }6770 }6771 6772 function get_player()6773 {6774 if ($this->player !== null)6775 {6776 return $this->player;6777 }6778 else6779 {6780 return null;6781 }6782 }6783 6784 function get_rating($key = 0)6785 {6786 $ratings = $this->get_ratings();6787 if (isset($ratings[$key]))6788 {6789 return $ratings[$key];6790 }6791 else6792 {6793 return null;6794 }6795 }6796 6797 function get_ratings()6798 {6799 if ($this->ratings !== null)6800 {6801 return $this->ratings;6802 }6803 else6804 {6805 return null;6806 }6807 }6808 6809 function get_restriction($key = 0)6810 {6811 $restrictions = $this->get_restrictions();6812 if (isset($restrictions[$key]))6813 {6814 return $restrictions[$key];6815 }6816 else6817 {6818 return null;6819 }6820 }6821 6822 function get_restrictions()6823 {6824 if ($this->restrictions !== null)6825 {6826 return $this->restrictions;6827 }6828 else6829 {6830 return null;6831 }6832 }6833 6834 function get_sampling_rate()6835 {6836 if ($this->samplingrate !== null)6837 {6838 return $this->samplingrate;6839 }6840 else6841 {6842 return null;6843 }6844 }6845 6846 function get_size()6847 {6848 $length = $this->get_length();6849 if ($length !== null)6850 {6851 return round($length/1048576, 2);6852 }6853 else6854 {6855 return null;6856 }6857 }6858 6859 function get_thumbnail($key = 0)6860 {6861 $thumbnails = $this->get_thumbnails();6862 if (isset($thumbnails[$key]))6863 {6864 return $thumbnails[$key];6865 }6866 else6867 {6868 return null;6869 }6870 }6871 6872 function get_thumbnails()6873 {6874 if ($this->thumbnails !== null)6875 {6876 return $this->thumbnails;6877 }6878 else6879 {6880 return null;6881 }6882 }6883 6884 function get_title()6885 {6886 if ($this->title !== null)6887 {6888 return $this->title;6889 }6890 else6891 {6892 return null;6893 }6894 }6895 6896 function get_type()6897 {6898 if ($this->type !== null)6899 {6900 return $this->type;6901 }6902 else6903 {6904 return null;6905 }6906 }6907 6908 function get_width()6909 {6910 if ($this->width !== null)6911 {6912 return $this->width;6913 }6914 else6915 {6916 return null;6917 }6918 }6919 6920 function native_embed($options='')6921 {6922 return $this->embed($options, true);6923 }6924 6925 /**6926 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.6927 */6928 function embed($options = '', $native = false)6929 {6930 // Set up defaults6931 $audio = '';6932 $video = '';6933 $alt = '';6934 $altclass = '';6935 $loop = 'false';6936 $width = 'auto';6937 $height = 'auto';6938 $bgcolor = '#ffffff';6939 $mediaplayer = '';6940 $widescreen = false;6941 $handler = $this->get_handler();6942 $type = $this->get_real_type();6943 6944 // Process options and reassign values as necessary6945 if (is_array($options))6946 {6947 extract($options);6948 }6949 else6950 {6951 $options = explode(',', $options);6952 foreach($options as $option)6953 {6954 $opt = explode(':', $option, 2);6955 if (isset($opt[0], $opt[1]))6956 {6957 $opt[0] = trim($opt[0]);6958 $opt[1] = trim($opt[1]);6959 switch ($opt[0])6960 {6961 case 'audio':6962 $audio = $opt[1];6963 break;6964 6965 case 'video':6966 $video = $opt[1];6967 break;6968 6969 case 'alt':6970 $alt = $opt[1];6971 break;6972 6973 case 'altclass':6974 $altclass = $opt[1];6975 break;6976 6977 case 'loop':6978 $loop = $opt[1];6979 break;6980 6981 case 'width':6982 $width = $opt[1];6983 break;6984 6985 case 'height':6986 $height = $opt[1];6987 break;6988 6989 case 'bgcolor':6990 $bgcolor = $opt[1];6991 break;6992 6993 case 'mediaplayer':6994 $mediaplayer = $opt[1];6995 break;6996 6997 case 'widescreen':6998 $widescreen = $opt[1];6999 break;7000 }7001 }7002 }7003 }7004 7005 $mime = explode('/', $type, 2);7006 $mime = $mime[0];7007 7008 // Process values for 'auto'7009 if ($width === 'auto')7010 {7011 if ($mime === 'video')7012 {7013 if ($height === 'auto')7014 {7015 $width = 480;7016 }7017 elseif ($widescreen)7018 {7019 $width = round((intval($height)/9)*16);7020 }7021 else7022 {7023 $width = round((intval($height)/3)*4);7024 }7025 }7026 else7027 {7028 $width = '100%';7029 }7030 }7031 7032 if ($height === 'auto')7033 {7034 if ($mime === 'audio')7035 {7036 $height = 0;7037 }7038 elseif ($mime === 'video')7039 {7040 if ($width === 'auto')7041 {7042 if ($widescreen)7043 {7044 $height = 270;7045 }7046 else7047 {7048 $height = 360;7049 }7050 }7051 elseif ($widescreen)7052 {7053 $height = round((intval($width)/16)*9);7054 }7055 else7056 {7057 $height = round((intval($width)/4)*3);7058 }7059 }7060 else7061 {7062 $height = 376;7063 }7064 }7065 elseif ($mime === 'audio')7066 {7067 $height = 0;7068 }7069 7070 // Set proper placeholder value7071 if ($mime === 'audio')7072 {7073 $placeholder = $audio;7074 }7075 elseif ($mime === 'video')7076 {7077 $placeholder = $video;7078 }7079 7080 $embed = '';7081 7082 // Make sure the JS library is included7083 if (!$native)7084 {7085 static $javascript_outputted = null;7086 if (!$javascript_outputted && $this->javascript)7087 {7088 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';7089 $javascript_outputted = true;7090 }7091 }7092 7093 // Odeo Feed MP3's7094 if ($handler === 'odeo')7095 {7096 if ($native)7097 {7098 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';7099 }7100 else7101 {7102 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';7103 }7104 }7105 7106 // Flash7107 elseif ($handler === 'flash')7108 {7109 if ($native)7110 {7111 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";7112 }7113 else7114 {7115 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";7116 }7117 }7118 7119 // Flash Media Player file types.7120 // Preferred handler for MP3 file types.7121 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))7122 {7123 $height += 20;7124 if ($native)7125 {7126 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";7127 }7128 else7129 {7130 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";7131 }7132 }7133 7134 // QuickTime 7 file types. Need to test with QuickTime 6.7135 // Only handle MP3's if the Flash Media Player is not present.7136 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))7137 {7138 $height += 16;7139 if ($native)7140 {7141 if ($placeholder !== '')7142 {7143 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";7144 }7145 else7146 {7147 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";7148 }7149 }7150 else7151 {7152 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";7153 }7154 }7155 7156 // Windows Media7157 elseif ($handler === 'wmedia')7158 {7159 $height += 45;7160 if ($native)7161 {7162 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";7163 }7164 else7165 {7166 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";7167 }7168 }7169 7170 // Everything else7171 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';7172 7173 return $embed;7174 }7175 7176 function get_real_type($find_handler = false)7177 {7178 // If it's Odeo, let's get it out of the way.7179 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')7180 {7181 return 'odeo';7182 }7183 7184 // Mime-types by handler.7185 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash7186 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player7187 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime7188 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media7189 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP37190 7191 if ($this->get_type() !== null)7192 {7193 $type = strtolower($this->type);7194 }7195 else7196 {7197 $type = null;7198 }7199 7200 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.7201 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))7202 {7203 switch (strtolower($this->get_extension()))7204 {7205 // Audio mime-types7206 case 'aac':7207 case 'adts':7208 $type = 'audio/acc';7209 break;7210 7211 case 'aif':7212 case 'aifc':7213 case 'aiff':7214 case 'cdda':7215 $type = 'audio/aiff';7216 break;7217 7218 case 'bwf':7219 $type = 'audio/wav';7220 break;7221 7222 case 'kar':7223 case 'mid':7224 case 'midi':7225 case 'smf':7226 $type = 'audio/midi';7227 break;7228 7229 case 'm4a':7230 $type = 'audio/x-m4a';7231 break;7232 7233 case 'mp3':7234 case 'swa':7235 $type = 'audio/mp3';7236 break;7237 7238 case 'wav':7239 $type = 'audio/wav';7240 break;7241 7242 case 'wax':7243 $type = 'audio/x-ms-wax';7244 break;7245 7246 case 'wma':7247 $type = 'audio/x-ms-wma';7248 break;7249 7250 // Video mime-types7251 case '3gp':7252 case '3gpp':7253 $type = 'video/3gpp';7254 break;7255 7256 case '3g2':7257 case '3gp2':7258 $type = 'video/3gpp2';7259 break;7260 7261 case 'asf':7262 $type = 'video/x-ms-asf';7263 break;7264 7265 case 'flv':7266 $type = 'video/x-flv';7267 break;7268 7269 case 'm1a':7270 case 'm1s':7271 case 'm1v':7272 case 'm15':7273 case 'm75':7274 case 'mp2':7275 case 'mpa':7276 case 'mpeg':7277 case 'mpg':7278 case 'mpm':7279 case 'mpv':7280 $type = 'video/mpeg';7281 break;7282 7283 case 'm4v':7284 $type = 'video/x-m4v';7285 break;7286 7287 case 'mov':7288 case 'qt':7289 $type = 'video/quicktime';7290 break;7291 7292 case 'mp4':7293 case 'mpg4':7294 $type = 'video/mp4';7295 break;7296 7297 case 'sdv':7298 $type = 'video/sd-video';7299 break;7300 7301 case 'wm':7302 $type = 'video/x-ms-wm';7303 break;7304 7305 case 'wmv':7306 $type = 'video/x-ms-wmv';7307 break;7308 7309 case 'wvx':7310 $type = 'video/x-ms-wvx';7311 break;7312 7313 // Flash mime-types7314 case 'spl':7315 $type = 'application/futuresplash';7316 break;7317 7318 case 'swf':7319 $type = 'application/x-shockwave-flash';7320 break;7321 }7322 }7323 7324 if ($find_handler)7325 {7326 if (in_array($type, $types_flash))7327 {7328 return 'flash';7329 }7330 elseif (in_array($type, $types_fmedia))7331 {7332 return 'fmedia';7333 }7334 elseif (in_array($type, $types_quicktime))7335 {7336 return 'quicktime';7337 }7338 elseif (in_array($type, $types_wmedia))7339 {7340 return 'wmedia';7341 }7342 elseif (in_array($type, $types_mp3))7343 {7344 return 'mp3';7345 }7346 else7347 {7348 return null;7349 }7350 }7351 else7352 {7353 return $type;7354 }7355 }7356 }7357 7358 class SimplePie_Caption7359 {7360 var $type;7361 var $lang;7362 var $startTime;7363 var $endTime;7364 var $text;7365 7366 // Constructor, used to input the data7367 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)7368 {7369 $this->type = $type;7370 $this->lang = $lang;7371 $this->startTime = $startTime;7372 $this->endTime = $endTime;7373 $this->text = $text;7374 }7375 7376 function __toString()7377 {7378 // There is no $this->data here7379 return md5(serialize($this));7380 }7381 7382 function get_endtime()7383 {7384 if ($this->endTime !== null)7385 {7386 return $this->endTime;7387 }7388 else7389 {7390 return null;7391 }7392 }7393 7394 function get_language()7395 {7396 if ($this->lang !== null)7397 {7398 return $this->lang;7399 }7400 else7401 {7402 return null;7403 }7404 }7405 7406 function get_starttime()7407 {7408 if ($this->startTime !== null)7409 {7410 return $this->startTime;7411 }7412 else7413 {7414 return null;7415 }7416 }7417 7418 function get_text()7419 {7420 if ($this->text !== null)7421 {7422 return $this->text;7423 }7424 else7425 {7426 return null;7427 }7428 }7429 7430 function get_type()7431 {7432 if ($this->type !== null)7433 {7434 return $this->type;7435 }7436 else7437 {7438 return null;7439 }7440 }7441 }7442 7443 class SimplePie_Credit7444 {7445 var $role;7446 var $scheme;7447 var $name;7448 7449 // Constructor, used to input the data7450 function SimplePie_Credit($role = null, $scheme = null, $name = null)7451 {7452 $this->role = $role;7453 $this->scheme = $scheme;7454 $this->name = $name;7455 }7456 7457 function __toString()7458 {7459 // There is no $this->data here7460 return md5(serialize($this));7461 }7462 7463 function get_role()7464 {7465 if ($this->role !== null)7466 {7467 return $this->role;7468 }7469 else7470 {7471 return null;7472 }7473 }7474 7475 function get_scheme()7476 {7477 if ($this->scheme !== null)7478 {7479 return $this->scheme;7480 }7481 else7482 {7483 return null;7484 }7485 }7486 7487 function get_name()7488 {7489 if ($this->name !== null)7490 {7491 return $this->name;7492 }7493 else7494 {7495 return null;7496 }7497 }7498 }7499 7500 class SimplePie_Copyright7501 {7502 var $url;7503 var $label;7504 7505 // Constructor, used to input the data7506 function SimplePie_Copyright($url = null, $label = null)7507 {7508 $this->url = $url;7509 $this->label = $label;7510 }7511 7512 function __toString()7513 {7514 // There is no $this->data here7515 return md5(serialize($this));7516 }7517 7518 function get_url()7519 {7520 if ($this->url !== null)7521 {7522 return $this->url;7523 }7524 else7525 {7526 return null;7527 }7528 }7529 7530 function get_attribution()7531 {7532 if ($this->label !== null)7533 {7534 return $this->label;7535 }7536 else7537 {7538 return null;7539 }7540 }7541 }7542 7543 class SimplePie_Rating7544 {7545 var $scheme;7546 var $value;7547 7548 // Constructor, used to input the data7549 function SimplePie_Rating($scheme = null, $value = null)7550 {7551 $this->scheme = $scheme;7552 $this->value = $value;7553 }7554 7555 function __toString()7556 {7557 // There is no $this->data here7558 return md5(serialize($this));7559 }7560 7561 function get_scheme()7562 {7563 if ($this->scheme !== null)7564 {7565 return $this->scheme;7566 }7567 else7568 {7569 return null;7570 }7571 }7572 7573 function get_value()7574 {7575 if ($this->value !== null)7576 {7577 return $this->value;7578 }7579 else7580 {7581 return null;7582 }7583 }7584 }7585 7586 class SimplePie_Restriction7587 {7588 var $relationship;7589 var $type;7590 var $value;7591 7592 // Constructor, used to input the data7593 function SimplePie_Restriction($relationship = null, $type = null, $value = null)7594 {7595 $this->relationship = $relationship;7596 $this->type = $type;7597 $this->value = $value;7598 }7599 7600 function __toString()7601 {7602 // There is no $this->data here7603 return md5(serialize($this));7604 }7605 7606 function get_relationship()7607 {7608 if ($this->relationship !== null)7609 {7610 return $this->relationship;7611 }7612 else7613 {7614 return null;7615 }7616 }7617 7618 function get_type()7619 {7620 if ($this->type !== null)7621 {7622 return $this->type;7623 }7624 else7625 {7626 return null;7627 }7628 }7629 7630 function get_value()7631 {7632 if ($this->value !== null)7633 {7634 return $this->value;7635 }7636 else7637 {7638 return null;7639 }7640 }7641 }7642 7643 /**7644 * @todo Move to properly supporting RFC2616 (HTTP/1.1)7645 */7646 class SimplePie_File7647 {7648 var $url;7649 var $useragent;7650 var $success = true;7651 var $headers = array();7652 var $body;7653 var $status_code;7654 var $redirects = 0;7655 var $error;7656 var $method = SIMPLEPIE_FILE_SOURCE_NONE;7657 7658 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)7659 {7660 if (class_exists('idna_convert'))7661 {7662 $idn =& new idna_convert;7663 $parsed = SimplePie_Misc::parse_url($url);7664 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);7665 }7666 $this->url = $url;7667 $this->useragent = $useragent;7668 if (preg_match('/^http(s)?:\/\//i', $url))7669 {7670 if ($useragent === null)7671 {7672 $useragent = ini_get('user_agent');7673 $this->useragent = $useragent;7674 }7675 if (!is_array($headers))7676 {7677 $headers = array();7678 }7679 if (!$force_fsockopen && function_exists('curl_exec'))7680 {7681 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;7682 $fp = curl_init();7683 $headers2 = array();7684 foreach ($headers as $key => $value)7685 {7686 $headers2[] = "$key: $value";7687 }7688 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))7689 {7690 curl_setopt($fp, CURLOPT_ENCODING, '');7691 }7692 curl_setopt($fp, CURLOPT_URL, $url);7693 curl_setopt($fp, CURLOPT_HEADER, 1);7694 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);7695 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);7696 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);7697 curl_setopt($fp, CURLOPT_REFERER, $url);7698 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);7699 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);7700 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))7701 {7702 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);7703 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);7704 }7705 7706 $this->headers = curl_exec($fp);7707 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)7708 {7709 curl_setopt($fp, CURLOPT_ENCODING, 'none');7710 $this->headers = curl_exec($fp);7711 }7712 if (curl_errno($fp))7713 {7714 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);7715 $this->success = false;7716 }7717 else7718 {7719 $info = curl_getinfo($fp);7720 curl_close($fp);7721 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);7722 $this->headers = array_pop($this->headers);7723 $parser =& new SimplePie_HTTP_Parser($this->headers);7724 if ($parser->parse())7725 {7726 $this->headers = $parser->headers;7727 $this->body = $parser->body;7728 $this->status_code = $parser->status_code;7729 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)7730 {7731 $this->redirects++;7732 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);7733 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);7734 }7735 }7736 }7737 }7738 else7739 {7740 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;7741 $url_parts = parse_url($url);7742 $socket_host = $url_parts['host'];7743 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')7744 {7745 $socket_host = "ssl://$url_parts[host]";7746 $url_parts['port'] = 443;7747 }7748 if (!isset($url_parts['port']))7749 {7750 $url_parts['port'] = 80;7751 }7752 $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);7753 if (!$fp)7754 {7755 $this->error = 'fsockopen error: ' . $errstr;7756 $this->success = false;7757 }7758 else7759 {7760 stream_set_timeout($fp, $timeout);7761 if (isset($url_parts['path']))7762 {7763 if (isset($url_parts['query']))7764 {7765 $get = "$url_parts[path]?$url_parts[query]";7766 }7767 else7768 {7769 $get = $url_parts['path'];7770 }7771 }7772 else7773 {7774 $get = '/';7775 }7776 $out = "GET $get HTTP/1.0\r\n";7777 $out .= "Host: $url_parts[host]\r\n";7778 $out .= "User-Agent: $useragent\r\n";7779 if (extension_loaded('zlib'))7780 {7781 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";7782 }7783 7784 if (isset($url_parts['user']) && isset($url_parts['pass']))7785 {7786 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";7787 }7788 foreach ($headers as $key => $value)7789 {7790 $out .= "$key: $value\r\n";7791 }7792 $out .= "Connection: Close\r\n\r\n";7793 fwrite($fp, $out);7794 7795 $info = stream_get_meta_data($fp);7796 7797 $this->headers = '';7798 while (!$info['eof'] && !$info['timed_out'])7799 {7800 $this->headers .= fread($fp, 1160);7801 $info = stream_get_meta_data($fp);7802 }7803 if (!$info['timed_out'])7804 {7805 $parser =& new SimplePie_HTTP_Parser($this->headers);7806 if ($parser->parse())7807 {7808 $this->headers = $parser->headers;7809 $this->body = $parser->body;7810 $this->status_code = $parser->status_code;7811 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)7812 {7813 $this->redirects++;7814 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);7815 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);7816 }7817 if (isset($this->headers['content-encoding']))7818 {7819 // Hey, we act dumb elsewhere, so let's do that here too7820 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))7821 {7822 case 'gzip':7823 case 'x-gzip':7824 $decoder =& new SimplePie_gzdecode($this->body);7825 if (!$decoder->parse())7826 {7827 $this->error = 'Unable to decode HTTP "gzip" stream';7828 $this->success = false;7829 }7830 else7831 {7832 $this->body = $decoder->data;7833 }7834 break;7835 7836 case 'deflate':7837 if (($body = gzuncompress($this->body)) === false)7838 {7839 if (($body = gzinflate($this->body)) === false)7840 {7841 $this->error = 'Unable to decode HTTP "deflate" stream';7842 $this->success = false;7843 }7844 }7845 $this->body = $body;7846 break;7847 7848 default:7849 $this->error = 'Unknown content coding';7850 $this->success = false;7851 }7852 }7853 }7854 }7855 else7856 {7857 $this->error = 'fsocket timed out';7858 $this->success = false;7859 }7860 fclose($fp);7861 }7862 }7863 }7864 else7865 {7866 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;7867 if (!$this->body = file_get_contents($url))7868 {7869 $this->error = 'file_get_contents could not read the file';7870 $this->success = false;7871 }7872 }7873 }7874 }7875 7876 /**7877 * HTTP Response Parser7878 *7879 * @package SimplePie7880 */7881 class SimplePie_HTTP_Parser7882 {7883 /**7884 * HTTP Version7885 *7886 * @access public7887 * @var float7888 */7889 var $http_version = 0.0;7890 7891 /**7892 * Status code7893 *7894 * @access public7895 * @var int7896 */7897 var $status_code = 0;7898 7899 /**7900 * Reason phrase7901 *7902 * @access public7903 * @var string7904 */7905 var $reason = '';7906 7907 /**7908 * Key/value pairs of the headers7909 *7910 * @access public7911 * @var array7912 */7913 var $headers = array();7914 7915 /**7916 * Body of the response7917 *7918 * @access public7919 * @var string7920 */7921 var $body = '';7922 7923 /**7924 * Current state of the state machine7925 *7926 * @access private7927 * @var string7928 */7929 var $state = 'http_version';7930 7931 /**7932 * Input data7933 *7934 * @access private7935 * @var string7936 */7937 var $data = '';7938 7939 /**7940 * Input data length (to avoid calling strlen() everytime this is needed)7941 *7942 * @access private7943 * @var int7944 */7945 var $data_length = 0;7946 7947 /**7948 * Current position of the pointer7949 *7950 * @var int7951 * @access private7952 */7953 var $position = 0;7954 7955 /**7956 * Name of the hedaer currently being parsed7957 *7958 * @access private7959 * @var string7960 */7961 var $name = '';7962 7963 /**7964 * Value of the hedaer currently being parsed7965 *7966 * @access private7967 * @var string7968 */7969 var $value = '';7970 7971 /**7972 * Create an instance of the class with the input data7973 *7974 * @access public7975 * @param string $data Input data7976 */7977 function SimplePie_HTTP_Parser($data)7978 {7979 $this->data = $data;7980 $this->data_length = strlen($this->data);7981 }7982 7983 /**7984 * Parse the input data7985 *7986 * @access public7987 * @return bool true on success, false on failure7988 */7989 function parse()7990 {7991 while ($this->state && $this->state !== 'emit' && $this->has_data())7992 {7993 $state = $this->state;7994 $this->$state();7995 }7996 $this->data = '';7997 if ($this->state === 'emit' || $this->state === 'body')7998 {7999 return true;8000 }8001 else8002 {8003 $this->http_version = '';8004 $this->status_code = '';8005 $this->reason = '';8006 $this->headers = array();8007 $this->body = '';8008 return false;8009 }8010 }8011 8012 /**8013 * Check whether there is data beyond the pointer8014 *8015 * @access private8016 * @return bool true if there is further data, false if not8017 */8018 function has_data()8019 {8020 return (bool) ($this->position < $this->data_length);8021 }8022 8023 /**8024 * See if the next character is LWS8025 *8026 * @access private8027 * @return bool true if the next character is LWS, false if not8028 */8029 function is_linear_whitespace()8030 {8031 return (bool) ($this->data[$this->position] === "\x09"8032 || $this->data[$this->position] === "\x20"8033 || ($this->data[$this->position] === "\x0A"8034 && isset($this->data[$this->position + 1])8035 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));8036 }8037 8038 /**8039 * Parse the HTTP version8040 *8041 * @access private8042 */8043 function http_version()8044 {8045 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')8046 {8047 $len = strspn($this->data, '0123456789.', 5);8048 $this->http_version = substr($this->data, 5, $len);8049 $this->position += 5 + $len;8050 if (substr_count($this->http_version, '.') <= 1)8051 {8052 $this->http_version = (float) $this->http_version;8053 $this->position += strspn($this->data, "\x09\x20", $this->position);8054 $this->state = 'status';8055 }8056 else8057 {8058 $this->state = false;8059 }8060 }8061 else8062 {8063 $this->state = false;8064 }8065 }8066 8067 /**8068 * Parse the status code8069 *8070 * @access private8071 */8072 function status()8073 {8074 if ($len = strspn($this->data, '0123456789', $this->position))8075 {8076 $this->status_code = (int) substr($this->data, $this->position, $len);8077 $this->position += $len;8078 $this->state = 'reason';8079 }8080 else8081 {8082 $this->state = false;8083 }8084 }8085 8086 /**8087 * Parse the reason phrase8088 *8089 * @access private8090 */8091 function reason()8092 {8093 $len = strcspn($this->data, "\x0A", $this->position);8094 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");8095 $this->position += $len + 1;8096 $this->state = 'new_line';8097 }8098 8099 /**8100 * Deal with a new line, shifting data around as needed8101 *8102 * @access private8103 */8104 function new_line()8105 {8106 $this->value = trim($this->value, "\x0D\x20");8107 if ($this->name !== '' && $this->value !== '')8108 {8109 $this->name = strtolower($this->name);8110 if (isset($this->headers[$this->name]))8111 {8112 $this->headers[$this->name] .= ', ' . $this->value;8113 }8114 else8115 {8116 $this->headers[$this->name] = $this->value;8117 }8118 }8119 $this->name = '';8120 $this->value = '';8121 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")8122 {8123 $this->position += 2;8124 $this->state = 'body';8125 }8126 elseif ($this->data[$this->position] === "\x0A")8127 {8128 $this->position++;8129 $this->state = 'body';8130 }8131 else8132 {8133 $this->state = 'name';8134 }8135 }8136 8137 /**8138 * Parse a header name8139 *8140 * @access private8141 */8142 function name()8143 {8144 $len = strcspn($this->data, "\x0A:", $this->position);8145 if (isset($this->data[$this->position + $len]))8146 {8147 if ($this->data[$this->position + $len] === "\x0A")8148 {8149 $this->position += $len;8150 $this->state = 'new_line';8151 }8152 else8153 {8154 $this->name = substr($this->data, $this->position, $len);8155 $this->position += $len + 1;8156 $this->state = 'value';8157 }8158 }8159 else8160 {8161 $this->state = false;8162 }8163 }8164 8165 /**8166 * Parse LWS, replacing consecutive LWS characters with a single space8167 *8168 * @access private8169 */8170 function linear_whitespace()8171 {8172 do8173 {8174 if (substr($this->data, $this->position, 2) === "\x0D\x0A")8175 {8176 $this->position += 2;8177 }8178 elseif ($this->data[$this->position] === "\x0A")8179 {8180 $this->position++;8181 }8182 $this->position += strspn($this->data, "\x09\x20", $this->position);8183 } while ($this->has_data() && $this->is_linear_whitespace());8184 $this->value .= "\x20";8185 }8186 8187 /**8188 * See what state to move to while within non-quoted header values8189 *8190 * @access private8191 */8192 function value()8193 {8194 if ($this->is_linear_whitespace())8195 {8196 $this->linear_whitespace();8197 }8198 else8199 {8200 switch ($this->data[$this->position])8201 {8202 case '"':8203 $this->position++;8204 $this->state = 'quote';8205 break;8206 8207 case "\x0A":8208 $this->position++;8209 $this->state = 'new_line';8210 break;8211 8212 default:8213 $this->state = 'value_char';8214 break;8215 }8216 }8217 }8218 8219 /**8220 * Parse a header value while outside quotes8221 *8222 * @access private8223 */8224 function value_char()8225 {8226 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);8227 $this->value .= substr($this->data, $this->position, $len);8228 $this->position += $len;8229 $this->state = 'value';8230 }8231 8232 /**8233 * See what state to move to while within quoted header values8234 *8235 * @access private8236 */8237 function quote()8238 {8239 if ($this->is_linear_whitespace())8240 {8241 $this->linear_whitespace();8242 }8243 else8244 {8245 switch ($this->data[$this->position])8246 {8247 case '"':8248 $this->position++;8249 $this->state = 'value';8250 break;8251 8252 case "\x0A":8253 $this->position++;8254 $this->state = 'new_line';8255 break;8256 8257 case '\\':8258 $this->position++;8259 $this->state = 'quote_escaped';8260 break;8261 8262 default:8263 $this->state = 'quote_char';8264 break;8265 }8266 }8267 }8268 8269 /**8270 * Parse a header value while within quotes8271 *8272 * @access private8273 */8274 function quote_char()8275 {8276 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);8277 $this->value .= substr($this->data, $this->position, $len);8278 $this->position += $len;8279 $this->state = 'value';8280 }8281 8282 /**8283 * Parse an escaped character within quotes8284 *8285 * @access private8286 */8287 function quote_escaped()8288 {8289 $this->value .= $this->data[$this->position];8290 $this->position++;8291 $this->state = 'quote';8292 }8293 8294 /**8295 * Parse the body8296 *8297 * @access private8298 */8299 function body()8300 {8301 $this->body = substr($this->data, $this->position);8302 $this->state = 'emit';8303 }8304 }8305 8306 /**8307 * gzdecode8308 *8309 * @package SimplePie8310 */8311 class SimplePie_gzdecode8312 {8313 /**8314 * Compressed data8315 *8316 * @access private8317 * @see gzdecode::$data8318 */8319 var $compressed_data;8320 8321 /**8322 * Size of compressed data8323 *8324 * @access private8325 */8326 var $compressed_size;8327 8328 /**8329 * Minimum size of a valid gzip string8330 *8331 * @access private8332 */8333 var $min_compressed_size = 18;8334 8335 /**8336 * Current position of pointer8337 *8338 * @access private8339 */8340 var $position = 0;8341 8342 /**8343 * Flags (FLG)8344 *8345 * @access private8346 */8347 var $flags;8348 8349 /**8350 * Uncompressed data8351 *8352 * @access public8353 * @see gzdecode::$compressed_data8354 */8355 var $data;8356 8357 /**8358 * Modified time8359 *8360 * @access public8361 */8362 var $MTIME;8363 8364 /**8365 * Extra Flags8366 *8367 * @access public8368 */8369 var $XFL;8370 8371 /**8372 * Operating System8373 *8374 * @access public8375 */8376 var $OS;8377 8378 /**8379 * Subfield ID 18380 *8381 * @access public8382 * @see gzdecode::$extra_field8383 * @see gzdecode::$SI28384 */8385 var $SI1;8386 8387 /**8388 * Subfield ID 28389 *8390 * @access public8391 * @see gzdecode::$extra_field8392 * @see gzdecode::$SI18393 */8394 var $SI2;8395 8396 /**8397 * Extra field content8398 *8399 * @access public8400 * @see gzdecode::$SI18401 * @see gzdecode::$SI28402 */8403 var $extra_field;8404 8405 /**8406 * Original filename8407 *8408 * @access public8409 */8410 var $filename;8411 8412 /**8413 * Human readable comment8414 *8415 * @access public8416 */8417 var $comment;8418 8419 /**8420 * Don't allow anything to be set8421 *8422 * @access public8423 */8424 function __set($name, $value)8425 {8426 trigger_error("Cannot write property $name", E_USER_ERROR);8427 }8428 8429 /**8430 * Set the compressed string and related properties8431 *8432 * @access public8433 */8434 function SimplePie_gzdecode($data)8435 {8436 $this->compressed_data = $data;8437 $this->compressed_size = strlen($data);8438 }8439 8440 /**8441 * Decode the GZIP stream8442 *8443 * @access public8444 */8445 function parse()8446 {8447 if ($this->compressed_size >= $this->min_compressed_size)8448 {8449 // Check ID1, ID2, and CM8450 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")8451 {8452 return false;8453 }8454 8455 // Get the FLG (FLaGs)8456 $this->flags = ord($this->compressed_data[3]);8457 8458 // FLG bits above (1 << 4) are reserved8459 if ($this->flags > 0x1F)8460 {8461 return false;8462 }8463 8464 // Advance the pointer after the above8465 $this->position += 4;8466 8467 // MTIME8468 $mtime = substr($this->compressed_data, $this->position, 4);8469 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness8470 if (current(unpack('S', "\x00\x01")) === 1)8471 {8472 $mtime = strrev($mtime);8473 }8474 $this->MTIME = current(unpack('l', $mtime));8475 $this->position += 4;8476 8477 // Get the XFL (eXtra FLags)8478 $this->XFL = ord($this->compressed_data[$this->position++]);8479 8480 // Get the OS (Operating System)8481 $this->OS = ord($this->compressed_data[$this->position++]);8482 8483 // Parse the FEXTRA8484 if ($this->flags & 4)8485 {8486 // Read subfield IDs8487 $this->SI1 = $this->compressed_data[$this->position++];8488 $this->SI2 = $this->compressed_data[$this->position++];8489 8490 // SI2 set to zero is reserved for future use8491 if ($this->SI2 === "\x00")8492 {8493 return false;8494 }8495 8496 // Get the length of the extra field8497 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));8498 $this->position += 2;8499 8500 // Check the length of the string is still valid8501 $this->min_compressed_size += $len + 4;8502 if ($this->compressed_size >= $this->min_compressed_size)8503 {8504 // Set the extra field to the given data8505 $this->extra_field = substr($this->compressed_data, $this->position, $len);8506 $this->position += $len;8507 }8508 else8509 {8510 return false;8511 }8512 }8513 8514 // Parse the FNAME8515 if ($this->flags & 8)8516 {8517 // Get the length of the filename8518 $len = strcspn($this->compressed_data, "\x00", $this->position);8519 8520 // Check the length of the string is still valid8521 $this->min_compressed_size += $len + 1;8522 if ($this->compressed_size >= $this->min_compressed_size)8523 {8524 // Set the original filename to the given string8525 $this->filename = substr($this->compressed_data, $this->position, $len);8526 $this->position += $len + 1;8527 }8528 else8529 {8530 return false;8531 }8532 }8533 8534 // Parse the FCOMMENT8535 if ($this->flags & 16)8536 {8537 // Get the length of the comment8538 $len = strcspn($this->compressed_data, "\x00", $this->position);8539 8540 // Check the length of the string is still valid8541 $this->min_compressed_size += $len + 1;8542 if ($this->compressed_size >= $this->min_compressed_size)8543 {8544 // Set the original comment to the given string8545 $this->comment = substr($this->compressed_data, $this->position, $len);8546 $this->position += $len + 1;8547 }8548 else8549 {8550 return false;8551 }8552 }8553 8554 // Parse the FHCRC8555 if ($this->flags & 2)8556 {8557 // Check the length of the string is still valid8558 $this->min_compressed_size += $len + 2;8559 if ($this->compressed_size >= $this->min_compressed_size)8560 {8561 // Read the CRC8562 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));8563 8564 // Check the CRC matches8565 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)8566 {8567 $this->position += 2;8568 }8569 else8570 {8571 return false;8572 }8573 }8574 else8575 {8576 return false;8577 }8578 }8579 8580 // Decompress the actual data8581 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)8582 {8583 return false;8584 }8585 else8586 {8587 $this->position = $this->compressed_size - 8;8588 }8589 8590 // Check CRC of data8591 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));8592 $this->position += 4;8593 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))8594 {8595 return false;8596 }*/8597 8598 // Check ISIZE of data8599 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));8600 $this->position += 4;8601 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))8602 {8603 return false;8604 }8605 8606 // Wow, against all odds, we've actually got a valid gzip string8607 return true;8608 }8609 else8610 {8611 return false;8612 }8613 }8614 }8615 8616 class SimplePie_Cache8617 {8618 /**8619 * Don't call the constructor. Please.8620 *8621 * @access private8622 */8623 function SimplePie_Cache()8624 {8625 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);8626 }8627 8628 /**8629 * Create a new SimplePie_Cache object8630 *8631 * @static8632 * @access public8633 */8634 function create($location, $filename, $extension)8635 {8636 $location_iri =& new SimplePie_IRI($location);8637 switch ($location_iri->get_scheme())8638 {8639 case 'mysql':8640 if (extension_loaded('mysql'))8641 {8642 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);8643 }8644 break;8645 8646 default:8647 return new SimplePie_Cache_File($location, $filename, $extension);8648 }8649 }8650 }8651 8652 class SimplePie_Cache_File8653 {8654 var $location;8655 var $filename;8656 var $extension;8657 var $name;8658 8659 function SimplePie_Cache_File($location, $filename, $extension)8660 {8661 $this->location = $location;8662 $this->filename = $filename;8663 $this->extension = $extension;8664 $this->name = "$this->location/$this->filename.$this->extension";8665 }8666 8667 function save($data)8668 {8669 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))8670 {8671 if (is_a($data, 'SimplePie'))8672 {8673 $data = $data->data;8674 }8675 8676 $data = serialize($data);8677 8678 if (function_exists('file_put_contents'))8679 {8680 return (bool) file_put_contents($this->name, $data);8681 }8682 else8683 {8684 $fp = fopen($this->name, 'wb');8685 if ($fp)8686 {8687 fwrite($fp, $data);8688 fclose($fp);8689 return true;8690 }8691 }8692 }8693 return false;8694 }8695 8696 function load()8697 {8698 if (file_exists($this->name) && is_readable($this->name))8699 {8700 return unserialize(file_get_contents($this->name));8701 }8702 return false;8703 }8704 8705 function mtime()8706 {8707 if (file_exists($this->name))8708 {8709 return filemtime($this->name);8710 }8711 return false;8712 }8713 8714 function touch()8715 {8716 if (file_exists($this->name))8717 {8718 return touch($this->name);8719 }8720 return false;8721 }8722 8723 function unlink()8724 {8725 if (file_exists($this->name))8726 {8727 return unlink($this->name);8728 }8729 return false;8730 }8731 }8732 8733 class SimplePie_Cache_DB8734 {8735 function prepare_simplepie_object_for_cache($data)8736 {8737 $items = $data->get_items();8738 $items_by_id = array();8739 8740 if (!empty($items))8741 {8742 foreach ($items as $item)8743 {8744 $items_by_id[$item->get_id()] = $item;8745 }8746 8747 if (count($items_by_id) !== count($items))8748 {8749 $items_by_id = array();8750 foreach ($items as $item)8751 {8752 $items_by_id[$item->get_id(true)] = $item;8753 }8754 }8755 8756 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))8757 {8758 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];8759 }8760 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))8761 {8762 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];8763 }8764 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))8765 {8766 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];8767 }8768 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))8769 {8770 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];8771 }8772 else8773 {8774 $channel = null;8775 }8776 8777 if ($channel !== null)8778 {8779 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))8780 {8781 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);8782 }8783 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))8784 {8785 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);8786 }8787 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))8788 {8789 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);8790 }8791 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))8792 {8793 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);8794 }8795 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))8796 {8797 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);8798 }8799 }8800 if (isset($data->data['items']))8801 {8802 unset($data->data['items']);8803 }8804 if (isset($data->data['ordered_items']))8805 {8806 unset($data->data['ordered_items']);8807 }8808 }8809 return array(serialize($data->data), $items_by_id);8810 }8811 }8812 8813 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB8814 {8815 var $mysql;8816 var $options;8817 var $id;8818 8819 function SimplePie_Cache_MySQL($mysql_location, $name, $extension)8820 {8821 $host = $mysql_location->get_host();8822 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')8823 {8824 $server = ':' . substr($host, 5, -1);8825 }8826 else8827 {8828 $server = $host;8829 if ($mysql_location->get_port() !== null)8830 {8831 $server .= ':' . $mysql_location->get_port();8832 }8833 }8834 8835 if (strpos($mysql_location->get_userinfo(), ':') !== false)8836 {8837 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);8838 }8839 else8840 {8841 $username = $mysql_location->get_userinfo();8842 $password = null;8843 }8844 8845 if ($this->mysql = mysql_connect($server, $username, $password))8846 {8847 $this->id = $name . $extension;8848 $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());8849 if (!isset($this->options['prefix'][0]))8850 {8851 $this->options['prefix'][0] = '';8852 }8853 8854 if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))8855 && mysql_query('SET NAMES utf8')8856 && ($query = mysql_unbuffered_query('SHOW TABLES')))8857 {8858 $db = array();8859 while ($row = mysql_fetch_row($query))8860 {8861 $db[] = $row[0];8862 }8863 8864 if (!in_array($this->options['prefix'][0] . 'cache_data', $db))8865 {8866 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))8867 {8868 $this->mysql = null;8869 }8870 }8871 8872 if (!in_array($this->options['prefix'][0] . 'items', $db))8873 {8874 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))8875 {8876 $this->mysql = null;8877 }8878 }8879 }8880 else8881 {8882 $this->mysql = null;8883 }8884 }8885 }8886 8887 function save($data)8888 {8889 if ($this->mysql)8890 {8891 $feed_id = "'" . mysql_real_escape_string($this->id) . "'";8892 8893 if (is_a($data, 'SimplePie'))8894 {8895 if (SIMPLEPIE_PHP5)8896 {8897 // This keyword needs to defy coding standards for PHP4 compatibility8898 $data = clone($data);8899 }8900 8901 $prepared = $this->prepare_simplepie_object_for_cache($data);8902 8903 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))8904 {8905 if (mysql_num_rows($query))8906 {8907 $items = count($prepared[1]);8908 if ($items)8909 {8910 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;8911 }8912 else8913 {8914 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;8915 }8916 8917 if (!mysql_query($sql, $this->mysql))8918 {8919 return false;8920 }8921 }8922 elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))8923 {8924 return false;8925 }8926 8927 $ids = array_keys($prepared[1]);8928 if (!empty($ids))8929 {8930 foreach ($ids as $id)8931 {8932 $database_ids[] = mysql_real_escape_string($id);8933 }8934 8935 if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))8936 {8937 $existing_ids = array();8938 while ($row = mysql_fetch_row($query))8939 {8940 $existing_ids[] = $row[0];8941 }8942 8943 $new_ids = array_diff($ids, $existing_ids);8944 8945 foreach ($new_ids as $new_id)8946 {8947 if (!($date = $prepared[1][$new_id]->get_date('U')))8948 {8949 $date = time();8950 }8951 8952 if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))8953 {8954 return false;8955 }8956 }8957 return true;8958 }8959 }8960 else8961 {8962 return true;8963 }8964 }8965 }8966 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))8967 {8968 if (mysql_num_rows($query))8969 {8970 if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))8971 {8972 return true;8973 }8974 }8975 elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))8976 {8977 return true;8978 }8979 }8980 }8981 return false;8982 }8983 8984 function load()8985 {8986 if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))8987 {8988 $data = unserialize($row[1]);8989 8990 if (isset($this->options['items'][0]))8991 {8992 $items = (int) $this->options['items'][0];8993 }8994 else8995 {8996 $items = (int) $row[0];8997 }8998 8999 if ($items !== 0)9000 {9001 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))9002 {9003 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];9004 }9005 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))9006 {9007 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];9008 }9009 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))9010 {9011 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];9012 }9013 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))9014 {9015 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];9016 }9017 else9018 {9019 $feed = null;9020 }9021 9022 if ($feed !== null)9023 {9024 $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';9025 if ($items > 0)9026 {9027 $sql .= ' LIMIT ' . $items;9028 }9029 9030 if ($query = mysql_unbuffered_query($sql, $this->mysql))9031 {9032 while ($row = mysql_fetch_row($query))9033 {9034 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);9035 }9036 }9037 else9038 {9039 return false;9040 }9041 }9042 }9043 return $data;9044 }9045 return false;9046 }9047 9048 function mtime()9049 {9050 if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))9051 {9052 return $row[0];9053 }9054 else9055 {9056 return false;9057 }9058 }9059 9060 function touch()9061 {9062 if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))9063 {9064 return true;9065 }9066 else9067 {9068 return false;9069 }9070 }9071 9072 function unlink()9073 {9074 if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))9075 {9076 return true;9077 }9078 else9079 {9080 return false;9081 }9082 }9083 }9084 9085 class SimplePie_Misc9086 {9087 function time_hms($seconds)9088 {9089 $time = '';9090 9091 $hours = floor($seconds / 3600);9092 $remainder = $seconds % 3600;9093 if ($hours > 0)9094 {9095 $time .= $hours.':';9096 }9097 9098 $minutes = floor($remainder / 60);9099 $seconds = $remainder % 60;9100 if ($minutes < 10 && $hours > 0)9101 {9102 $minutes = '0' . $minutes;9103 }9104 if ($seconds < 10)9105 {9106 $seconds = '0' . $seconds;9107 }9108 9109 $time .= $minutes.':';9110 $time .= $seconds;9111 9112 return $time;9113 }9114 9115 function absolutize_url($relative, $base)9116 {9117 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);9118 return $iri->get_iri();9119 }9120 9121 function remove_dot_segments($input)9122 {9123 $output = '';9124 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')9125 {9126 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,9127 if (strpos($input, '../') === 0)9128 {9129 $input = substr($input, 3);9130 }9131 elseif (strpos($input, './') === 0)9132 {9133 $input = substr($input, 2);9134 }9135 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,9136 elseif (strpos($input, '/./') === 0)9137 {9138 $input = substr_replace($input, '/', 0, 3);9139 }9140 elseif ($input === '/.')9141 {9142 $input = '/';9143 }9144 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,9145 elseif (strpos($input, '/../') === 0)9146 {9147 $input = substr_replace($input, '/', 0, 4);9148 $output = substr_replace($output, '', strrpos($output, '/'));9149 }9150 elseif ($input === '/..')9151 {9152 $input = '/';9153 $output = substr_replace($output, '', strrpos($output, '/'));9154 }9155 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,9156 elseif ($input === '.' || $input === '..')9157 {9158 $input = '';9159 }9160 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer9161 elseif (($pos = strpos($input, '/', 1)) !== false)9162 {9163 $output .= substr($input, 0, $pos);9164 $input = substr_replace($input, '', 0, $pos);9165 }9166 else9167 {9168 $output .= $input;9169 $input = '';9170 }9171 }9172 return $output . $input;9173 }9174 9175 function get_element($realname, $string)9176 {9177 $return = array();9178 $name = preg_quote($realname, '/');9179 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))9180 {9181 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)9182 {9183 $return[$i]['tag'] = $realname;9184 $return[$i]['full'] = $matches[$i][0][0];9185 $return[$i]['offset'] = $matches[$i][0][1];9186 if (strlen($matches[$i][3][0]) <= 2)9187 {9188 $return[$i]['self_closing'] = true;9189 }9190 else9191 {9192 $return[$i]['self_closing'] = false;9193 $return[$i]['content'] = $matches[$i][4][0];9194 }9195 $return[$i]['attribs'] = array();9196 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))9197 {9198 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)9199 {9200 if (count($attribs[$j]) === 2)9201 {9202 $attribs[$j][2] = $attribs[$j][1];9203 }9204 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');9205 }9206 }9207 }9208 }9209 return $return;9210 }9211 9212 function element_implode($element)9213 {9214 $full = "<$element[tag]";9215 foreach ($element['attribs'] as $key => $value)9216 {9217 $key = strtolower($key);9218 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';9219 }9220 if ($element['self_closing'])9221 {9222 $full .= ' />';9223 }9224 else9225 {9226 $full .= ">$element[content]</$element[tag]>";9227 }9228 return $full;9229 }9230 9231 function error($message, $level, $file, $line)9232 {9233 if ((ini_get('error_reporting') & $level) > 0)9234 {9235 switch ($level)9236 {9237 case E_USER_ERROR:9238 $note = 'PHP Error';9239 break;9240 case E_USER_WARNING:9241 $note = 'PHP Warning';9242 break;9243 case E_USER_NOTICE:9244 $note = 'PHP Notice';9245 break;9246 default:9247 $note = 'Unknown Error';9248 break;9249 }9250 9251 $log_error = true;9252 if (!function_exists('error_log'))9253 {9254 $log_error = false;9255 }9256 9257 $log_file = @ini_get('error_log');9258 if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file))9259 {9260 $log_error = false;9261 }9262 9263 if ($log_error)9264 {9265 @error_log("$note: $message in $file on line $line", 0);9266 }9267 }9268 9269 return $message;9270 }9271 9272 /**9273 * If a file has been cached, retrieve and display it.9274 *9275 * This is most useful for caching images (get_favicon(), etc.),9276 * however it works for all cached files. This WILL NOT display ANY9277 * file/image/page/whatever, but rather only display what has already9278 * been cached by SimplePie.9279 *9280 * @access public9281 * @see SimplePie::get_favicon()9282 * @param str $identifier_url URL that is used to identify the content.9283 * This may or may not be the actual URL of the live content.9284 * @param str $cache_location Location of SimplePie's cache. Defaults9285 * to './cache'.9286 * @param str $cache_extension The file extension that the file was9287 * cached with. Defaults to 'spc'.9288 * @param str $cache_class Name of the cache-handling class being used9289 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left9290 * as-is unless you've overloaded the class.9291 * @param str $cache_name_function Obsolete. Exists for backwards9292 * compatibility reasons only.9293 */9294 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')9295 {9296 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);9297 9298 if ($file = $cache->load())9299 {9300 if (isset($file['headers']['content-type']))9301 {9302 header('Content-type:' . $file['headers']['content-type']);9303 }9304 else9305 {9306 header('Content-type: application/octet-stream');9307 }9308 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days9309 echo $file['body'];9310 exit;9311 }9312 9313 die('Cached file for ' . $identifier_url . ' cannot be found.');9314 }9315 9316 function fix_protocol($url, $http = 1)9317 {9318 $url = SimplePie_Misc::normalize_url($url);9319 $parsed = SimplePie_Misc::parse_url($url);9320 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')9321 {9322 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);9323 }9324 9325 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))9326 {9327 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);9328 }9329 9330 if ($http === 2 && $parsed['scheme'] !== '')9331 {9332 return "feed:$url";9333 }9334 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')9335 {9336 return substr_replace($url, 'podcast', 0, 4);9337 }9338 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')9339 {9340 return substr_replace($url, 'itpc', 0, 4);9341 }9342 else9343 {9344 return $url;9345 }9346 }9347 9348 function parse_url($url)9349 {9350 $iri =& new SimplePie_IRI($url);9351 return array(9352 'scheme' => (string) $iri->get_scheme(),9353 'authority' => (string) $iri->get_authority(),9354 'path' => (string) $iri->get_path(),9355 'query' => (string) $iri->get_query(),9356 'fragment' => (string) $iri->get_fragment()9357 );9358 }9359 9360 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')9361 {9362 $iri =& new SimplePie_IRI('');9363 $iri->set_scheme($scheme);9364 $iri->set_authority($authority);9365 $iri->set_path($path);9366 $iri->set_query($query);9367 $iri->set_fragment($fragment);9368 return $iri->get_iri();9369 }9370 9371 function normalize_url($url)9372 {9373 $iri =& new SimplePie_IRI($url);9374 return $iri->get_iri();9375 }9376 9377 function percent_encoding_normalization($match)9378 {9379 $integer = hexdec($match[1]);9380 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)9381 {9382 return chr($integer);9383 }9384 else9385 {9386 return strtoupper($match[0]);9387 }9388 }9389 9390 /**9391 * Remove bad UTF-8 bytes9392 *9393 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C9394 * FAQ: Multilingual Forms (modified to include full ASCII range)9395 *9396 * @author Geoffrey Sneddon9397 * @see http://www.w3.org/International/questions/qa-forms-utf-89398 * @param string $str String to remove bad UTF-8 bytes from9399 * @return string UTF-8 string9400 */9401 function utf8_bad_replace($str)9402 {9403 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))9404 {9405 return $return;9406 }9407 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))9408 {9409 return $return;9410 }9411 elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))9412 {9413 return implode("\xEF\xBF\xBD", $matches[0]);9414 }9415 elseif ($str !== '')9416 {9417 return "\xEF\xBF\xBD";9418 }9419 else9420 {9421 return '';9422 }9423 }9424 9425 /**9426 * Converts a Windows-1252 encoded string to a UTF-8 encoded string9427 *9428 * @static9429 * @access public9430 * @param string $string Windows-1252 encoded string9431 * @return string UTF-8 encoded string9432 */9433 function windows_1252_to_utf8($string)9434 {9435 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");9436 9437 return strtr($string, $convert_table);9438 }9439 9440 function change_encoding($data, $input, $output)9441 {9442 $input = SimplePie_Misc::encoding($input);9443 $output = SimplePie_Misc::encoding($output);9444 9445 // We fail to fail on non US-ASCII bytes9446 if ($input === 'US-ASCII')9447 {9448 static $non_ascii_octects = '';9449 if (!$non_ascii_octects)9450 {9451 for ($i = 0x80; $i <= 0xFF; $i++)9452 {9453 $non_ascii_octects .= chr($i);9454 }9455 }9456 $data = substr($data, 0, strcspn($data, $non_ascii_octects));9457 }9458 9459 // This is first, as behaviour of this is completely predictable9460 if ($input === 'windows-1252' && $output === 'UTF-8')9461 {9462 return SimplePie_Misc::windows_1252_to_utf8($data);9463 }9464 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).9465 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && in_array($input, mb_list_encodings()) && ($return = @mb_convert_encoding($data, $output, $input)))9466 {9467 return $return;9468 }9469 // This is last, as behaviour of this varies with OS userland and PHP version9470 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))9471 {9472 return $return;9473 }9474 // If we can't do anything, just fail9475 else9476 {9477 return false;9478 }9479 }9480 9481 /**9482 * Normalize an encoding name9483 *9484 * This is automatically generated by create.php9485 *9486 * To generate it, run `php create.php` on the command line, and copy the9487 * output to replace this function.9488 *9489 * @param string $charset Character set to standardise9490 * @return string Standardised name9491 */9492 function encoding($charset)9493 {9494 // Normalization from UTS #229495 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))9496 {9497 case 'adobestandardencoding':9498 case 'csadobestandardencoding':9499 return 'Adobe-Standard-Encoding';9500 9501 case 'adobesymbolencoding':9502 case 'cshppsmath':9503 return 'Adobe-Symbol-Encoding';9504 9505 case 'ami1251':9506 case 'amiga1251':9507 return 'Amiga-1251';9508 9509 case 'ansix31101983':9510 case 'csat5001983':9511 case 'csiso99naplps':9512 case 'isoir99':9513 case 'naplps':9514 return 'ANSI_X3.110-1983';9515 9516 case 'arabic7':9517 case 'asmo449':9518 case 'csiso89asmo449':9519 case 'iso9036':9520 case 'isoir89':9521 return 'ASMO_449';9522 9523 case 'big5':9524 case 'csbig5':9525 return 'Big5';9526 9527 case 'big5hkscs':9528 return 'Big5-HKSCS';9529 9530 case 'bocu1':9531 case 'csbocu1':9532 return 'BOCU-1';9533 9534 case 'brf':9535 case 'csbrf':9536 return 'BRF';9537 9538 case 'bs4730':9539 case 'csiso4unitedkingdom':9540 case 'gb':9541 case 'iso646gb':9542 case 'isoir4':9543 case 'uk':9544 return 'BS_4730';9545 9546 case 'bsviewdata':9547 case 'csiso47bsviewdata':9548 case 'isoir47':9549 return 'BS_viewdata';9550 9551 case 'cesu8':9552 case 'cscesu8':9553 return 'CESU-8';9554 9555 case 'ca':9556 case 'csa71':9557 case 'csaz243419851':9558 case 'csiso121canadian1':9559 case 'iso646ca':9560 case 'isoir121':9561 return 'CSA_Z243.4-1985-1';9562 9563 case 'csa72':9564 case 'csaz243419852':9565 case 'csiso122canadian2':9566 case 'iso646ca2':9567 case 'isoir122':9568 return 'CSA_Z243.4-1985-2';9569 9570 case 'csaz24341985gr':9571 case 'csiso123csaz24341985gr':9572 case 'isoir123':9573 return 'CSA_Z243.4-1985-gr';9574 9575 case 'csiso139csn369103':9576 case 'csn369103':9577 case 'isoir139':9578 return 'CSN_369103';9579 9580 case 'csdecmcs':9581 case 'dec':9582 case 'decmcs':9583 return 'DEC-MCS';9584 9585 case 'csiso21german':9586 case 'de':9587 case 'din66003':9588 case 'iso646de':9589 case 'isoir21':9590 return 'DIN_66003';9591 9592 case 'csdkus':9593 case 'dkus':9594 return 'dk-us';9595 9596 case 'csiso646danish':9597 case 'dk':9598 case 'ds2089':9599 case 'iso646dk':9600 return 'DS_2089';9601 9602 case 'csibmebcdicatde':9603 case 'ebcdicatde':9604 return 'EBCDIC-AT-DE';9605 9606 case 'csebcdicatdea':9607 case 'ebcdicatdea':9608 return 'EBCDIC-AT-DE-A';9609 9610 case 'csebcdiccafr':9611 case 'ebcdiccafr':9612 return 'EBCDIC-CA-FR';9613 9614 case 'csebcdicdkno':9615 case 'ebcdicdkno':9616 return 'EBCDIC-DK-NO';9617 9618 case 'csebcdicdknoa':9619 case 'ebcdicdknoa':9620 return 'EBCDIC-DK-NO-A';9621 9622 case 'csebcdices':9623 case 'ebcdices':9624 return 'EBCDIC-ES';9625 9626 case 'csebcdicesa':9627 case 'ebcdicesa':9628 return 'EBCDIC-ES-A';9629 9630 case 'csebcdicess':9631 case 'ebcdicess':9632 return 'EBCDIC-ES-S';9633 9634 case 'csebcdicfise':9635 case 'ebcdicfise':9636 return 'EBCDIC-FI-SE';9637 9638 case 'csebcdicfisea':9639 case 'ebcdicfisea':9640 return 'EBCDIC-FI-SE-A';9641 9642 case 'csebcdicfr':9643 case 'ebcdicfr':9644 return 'EBCDIC-FR';9645 9646 case 'csebcdicit':9647 case 'ebcdicit':9648 return 'EBCDIC-IT';9649 9650 case 'csebcdicpt':9651 case 'ebcdicpt':9652 return 'EBCDIC-PT';9653 9654 case 'csebcdicuk':9655 case 'ebcdicuk':9656 return 'EBCDIC-UK';9657 9658 case 'csebcdicus':9659 case 'ebcdicus':9660 return 'EBCDIC-US';9661 9662 case 'csiso111ecmacyrillic':9663 case 'ecmacyrillic':9664 case 'isoir111':9665 case 'koi8e':9666 return 'ECMA-cyrillic';9667 9668 case 'csiso17spanish':9669 case 'es':9670 case 'iso646es':9671 case 'isoir17':9672 return 'ES';9673 9674 case 'csiso85spanish2':9675 case 'es2':9676 case 'iso646es2':9677 case 'isoir85':9678 return 'ES2';9679 9680 case 'cseucpkdfmtjapanese':9681 case 'eucjp':9682 case 'extendedunixcodepackedformatforjapanese':9683 return 'EUC-JP';9684 9685 case 'cseucfixwidjapanese':9686 case 'extendedunixcodefixedwidthforjapanese':9687 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';9688 9689 case 'gb18030':9690 return 'GB18030';9691 9692 case 'chinese':9693 case 'cp936':9694 case 'csgb2312':9695 case 'csiso58gb231280':9696 case 'gb2312':9697 case 'gb231280':9698 case 'gbk':9699 case 'isoir58':9700 case 'ms936':9701 case 'windows936':9702 return 'GBK';9703 9704 case 'cn':9705 case 'csiso57gb1988':9706 case 'gb198880':9707 case 'iso646cn':9708 case 'isoir57':9709 return 'GB_1988-80';9710 9711 case 'csiso153gost1976874':9712 case 'gost1976874':9713 case 'isoir153':9714 case 'stsev35888':9715 return 'GOST_19768-74';9716 9717 case 'csiso150':9718 case 'csiso150greekccitt':9719 case 'greekccitt':9720 case 'isoir150':9721 return 'greek-ccitt';9722 9723 case 'csiso88greek7':9724 case 'greek7':9725 case 'isoir88':9726 return 'greek7';9727 9728 case 'csiso18greek7old':9729 case 'greek7old':9730 case 'isoir18':9731 return 'greek7-old';9732 9733 case 'cshpdesktop':9734 case 'hpdesktop':9735 return 'HP-DeskTop';9736 9737 case 'cshplegal':9738 case 'hplegal':9739 return 'HP-Legal';9740 9741 case 'cshpmath8':9742 case 'hpmath8':9743 return 'HP-Math8';9744 9745 case 'cshppifont':9746 case 'hppifont':9747 return 'HP-Pi-font';9748 9749 case 'cshproman8':9750 case 'hproman8':9751 case 'r8':9752 case 'roman8':9753 return 'hp-roman8';9754 9755 case 'hzgb2312':9756 return 'HZ-GB-2312';9757 9758 case 'csibmsymbols':9759 case 'ibmsymbols':9760 return 'IBM-Symbols';9761 9762 case 'csibmthai':9763 case 'ibmthai':9764 return 'IBM-Thai';9765 9766 case 'cp37':9767 case 'csibm37':9768 case 'ebcdiccpca':9769 case 'ebcdiccpnl':9770 case 'ebcdiccpus':9771 case 'ebcdiccpwt':9772 case 'ibm37':9773 return 'IBM037';9774 9775 case 'cp38':9776 case 'csibm38':9777 case 'ebcdicint':9778 case 'ibm38':9779 return 'IBM038';9780 9781 case 'cp273':9782 case 'csibm273':9783 case 'ibm273':9784 return 'IBM273';9785 9786 case 'cp274':9787 case 'csibm274':9788 case 'ebcdicbe':9789 case 'ibm274':9790 return 'IBM274';9791 9792 case 'cp275':9793 case 'csibm275':9794 case 'ebcdicbr':9795 case 'ibm275':9796 return 'IBM275';9797 9798 case 'csibm277':9799 case 'ebcdiccpdk':9800 case 'ebcdiccpno':9801 case 'ibm277':9802 return 'IBM277';9803 9804 case 'cp278':9805 case 'csibm278':9806 case 'ebcdiccpfi':9807 case 'ebcdiccpse':9808 case 'ibm278':9809 return 'IBM278';9810 9811 case 'cp280':9812 case 'csibm280':9813 case 'ebcdiccpit':9814 case 'ibm280':9815 return 'IBM280';9816 9817 case 'cp281':9818 case 'csibm281':9819 case 'ebcdicjpe':9820 case 'ibm281':9821 return 'IBM281';9822 9823 case 'cp284':9824 case 'csibm284':9825 case 'ebcdiccpes':9826 case 'ibm284':9827 return 'IBM284';9828 9829 case 'cp285':9830 case 'csibm285':9831 case 'ebcdiccpgb':9832 case 'ibm285':9833 return 'IBM285';9834 9835 case 'cp290':9836 case 'csibm290':9837 case 'ebcdicjpkana':9838 case 'ibm290':9839 return 'IBM290';9840 9841 case 'cp297':9842 case 'csibm297':9843 case 'ebcdiccpfr':9844 case 'ibm297':9845 return 'IBM297';9846 9847 case 'cp420':9848 case 'csibm420':9849 case 'ebcdiccpar1':9850 case 'ibm420':9851 return 'IBM420';9852 9853 case 'cp423':9854 case 'csibm423':9855 case 'ebcdiccpgr':9856 case 'ibm423':9857 return 'IBM423';9858 9859 case 'cp424':9860 case 'csibm424':9861 case 'ebcdiccphe':9862 case 'ibm424':9863 return 'IBM424';9864 9865 case '437':9866 case 'cp437':9867 case 'cspc8codepage437':9868 case 'ibm437':9869 return 'IBM437';9870 9871 case 'cp500':9872 case 'csibm500':9873 case 'ebcdiccpbe':9874 case 'ebcdiccpch':9875 case 'ibm500':9876 return 'IBM500';9877 9878 case 'cp775':9879 case 'cspc775baltic':9880 case 'ibm775':9881 return 'IBM775';9882 9883 case '850':9884 case 'cp850':9885 case 'cspc850multilingual':9886 case 'ibm850':9887 return 'IBM850';9888 9889 case '851':9890 case 'cp851':9891 case 'csibm851':9892 case 'ibm851':9893 return 'IBM851';9894 9895 case '852':9896 case 'cp852':9897 case 'cspcp852':9898 case 'ibm852':9899 return 'IBM852';9900 9901 case '855':9902 case 'cp855':9903 case 'csibm855':9904 case 'ibm855':9905 return 'IBM855';9906 9907 case '857':9908 case 'cp857':9909 case 'csibm857':9910 case 'ibm857':9911 return 'IBM857';9912 9913 case 'ccsid858':9914 case 'cp858':9915 case 'ibm858':9916 case 'pcmultilingual850euro':9917 return 'IBM00858';9918 9919 case '860':9920 case 'cp860':9921 case 'csibm860':9922 case 'ibm860':9923 return 'IBM860';9924 9925 case '861':9926 case 'cp861':9927 case 'cpis':9928 case 'csibm861':9929 case 'ibm861':9930 return 'IBM861';9931 9932 case '862':9933 case 'cp862':9934 case 'cspc862latinhebrew':9935 case 'ibm862':9936 return 'IBM862';9937 9938 case '863':9939 case 'cp863':9940 case 'csibm863':9941 case 'ibm863':9942 return 'IBM863';9943 9944 case 'cp864':9945 case 'csibm864':9946 case 'ibm864':9947 return 'IBM864';9948 9949 case '865':9950 case 'cp865':9951 case 'csibm865':9952 case 'ibm865':9953 return 'IBM865';9954 9955 case '866':9956 case 'cp866':9957 case 'csibm866':9958 case 'ibm866':9959 return 'IBM866';9960 9961 case 'cp868':9962 case 'cpar':9963 case 'csibm868':9964 case 'ibm868':9965 return 'IBM868';9966 9967 case '869':9968 case 'cp869':9969 case 'cpgr':9970 case 'csibm869':9971 case 'ibm869':9972 return 'IBM869';9973 9974 case 'cp870':9975 case 'csibm870':9976 case 'ebcdiccproece':9977 case 'ebcdiccpyu':9978 case 'ibm870':9979 return 'IBM870';9980 9981 case 'cp871':9982 case 'csibm871':9983 case 'ebcdiccpis':9984 case 'ibm871':9985 return 'IBM871';9986 9987 case 'cp880':9988 case 'csibm880':9989 case 'ebcdiccyrillic':9990 case 'ibm880':9991 return 'IBM880';9992 9993 case 'cp891':9994 case 'csibm891':9995 case 'ibm891':9996 return 'IBM891';9997 9998 case 'cp903':9999 case 'csibm903':10000 case 'ibm903':10001 return 'IBM903';10002 10003 case '904':10004 case 'cp904':10005 case 'csibbm904':10006 case 'ibm904':10007 return 'IBM904';10008 10009 case 'cp905':10010 case 'csibm905':10011 case 'ebcdiccptr':10012 case 'ibm905':10013 return 'IBM905';10014 10015 case 'cp918':10016 case 'csibm918':10017 case 'ebcdiccpar2':10018 case 'ibm918':10019 return 'IBM918';10020 10021 case 'ccsid924':10022 case 'cp924':10023 case 'ebcdiclatin9euro':10024 case 'ibm924':10025 return 'IBM00924';10026 10027 case 'cp1026':10028 case 'csibm1026':10029 case 'ibm1026':10030 return 'IBM1026';10031 10032 case 'ibm1047':10033 return 'IBM1047';10034 10035 case 'ccsid1140':10036 case 'cp1140':10037 case 'ebcdicus37euro':10038 case 'ibm1140':10039 return 'IBM01140';10040 10041 case 'ccsid1141':10042 case 'cp1141':10043 case 'ebcdicde273euro':10044 case 'ibm1141':10045 return 'IBM01141';10046 10047 case 'ccsid1142':10048 case 'cp1142':10049 case 'ebcdicdk277euro':10050 case 'ebcdicno277euro':10051 case 'ibm1142':10052 return 'IBM01142';10053 10054 case 'ccsid1143':10055 case 'cp1143':10056 case 'ebcdicfi278euro':10057 case 'ebcdicse278euro':10058 case 'ibm1143':10059 return 'IBM01143';10060 10061 case 'ccsid1144':10062 case 'cp1144':10063 case 'ebcdicit280euro':10064 case 'ibm1144':10065 return 'IBM01144';10066 10067 case 'ccsid1145':10068 case 'cp1145':10069 case 'ebcdices284euro':10070 case 'ibm1145':10071 return 'IBM01145';10072 10073 case 'ccsid1146':10074 case 'cp1146':10075 case 'ebcdicgb285euro':10076 case 'ibm1146':10077 return 'IBM01146';10078 10079 case 'ccsid1147':10080 case 'cp1147':10081 case 'ebcdicfr297euro':10082 case 'ibm1147':10083 return 'IBM01147';10084 10085 case 'ccsid1148':10086 case 'cp1148':10087 case 'ebcdicinternational500euro':10088 case 'ibm1148':10089 return 'IBM01148';10090 10091 case 'ccsid1149':10092 case 'cp1149':10093 case 'ebcdicis871euro':10094 case 'ibm1149':10095 return 'IBM01149';10096 10097 case 'csiso143iecp271':10098 case 'iecp271':10099 case 'isoir143':10100 return 'IEC_P27-1';10101 10102 case 'csiso49inis':10103 case 'inis':10104 case 'isoir49':10105 return 'INIS';10106 10107 case 'csiso50inis8':10108 case 'inis8':10109 case 'isoir50':10110 return 'INIS-8';10111 10112 case 'csiso51iniscyrillic':10113 case 'iniscyrillic':10114 case 'isoir51':10115 return 'INIS-cyrillic';10116 10117 case 'csinvariant':10118 case 'invariant':10119 return 'INVARIANT';10120 10121 case 'iso2022cn':10122 return 'ISO-2022-CN';10123 10124 case 'iso2022cnext':10125 return 'ISO-2022-CN-EXT';10126 10127 case 'csiso2022jp':10128 case 'iso2022jp':10129 return 'ISO-2022-JP';10130 10131 case 'csiso2022jp2':10132 case 'iso2022jp2':10133 return 'ISO-2022-JP-2';10134 10135 case 'csiso2022kr':10136 case 'iso2022kr':10137 return 'ISO-2022-KR';10138 10139 case 'cswindows30latin1':10140 case 'iso88591windows30latin1':10141 return 'ISO-8859-1-Windows-3.0-Latin-1';10142 10143 case 'cswindows31latin1':10144 case 'iso88591windows31latin1':10145 return 'ISO-8859-1-Windows-3.1-Latin-1';10146 10147 case 'csisolatin2':10148 case 'iso88592':10149 case 'iso885921987':10150 case 'isoir101':10151 case 'l2':10152 case 'latin2':10153 return 'ISO-8859-2';10154 10155 case 'cswindows31latin2':10156 case 'iso88592windowslatin2':10157 return 'ISO-8859-2-Windows-Latin-2';10158 10159 case 'csisolatin3':10160 case 'iso88593':10161 case 'iso885931988':10162 case 'isoir109':10163 case 'l3':10164 case 'latin3':10165 return 'ISO-8859-3';10166 10167 case 'csisolatin4':10168 case 'iso88594':10169 case 'iso885941988':10170 case 'isoir110':10171 case 'l4':10172 case 'latin4':10173 return 'ISO-8859-4';10174 10175 case 'csisolatincyrillic':10176 case 'cyrillic':10177 case 'iso88595':10178 case 'iso885951988':10179 case 'isoir144':10180 return 'ISO-8859-5';10181 10182 case 'arabic':10183 case 'asmo708':10184 case 'csisolatinarabic':10185 case 'ecma114':10186 case 'iso88596':10187 case 'iso885961987':10188 case 'isoir127':10189 return 'ISO-8859-6';10190 10191 case 'csiso88596e':10192 case 'iso88596e':10193 return 'ISO-8859-6-E';10194 10195 case 'csiso88596i':10196 case 'iso88596i':10197 return 'ISO-8859-6-I';10198 10199 case 'csisolatingreek':10200 case 'ecma118':10201 case 'elot928':10202 case 'greek':10203 case 'greek8':10204 case 'iso88597':10205 case 'iso885971987':10206 case 'isoir126':10207 return 'ISO-8859-7';10208 10209 case 'csisolatinhebrew':10210 case 'hebrew':10211 case 'iso88598':10212 case 'iso885981988':10213 case 'isoir138':10214 return 'ISO-8859-8';10215 10216 case 'csiso88598e':10217 case 'iso88598e':10218 return 'ISO-8859-8-E';10219 10220 case 'csiso88598i':10221 case 'iso88598i':10222 return 'ISO-8859-8-I';10223 10224 case 'cswindows31latin5':10225 case 'iso88599windowslatin5':10226 return 'ISO-8859-9-Windows-Latin-5';10227 10228 case 'csisolatin6':10229 case 'iso885910':10230 case 'iso8859101992':10231 case 'isoir157':10232 case 'l6':10233 case 'latin6':10234 return 'ISO-8859-10';10235 10236 case 'iso885913':10237 return 'ISO-8859-13';10238 10239 case 'iso885914':10240 case 'iso8859141998':10241 case 'isoceltic':10242 case 'isoir199':10243 case 'l8':10244 case 'latin8':10245 return 'ISO-8859-14';10246 10247 case 'iso885915':10248 case 'latin9':10249 return 'ISO-8859-15';10250 10251 case 'iso885916':10252 case 'iso8859162001':10253 case 'isoir226':10254 case 'l10':10255 case 'latin10':10256 return 'ISO-8859-16';10257 10258 case 'iso10646j1':10259 return 'ISO-10646-J-1';10260 10261 case 'csunicode':10262 case 'iso10646ucs2':10263 return 'ISO-10646-UCS-2';10264 10265 case 'csucs4':10266 case 'iso10646ucs4':10267 return 'ISO-10646-UCS-4';10268 10269 case 'csunicodeascii':10270 case 'iso10646ucsbasic':10271 return 'ISO-10646-UCS-Basic';10272 10273 case 'csunicodelatin1':10274 case 'iso10646':10275 case 'iso10646unicodelatin1':10276 return 'ISO-10646-Unicode-Latin1';10277 10278 case 'csiso10646utf1':10279 case 'iso10646utf1':10280 return 'ISO-10646-UTF-1';10281 10282 case 'csiso115481':10283 case 'iso115481':10284 case 'isotr115481':10285 return 'ISO-11548-1';10286 10287 case 'csiso90':10288 case 'isoir90':10289 return 'iso-ir-90';10290 10291 case 'csunicodeibm1261':10292 case 'isounicodeibm1261':10293 return 'ISO-Unicode-IBM-1261';10294 10295 case 'csunicodeibm1264':10296 case 'isounicodeibm1264':10297 return 'ISO-Unicode-IBM-1264';10298 10299 case 'csunicodeibm1265':10300 case 'isounicodeibm1265':10301 return 'ISO-Unicode-IBM-1265';10302 10303 case 'csunicodeibm1268':10304 case 'isounicodeibm1268':10305 return 'ISO-Unicode-IBM-1268';10306 10307 case 'csunicodeibm1276':10308 case 'isounicodeibm1276':10309 return 'ISO-Unicode-IBM-1276';10310 10311 case 'csiso646basic1983':10312 case 'iso646basic1983':10313 case 'ref':10314 return 'ISO_646.basic:1983';10315 10316 case 'csiso2intlrefversion':10317 case 'irv':10318 case 'iso646irv1983':10319 case 'isoir2':10320 return 'ISO_646.irv:1983';10321 10322 case 'csiso2033':10323 case 'e13b':10324 case 'iso20331983':10325 case 'isoir98':10326 return 'ISO_2033-1983';10327 10328 case 'csiso5427cyrillic':10329 case 'iso5427':10330 case 'isoir37':10331 return 'ISO_5427';10332 10333 case 'iso5427cyrillic1981':10334 case 'iso54271981':10335 case 'isoir54':10336 return 'ISO_5427:1981';10337 10338 case 'csiso5428greek':10339 case 'iso54281980':10340 case 'isoir55':10341 return 'ISO_5428:1980';10342 10343 case 'csiso6937add':10344 case 'iso6937225':10345 case 'isoir152':10346 return 'ISO_6937-2-25';10347 10348 case 'csisotextcomm':10349 case 'iso69372add':10350 case 'isoir142':10351 return 'ISO_6937-2-add';10352 10353 case 'csiso8859supp':10354 case 'iso8859supp':10355 case 'isoir154':10356 case 'latin125':10357 return 'ISO_8859-supp';10358 10359 case 'csiso10367box':10360 case 'iso10367box':10361 case 'isoir155':10362 return 'ISO_10367-box';10363 10364 case 'csiso15italian':10365 case 'iso646it':10366 case 'isoir15':10367 case 'it':10368 return 'IT';10369 10370 case 'csiso13jisc6220jp':10371 case 'isoir13':10372 case 'jisc62201969':10373 case 'jisc62201969jp':10374 case 'katakana':10375 case 'x2017':10376 return 'JIS_C6220-1969-jp';10377 10378 case 'csiso14jisc6220ro':10379 case 'iso646jp':10380 case 'isoir14':10381 case 'jisc62201969ro':10382 case 'jp':10383 return 'JIS_C6220-1969-ro';10384 10385 case 'csiso42jisc62261978':10386 case 'isoir42':10387 case 'jisc62261978':10388 return 'JIS_C6226-1978';10389 10390 case 'csiso87jisx208':10391 case 'isoir87':10392 case 'jisc62261983':10393 case 'jisx2081983':10394 case 'x208':10395 return 'JIS_C6226-1983';10396 10397 case 'csiso91jisc62291984a':10398 case 'isoir91':10399 case 'jisc62291984a':10400 case 'jpocra':10401 return 'JIS_C6229-1984-a';10402 10403 case 'csiso92jisc62991984b':10404 case 'iso646jpocrb':10405 case 'isoir92':10406 case 'jisc62291984b':10407 case 'jpocrb':10408 return 'JIS_C6229-1984-b';10409 10410 case 'csiso93jis62291984badd':10411 case 'isoir93':10412 case 'jisc62291984badd':10413 case 'jpocrbadd':10414 return 'JIS_C6229-1984-b-add';10415 10416 case 'csiso94jis62291984hand':10417 case 'isoir94':10418 case 'jisc62291984hand':10419 case 'jpocrhand':10420 return 'JIS_C6229-1984-hand';10421 10422 case 'csiso95jis62291984handadd':10423 case 'isoir95':10424 case 'jisc62291984handadd':10425 case 'jpocrhandadd':10426 return 'JIS_C6229-1984-hand-add';10427 10428 case 'csiso96jisc62291984kana':10429 case 'isoir96':10430 case 'jisc62291984kana':10431 return 'JIS_C6229-1984-kana';10432 10433 case 'csjisencoding':10434 case 'jisencoding':10435 return 'JIS_Encoding';10436 10437 case 'cshalfwidthkatakana':10438 case 'jisx201':10439 case 'x201':10440 return 'JIS_X0201';10441 10442 case 'csiso159jisx2121990':10443 case 'isoir159':10444 case 'jisx2121990':10445 case 'x212':10446 return 'JIS_X0212-1990';10447 10448 case 'csiso141jusib1002':10449 case 'iso646yu':10450 case 'isoir141':10451 case 'js':10452 case 'jusib1002':10453 case 'yu':10454 return 'JUS_I.B1.002';10455 10456 case 'csiso147macedonian':10457 case 'isoir147':10458 case 'jusib1003mac':10459 case 'macedonian':10460 return 'JUS_I.B1.003-mac';10461 10462 case 'csiso146serbian':10463 case 'isoir146':10464 case 'jusib1003serb':10465 case 'serbian':10466 return 'JUS_I.B1.003-serb';10467 10468 case 'koi7switched':10469 return 'KOI7-switched';10470 10471 case 'cskoi8r':10472 case 'koi8r':10473 return 'KOI8-R';10474 10475 case 'koi8u':10476 return 'KOI8-U';10477 10478 case 'csksc5636':10479 case 'iso646kr':10480 case 'ksc5636':10481 return 'KSC5636';10482 10483 case 'cskz1048':10484 case 'kz1048':10485 case 'rk1048':10486 case 'strk10482002':10487 return 'KZ-1048';10488 10489 case 'csiso19latingreek':10490 case 'isoir19':10491 case 'latingreek':10492 return 'latin-greek';10493 10494 case 'csiso27latingreek1':10495 case 'isoir27':10496 case 'latingreek1':10497 return 'Latin-greek-1';10498 10499 case 'csiso158lap':10500 case 'isoir158':10501 case 'lap':10502 case 'latinlap':10503 return 'latin-lap';10504 10505 case 'csmacintosh':10506 case 'mac':10507 case 'macintosh':10508 return 'macintosh';10509 10510 case 'csmicrosoftpublishing':10511 case 'microsoftpublishing':10512 return 'Microsoft-Publishing';10513 10514 case 'csmnem':10515 case 'mnem':10516 return 'MNEM';10517 10518 case 'csmnemonic':10519 case 'mnemonic':10520 return 'MNEMONIC';10521 10522 case 'csiso86hungarian':10523 case 'hu':10524 case 'iso646hu':10525 case 'isoir86':10526 case 'msz77953':10527 return 'MSZ_7795.3';10528 10529 case 'csnatsdano':10530 case 'isoir91':10531 case 'natsdano':10532 return 'NATS-DANO';10533 10534 case 'csnatsdanoadd':10535 case 'isoir92':10536 case 'natsdanoadd':10537 return 'NATS-DANO-ADD';10538 10539 case 'csnatssefi':10540 case 'isoir81':10541 case 'natssefi':10542 return 'NATS-SEFI';10543 10544 case 'csnatssefiadd':10545 case 'isoir82':10546 case 'natssefiadd':10547 return 'NATS-SEFI-ADD';10548 10549 case 'csiso151cuba':10550 case 'cuba':10551 case 'iso646cu':10552 case 'isoir151':10553 case 'ncnc1081':10554 return 'NC_NC00-10:81';10555 10556 case 'csiso69french':10557 case 'fr':10558 case 'iso646fr':10559 case 'isoir69':10560 case 'nfz62010':10561 return 'NF_Z_62-010';10562 10563 case 'csiso25french':10564 case 'iso646fr1':10565 case 'isoir25':10566 case 'nfz620101973':10567 return 'NF_Z_62-010_(1973)';10568 10569 case 'csiso60danishnorwegian':10570 case 'csiso60norwegian1':10571 case 'iso646no':10572 case 'isoir60':10573 case 'no':10574 case 'ns45511':10575 return 'NS_4551-1';10576 10577 case 'csiso61norwegian2':10578 case 'iso646no2':10579 case 'isoir61':10580 case 'no2':10581 case 'ns45512':10582 return 'NS_4551-2';10583 10584 case 'osdebcdicdf3irv':10585 return 'OSD_EBCDIC_DF03_IRV';10586 10587 case 'osdebcdicdf41':10588 return 'OSD_EBCDIC_DF04_1';10589 10590 case 'osdebcdicdf415':10591 return 'OSD_EBCDIC_DF04_15';10592 10593 case 'cspc8danishnorwegian':10594 case 'pc8danishnorwegian':10595 return 'PC8-Danish-Norwegian';10596 10597 case 'cspc8turkish':10598 case 'pc8turkish':10599 return 'PC8-Turkish';10600 10601 case 'csiso16portuguese':10602 case 'iso646pt':10603 case 'isoir16':10604 case 'pt':10605 return 'PT';10606 10607 case 'csiso84portuguese2':10608 case 'iso646pt2':10609 case 'isoir84':10610 case 'pt2':10611 return 'PT2';10612 10613 case 'cp154':10614 case 'csptcp154':10615 case 'cyrillicasian':10616 case 'pt154':10617 case 'ptcp154':10618 return 'PTCP154';10619 10620 case 'scsu':10621 return 'SCSU';10622 10623 case 'csiso10swedish':10624 case 'fi':10625 case 'iso646fi':10626 case 'iso646se':10627 case 'isoir10':10628 case 'se':10629 case 'sen850200b':10630 return 'SEN_850200_B';10631 10632 case 'csiso11swedishfornames':10633 case 'iso646se2':10634 case 'isoir11':10635 case 'se2':10636 case 'sen850200c':10637 return 'SEN_850200_C';10638 10639 case 'csiso102t617bit':10640 case 'isoir102':10641 case 't617bit':10642 return 'T.61-7bit';10643 10644 case 'csiso103t618bit':10645 case 'isoir103':10646 case 't61':10647 case 't618bit':10648 return 'T.61-8bit';10649 10650 case 'csiso128t101g2':10651 case 'isoir128':10652 case 't101g2':10653 return 'T.101-G2';10654 10655 case 'cstscii':10656 case 'tscii':10657 return 'TSCII';10658 10659 case 'csunicode11':10660 case 'unicode11':10661 return 'UNICODE-1-1';10662 10663 case 'csunicode11utf7':10664 case 'unicode11utf7':10665 return 'UNICODE-1-1-UTF-7';10666 10667 case 'csunknown8bit':10668 case 'unknown8bit':10669 return 'UNKNOWN-8BIT';10670 10671 case 'ansix341968':10672 case 'ansix341986':10673 case 'ascii':10674 case 'cp367':10675 case 'csascii':10676 case 'ibm367':10677 case 'iso646irv1991':10678 case 'iso646us':10679 case 'isoir6':10680 case 'us':10681 case 'usascii':10682 return 'US-ASCII';10683 10684 case 'csusdk':10685 case 'usdk':10686 return 'us-dk';10687 10688 case 'utf7':10689 return 'UTF-7';10690 10691 case 'utf8':10692 return 'UTF-8';10693 10694 case 'utf16':10695 return 'UTF-16';10696 10697 case 'utf16be':10698 return 'UTF-16BE';10699 10700 case 'utf16le':10701 return 'UTF-16LE';10702 10703 case 'utf32':10704 return 'UTF-32';10705 10706 case 'utf32be':10707 return 'UTF-32BE';10708 10709 case 'utf32le':10710 return 'UTF-32LE';10711 10712 case 'csventurainternational':10713 case 'venturainternational':10714 return 'Ventura-International';10715 10716 case 'csventuramath':10717 case 'venturamath':10718 return 'Ventura-Math';10719 10720 case 'csventuraus':10721 case 'venturaus':10722 return 'Ventura-US';10723 10724 case 'csiso70videotexsupp1':10725 case 'isoir70':10726 case 'videotexsuppl':10727 return 'videotex-suppl';10728 10729 case 'csviqr':10730 case 'viqr':10731 return 'VIQR';10732 10733 case 'csviscii':10734 case 'viscii':10735 return 'VISCII';10736 10737 case 'csshiftjis':10738 case 'cswindows31j':10739 case 'mskanji':10740 case 'shiftjis':10741 case 'windows31j':10742 return 'Windows-31J';10743 10744 case 'iso885911':10745 case 'tis620':10746 return 'windows-874';10747 10748 case 'cseuckr':10749 case 'csksc56011987':10750 case 'euckr':10751 case 'isoir149':10752 case 'korean':10753 case 'ksc5601':10754 case 'ksc56011987':10755 case 'ksc56011989':10756 case 'windows949':10757 return 'windows-949';10758 10759 case 'windows1250':10760 return 'windows-1250';10761 10762 case 'windows1251':10763 return 'windows-1251';10764 10765 case 'cp819':10766 case 'csisolatin1':10767 case 'ibm819':10768 case 'iso88591':10769 case 'iso885911987':10770 case 'isoir100':10771 case 'l1':10772 case 'latin1':10773 case 'windows1252':10774 return 'windows-1252';10775 10776 case 'windows1253':10777 return 'windows-1253';10778 10779 case 'csisolatin5':10780 case 'iso88599':10781 case 'iso885991989':10782 case 'isoir148':10783 case 'l5':10784 case 'latin5':10785 case 'windows1254':10786 return 'windows-1254';10787 10788 case 'windows1255':10789 return 'windows-1255';10790 10791 case 'windows1256':10792 return 'windows-1256';10793 10794 case 'windows1257':10795 return 'windows-1257';10796 10797 case 'windows1258':10798 return 'windows-1258';10799 10800 default:10801 return $charset;10802 }10803 }10804 10805 function get_curl_version()10806 {10807 if (is_array($curl = curl_version()))10808 {10809 $curl = $curl['version'];10810 }10811 elseif (substr($curl, 0, 5) === 'curl/')10812 {10813 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));10814 }10815 elseif (substr($curl, 0, 8) === 'libcurl/')10816 {10817 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));10818 }10819 else10820 {10821 $curl = 0;10822 }10823 return $curl;10824 }10825 10826 function is_subclass_of($class1, $class2)10827 {10828 if (func_num_args() !== 2)10829 {10830 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);10831 }10832 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))10833 {10834 return is_subclass_of($class1, $class2);10835 }10836 elseif (is_string($class1) && is_string($class2))10837 {10838 if (class_exists($class1))10839 {10840 if (class_exists($class2))10841 {10842 $class2 = strtolower($class2);10843 while ($class1 = strtolower(get_parent_class($class1)))10844 {10845 if ($class1 === $class2)10846 {10847 return true;10848 }10849 }10850 }10851 }10852 else10853 {10854 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);10855 }10856 }10857 return false;10858 }10859 10860 /**10861 * Strip HTML comments10862 *10863 * @access public10864 * @param string $data Data to strip comments from10865 * @return string Comment stripped string10866 */10867 function strip_comments($data)10868 {10869 $output = '';10870 while (($start = strpos($data, '<!--')) !== false)10871 {10872 $output .= substr($data, 0, $start);10873 if (($end = strpos($data, '-->', $start)) !== false)10874 {10875 $data = substr_replace($data, '', 0, $end + 3);10876 }10877 else10878 {10879 $data = '';10880 }10881 }10882 return $output . $data;10883 }10884 10885 function parse_date($dt)10886 {10887 $parser = SimplePie_Parse_Date::get();10888 return $parser->parse($dt);10889 }10890 10891 /**10892 * Decode HTML entities10893 *10894 * @static10895 * @access public10896 * @param string $data Input data10897 * @return string Output data10898 */10899 function entities_decode($data)10900 {10901 $decoder =& new SimplePie_Decode_HTML_Entities($data);10902 return $decoder->parse();10903 }10904 10905 /**10906 * Remove RFC822 comments10907 *10908 * @access public10909 * @param string $data Data to strip comments from10910 * @return string Comment stripped string10911 */10912 function uncomment_rfc822($string)10913 {10914 $string = (string) $string;10915 $position = 0;10916 $length = strlen($string);10917 $depth = 0;10918 10919 $output = '';10920 10921 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)10922 {10923 $output .= substr($string, $position, $pos - $position);10924 $position = $pos + 1;10925 if ($string[$pos - 1] !== '\\')10926 {10927 $depth++;10928 while ($depth && $position < $length)10929 {10930 $position += strcspn($string, '()', $position);10931 if ($string[$position - 1] === '\\')10932 {10933 $position++;10934 continue;10935 }10936 elseif (isset($string[$position]))10937 {10938 switch ($string[$position])10939 {10940 case '(':10941 $depth++;10942 break;10943 10944 case ')':10945 $depth--;10946 break;10947 }10948 $position++;10949 }10950 else10951 {10952 break;10953 }10954 }10955 }10956 else10957 {10958 $output .= '(';10959 }10960 }10961 $output .= substr($string, $position);10962 10963 return $output;10964 }10965 10966 function parse_mime($mime)10967 {10968 if (($pos = strpos($mime, ';')) === false)10969 {10970 return trim($mime);10971 }10972 else10973 {10974 return trim(substr($mime, 0, $pos));10975 }10976 }10977 10978 function htmlspecialchars_decode($string, $quote_style)10979 {10980 if (function_exists('htmlspecialchars_decode'))10981 {10982 return htmlspecialchars_decode($string, $quote_style);10983 }10984 else10985 {10986 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));10987 }10988 }10989 10990 function atom_03_construct_type($attribs)10991 {10992 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))10993 {10994 $mode = SIMPLEPIE_CONSTRUCT_BASE64;10995 }10996 else10997 {10998 $mode = SIMPLEPIE_CONSTRUCT_NONE;10999 }11000 if (isset($attribs['']['type']))11001 {11002 switch (strtolower(trim($attribs['']['type'])))11003 {11004 case 'text':11005 case 'text/plain':11006 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;11007 11008 case 'html':11009 case 'text/html':11010 return SIMPLEPIE_CONSTRUCT_HTML | $mode;11011 11012 case 'xhtml':11013 case 'application/xhtml+xml':11014 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;11015 11016 default:11017 return SIMPLEPIE_CONSTRUCT_NONE | $mode;11018 }11019 }11020 else11021 {11022 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;11023 }11024 }11025 11026 function atom_10_construct_type($attribs)11027 {11028 if (isset($attribs['']['type']))11029 {11030 switch (strtolower(trim($attribs['']['type'])))11031 {11032 case 'text':11033 return SIMPLEPIE_CONSTRUCT_TEXT;11034 11035 case 'html':11036 return SIMPLEPIE_CONSTRUCT_HTML;11037 11038 case 'xhtml':11039 return SIMPLEPIE_CONSTRUCT_XHTML;11040 11041 default:11042 return SIMPLEPIE_CONSTRUCT_NONE;11043 }11044 }11045 return SIMPLEPIE_CONSTRUCT_TEXT;11046 }11047 11048 function atom_10_content_construct_type($attribs)11049 {11050 if (isset($attribs['']['type']))11051 {11052 $type = strtolower(trim($attribs['']['type']));11053 switch ($type)11054 {11055 case 'text':11056 return SIMPLEPIE_CONSTRUCT_TEXT;11057 11058 case 'html':11059 return SIMPLEPIE_CONSTRUCT_HTML;11060 11061 case 'xhtml':11062 return SIMPLEPIE_CONSTRUCT_XHTML;11063 }11064 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')11065 {11066 return SIMPLEPIE_CONSTRUCT_NONE;11067 }11068 else11069 {11070 return SIMPLEPIE_CONSTRUCT_BASE64;11071 }11072 }11073 else11074 {11075 return SIMPLEPIE_CONSTRUCT_TEXT;11076 }11077 }11078 11079 function is_isegment_nz_nc($string)11080 {11081 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);11082 }11083 11084 function space_seperated_tokens($string)11085 {11086 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";11087 $string_length = strlen($string);11088 11089 $position = strspn($string, $space_characters);11090 $tokens = array();11091 11092 while ($position < $string_length)11093 {11094 $len = strcspn($string, $space_characters, $position);11095 $tokens[] = substr($string, $position, $len);11096 $position += $len;11097 $position += strspn($string, $space_characters, $position);11098 }11099 11100 return $tokens;11101 }11102 11103 function array_unique($array)11104 {11105 if (version_compare(PHP_VERSION, '5.2', '>='))11106 {11107 return array_unique($array);11108 }11109 else11110 {11111 $array = (array) $array;11112 $new_array = array();11113 $new_array_strings = array();11114 foreach ($array as $key => $value)11115 {11116 if (is_object($value))11117 {11118 if (method_exists($value, '__toString'))11119 {11120 $cmp = $value->__toString();11121 }11122 else11123 {11124 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);11125 }11126 }11127 elseif (is_array($value))11128 {11129 $cmp = (string) reset($value);11130 }11131 else11132 {11133 $cmp = (string) $value;11134 }11135 if (!in_array($cmp, $new_array_strings))11136 {11137 $new_array[$key] = $value;11138 $new_array_strings[] = $cmp;11139 }11140 }11141 return $new_array;11142 }11143 }11144 11145 /**11146 * Converts a unicode codepoint to a UTF-8 character11147 *11148 * @static11149 * @access public11150 * @param int $codepoint Unicode codepoint11151 * @return string UTF-8 character11152 */11153 function codepoint_to_utf8($codepoint)11154 {11155 $codepoint = (int) $codepoint;11156 if ($codepoint < 0)11157 {11158 return false;11159 }11160 else if ($codepoint <= 0x7f)11161 {11162 return chr($codepoint);11163 }11164 else if ($codepoint <= 0x7ff)11165 {11166 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));11167 }11168 else if ($codepoint <= 0xffff)11169 {11170 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));11171 }11172 else if ($codepoint <= 0x10ffff)11173 {11174 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));11175 }11176 else11177 {11178 // U+FFFD REPLACEMENT CHARACTER11179 return "\xEF\xBF\xBD";11180 }11181 }11182 11183 /**11184 * Re-implementation of PHP 5's stripos()11185 *11186 * Returns the numeric position of the first occurrence of needle in the11187 * haystack string.11188 *11189 * @static11190 * @access string11191 * @param object $haystack11192 * @param string $needle Note that the needle may be a string of one or more11193 * characters. If needle is not a string, it is converted to an integer11194 * and applied as the ordinal value of a character.11195 * @param int $offset The optional offset parameter allows you to specify which11196 * character in haystack to start searching. The position returned is still11197 * relative to the beginning of haystack.11198 * @return bool If needle is not found, stripos() will return boolean false.11199 */11200 function stripos($haystack, $needle, $offset = 0)11201 {11202 if (function_exists('stripos'))11203 {11204 return stripos($haystack, $needle, $offset);11205 }11206 else11207 {11208 if (is_string($needle))11209 {11210 $needle = strtolower($needle);11211 }11212 elseif (is_int($needle) || is_bool($needle) || is_double($needle))11213 {11214 $needle = strtolower(chr($needle));11215 }11216 else11217 {11218 trigger_error('needle is not a string or an integer', E_USER_WARNING);11219 return false;11220 }11221 11222 return strpos(strtolower($haystack), $needle, $offset);11223 }11224 }11225 11226 /**11227 * Similar to parse_str()11228 *11229 * Returns an associative array of name/value pairs, where the value is an11230 * array of values that have used the same name11231 *11232 * @static11233 * @access string11234 * @param string $str The input string.11235 * @return array11236 */11237 function parse_str($str)11238 {11239 $return = array();11240 $str = explode('&', $str);11241 11242 foreach ($str as $section)11243 {11244 if (strpos($section, '=') !== false)11245 {11246 list($name, $value) = explode('=', $section, 2);11247 $return[urldecode($name)][] = urldecode($value);11248 }11249 else11250 {11251 $return[urldecode($section)][] = null;11252 }11253 }11254 11255 return $return;11256 }11257 11258 /**11259 * Detect XML encoding, as per XML 1.0 Appendix F.111260 *11261 * @todo Add support for EBCDIC11262 * @param string $data XML data11263 * @return array Possible encodings11264 */11265 function xml_encoding($data)11266 {11267 // UTF-32 Big Endian BOM11268 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")11269 {11270 $encoding[] = 'UTF-32BE';11271 }11272 // UTF-32 Little Endian BOM11273 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")11274 {11275 $encoding[] = 'UTF-32LE';11276 }11277 // UTF-16 Big Endian BOM11278 elseif (substr($data, 0, 2) === "\xFE\xFF")11279 {11280 $encoding[] = 'UTF-16BE';11281 }11282 // UTF-16 Little Endian BOM11283 elseif (substr($data, 0, 2) === "\xFF\xFE")11284 {11285 $encoding[] = 'UTF-16LE';11286 }11287 // UTF-8 BOM11288 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")11289 {11290 $encoding[] = 'UTF-8';11291 }11292 // UTF-32 Big Endian Without BOM11293 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")11294 {11295 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))11296 {11297 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));11298 if ($parser->parse())11299 {11300 $encoding[] = $parser->encoding;11301 }11302 }11303 $encoding[] = 'UTF-32BE';11304 }11305 // UTF-32 Little Endian Without BOM11306 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")11307 {11308 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))11309 {11310 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));11311 if ($parser->parse())11312 {11313 $encoding[] = $parser->encoding;11314 }11315 }11316 $encoding[] = 'UTF-32LE';11317 }11318 // UTF-16 Big Endian Without BOM11319 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")11320 {11321 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))11322 {11323 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));11324 if ($parser->parse())11325 {11326 $encoding[] = $parser->encoding;11327 }11328 }11329 $encoding[] = 'UTF-16BE';11330 }11331 // UTF-16 Little Endian Without BOM11332 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")11333 {11334 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))11335 {11336 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));11337 if ($parser->parse())11338 {11339 $encoding[] = $parser->encoding;11340 }11341 }11342 $encoding[] = 'UTF-16LE';11343 }11344 // US-ASCII (or superset)11345 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")11346 {11347 if ($pos = strpos($data, "\x3F\x3E"))11348 {11349 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));11350 if ($parser->parse())11351 {11352 $encoding[] = $parser->encoding;11353 }11354 }11355 $encoding[] = 'UTF-8';11356 }11357 // Fallback to UTF-811358 else11359 {11360 $encoding[] = 'UTF-8';11361 }11362 return $encoding;11363 }11364 11365 function output_javascript()11366 {11367 if (function_exists('ob_gzhandler'))11368 {11369 ob_start('ob_gzhandler');11370 }11371 header('Content-type: text/javascript; charset: UTF-8');11372 header('Cache-Control: must-revalidate');11373 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days11374 ?>11375 function embed_odeo(link) {11376 document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');11377 }11378 11379 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {11380 if (placeholder != '') {11381 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');11382 }11383 else {11384 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');11385 }11386 }11387 11388 function embed_flash(bgcolor, width, height, link, loop, type) {11389 document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');11390 }11391 11392 function embed_flv(width, height, link, placeholder, loop, player) {11393 document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');11394 }11395 11396 function embed_wmedia(width, height, link) {11397 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');11398 }11399 <?php11400 }11401 11402 11403 11404 /**11405 * Format debugging information11406 */11407 function debug($sp)11408 {11409 $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";11410 $info .= 'PHP ' . PHP_VERSION . "\n";11411 if ($sp->error() !== null)11412 {11413 $info .= 'Error occurred: ' . $sp->error() . "\n";11414 }11415 else11416 {11417 $info .= "No error found.\n";11418 }11419 $info .= "Extensions:\n";11420 $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');11421 foreach ($extensions as $ext)11422 {11423 if (extension_loaded($ext))11424 {11425 $info .= " $ext loaded\n";11426 switch ($ext)11427 {11428 case 'pcre':11429 $info .= ' Version ' . PCRE_VERSION . "\n";11430 break;11431 case 'curl':11432 $version = curl_version();11433 $info .= ' Version ' . $version['version'] . "\n";11434 break;11435 case 'mbstring':11436 $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";11437 break;11438 case 'iconv':11439 $info .= ' Version ' . ICONV_VERSION . "\n";11440 break;11441 case 'xml':11442 $info .= ' Version ' . LIBXML_DOTTED_VERSION . "\n";11443 break;11444 }11445 }11446 else11447 {11448 $info .= " $ext not loaded\n";11449 }11450 }11451 return $info;11452 }11453 }11454 11455 /**11456 * Decode HTML Entities11457 *11458 * This implements HTML5 as of revision 967 (2007-06-28)11459 *11460 * @package SimplePie11461 */11462 class SimplePie_Decode_HTML_Entities11463 {11464 /**11465 * Data to be parsed11466 *11467 * @access private11468 * @var string11469 */11470 var $data = '';11471 11472 /**11473 * Currently consumed bytes11474 *11475 * @access private11476 * @var string11477 */11478 var $consumed = '';11479 11480 /**11481 * Position of the current byte being parsed11482 *11483 * @access private11484 * @var int11485 */11486 var $position = 0;11487 11488 /**11489 * Create an instance of the class with the input data11490 *11491 * @access public11492 * @param string $data Input data11493 */11494 function SimplePie_Decode_HTML_Entities($data)11495 {11496 $this->data = $data;11497 }11498 11499 /**11500 * Parse the input data11501 *11502 * @access public11503 * @return string Output data11504 */11505 function parse()11506 {11507 while (($this->position = strpos($this->data, '&', $this->position)) !== false)11508 {11509 $this->consume();11510 $this->entity();11511 $this->consumed = '';11512 }11513 return $this->data;11514 }11515 11516 /**11517 * Consume the next byte11518 *11519 * @access private11520 * @return mixed The next byte, or false, if there is no more data11521 */11522 function consume()11523 {11524 if (isset($this->data[$this->position]))11525 {11526 $this->consumed .= $this->data[$this->position];11527 return $this->data[$this->position++];11528 }11529 else11530 {11531 return false;11532 }11533 }11534 11535 /**11536 * Consume a range of characters11537 *11538 * @access private11539 * @param string $chars Characters to consume11540 * @return mixed A series of characters that match the range, or false11541 */11542 function consume_range($chars)11543 {11544 if ($len = strspn($this->data, $chars, $this->position))11545 {11546 $data = substr($this->data, $this->position, $len);11547 $this->consumed .= $data;11548 $this->position += $len;11549 return $data;11550 }11551 else11552 {11553 return false;11554 }11555 }11556 11557 /**11558 * Unconsume one byte11559 *11560 * @access private11561 */11562 function unconsume()11563 {11564 $this->consumed = substr($this->consumed, 0, -1);11565 $this->position--;11566 }11567 11568 /**11569 * Decode an entity11570 *11571 * @access private11572 */11573 function entity()11574 {11575 switch ($this->consume())11576 {11577 case "\x09":11578 case "\x0A":11579 case "\x0B":11580 case "\x0B":11581 case "\x0C":11582 case "\x20":11583 case "\x3C":11584 case "\x26":11585 case false:11586 break;11587 11588 case "\x23":11589 switch ($this->consume())11590 {11591 case "\x78":11592 case "\x58":11593 $range = '0123456789ABCDEFabcdef';11594 $hex = true;11595 break;11596 11597 default:11598 $range = '0123456789';11599 $hex = false;11600 $this->unconsume();11601 break;11602 }11603 11604 if ($codepoint = $this->consume_range($range))11605 {11606 static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");11607 11608 if ($hex)11609 {11610 $codepoint = hexdec($codepoint);11611 }11612 else11613 {11614 $codepoint = intval($codepoint);11615 }11616 11617 if (isset($windows_1252_specials[$codepoint]))11618 {11619 $replacement = $windows_1252_specials[$codepoint];11620 }11621 else11622 {11623 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);11624 }11625 11626 if (!in_array($this->consume(), array(';', false), true))11627 {11628 $this->unconsume();11629 }11630 11631 $consumed_length = strlen($this->consumed);11632 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);11633 $this->position += strlen($replacement) - $consumed_length;11634 }11635 break;11636 11637 default:11638 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");11639 11640 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)11641 {11642 $consumed = substr($this->consumed, 1);11643 if (isset($entities[$consumed]))11644 {11645 $match = $consumed;11646 }11647 }11648 11649 if ($match !== null)11650 {11651 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);11652 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;11653 }11654 break;11655 }11656 }11657 }11658 11659 /**11660 * IRI parser/serialiser11661 *11662 * @package SimplePie11663 */11664 class SimplePie_IRI11665 {11666 /**11667 * Scheme11668 *11669 * @access private11670 * @var string11671 */11672 var $scheme;11673 11674 /**11675 * User Information11676 *11677 * @access private11678 * @var string11679 */11680 var $userinfo;11681 11682 /**11683 * Host11684 *11685 * @access private11686 * @var string11687 */11688 var $host;11689 11690 /**11691 * Port11692 *11693 * @access private11694 * @var string11695 */11696 var $port;11697 11698 /**11699 * Path11700 *11701 * @access private11702 * @var string11703 */11704 var $path;11705 11706 /**11707 * Query11708 *11709 * @access private11710 * @var string11711 */11712 var $query;11713 11714 /**11715 * Fragment11716 *11717 * @access private11718 * @var string11719 */11720 var $fragment;11721 11722 /**11723 * Whether the object represents a valid IRI11724 *11725 * @access private11726 * @var array11727 */11728 var $valid = array();11729 11730 /**11731 * Return the entire IRI when you try and read the object as a string11732 *11733 * @access public11734 * @return string11735 */11736 function __toString()11737 {11738 return $this->get_iri();11739 }11740 11741 /**11742 * Create a new IRI object, from a specified string11743 *11744 * @access public11745 * @param string $iri11746 * @return SimplePie_IRI11747 */11748 function SimplePie_IRI($iri)11749 {11750 $iri = (string) $iri;11751 if ($iri !== '')11752 {11753 $parsed = $this->parse_iri($iri);11754 $this->set_scheme($parsed['scheme']);11755 $this->set_authority($parsed['authority']);11756 $this->set_path($parsed['path']);11757 $this->set_query($parsed['query']);11758 $this->set_fragment($parsed['fragment']);11759 }11760 }11761 11762 /**11763 * Create a new IRI object by resolving a relative IRI11764 *11765 * @static11766 * @access public11767 * @param SimplePie_IRI $base Base IRI11768 * @param string $relative Relative IRI11769 * @return SimplePie_IRI11770 */11771 function absolutize($base, $relative)11772 {11773 $relative = (string) $relative;11774 if ($relative !== '')11775 {11776 $relative =& new SimplePie_IRI($relative);11777 if ($relative->get_scheme() !== null)11778 {11779 $target = $relative;11780 }11781 elseif ($base->get_iri() !== null)11782 {11783 if ($relative->get_authority() !== null)11784 {11785 $target = $relative;11786 $target->set_scheme($base->get_scheme());11787 }11788 else11789 {11790 $target =& new SimplePie_IRI('');11791 $target->set_scheme($base->get_scheme());11792 $target->set_userinfo($base->get_userinfo());11793 $target->set_host($base->get_host());11794 $target->set_port($base->get_port());11795 if ($relative->get_path() !== null)11796 {11797 if (strpos($relative->get_path(), '/') === 0)11798 {11799 $target->set_path($relative->get_path());11800 }11801 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)11802 {11803 $target->set_path('/' . $relative->get_path());11804 }11805 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)11806 {11807 $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());11808 }11809 else11810 {11811 $target->set_path($relative->get_path());11812 }11813 $target->set_query($relative->get_query());11814 }11815 else11816 {11817 $target->set_path($base->get_path());11818 if ($relative->get_query() !== null)11819 {11820 $target->set_query($relative->get_query());11821 }11822 elseif ($base->get_query() !== null)11823 {11824 $target->set_query($base->get_query());11825 }11826 }11827 }11828 $target->set_fragment($relative->get_fragment());11829 }11830 else11831 {11832 // No base URL, just return the relative URL11833 $target = $relative;11834 }11835 }11836 else11837 {11838 $target = $base;11839 }11840 return $target;11841 }11842 11843 /**11844 * Parse an IRI into scheme/authority/path/query/fragment segments11845 *11846 * @access private11847 * @param string $iri11848 * @return array11849 */11850 function parse_iri($iri)11851 {11852 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);11853 for ($i = count($match); $i <= 9; $i++)11854 {11855 $match[$i] = '';11856 }11857 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);11858 }11859 11860 /**11861 * Remove dot segments from a path11862 *11863 * @access private11864 * @param string $input11865 * @return string11866 */11867 function remove_dot_segments($input)11868 {11869 $output = '';11870 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')11871 {11872 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,11873 if (strpos($input, '../') === 0)11874 {11875 $input = substr($input, 3);11876 }11877 elseif (strpos($input, './') === 0)11878 {11879 $input = substr($input, 2);11880 }11881 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,11882 elseif (strpos($input, '/./') === 0)11883 {11884 $input = substr_replace($input, '/', 0, 3);11885 }11886 elseif ($input === '/.')11887 {11888 $input = '/';11889 }11890 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,11891 elseif (strpos($input, '/../') === 0)11892 {11893 $input = substr_replace($input, '/', 0, 4);11894 $output = substr_replace($output, '', strrpos($output, '/'));11895 }11896 elseif ($input === '/..')11897 {11898 $input = '/';11899 $output = substr_replace($output, '', strrpos($output, '/'));11900 }11901 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,11902 elseif ($input === '.' || $input === '..')11903 {11904 $input = '';11905 }11906 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer11907 elseif (($pos = strpos($input, '/', 1)) !== false)11908 {11909 $output .= substr($input, 0, $pos);11910 $input = substr_replace($input, '', 0, $pos);11911 }11912 else11913 {11914 $output .= $input;11915 $input = '';11916 }11917 }11918 return $output . $input;11919 }11920 11921 /**11922 * Replace invalid character with percent encoding11923 *11924 * @param string $string Input string11925 * @param string $valid_chars Valid characters11926 * @param int $case Normalise case11927 * @return string11928 */11929 function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)11930 {11931 // Normalize as many pct-encoded sections as possible11932 $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);11933 11934 // Replace invalid percent characters11935 $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);11936 11937 // Add unreserved and % to $valid_chars (the latter is safe because all11938 // pct-encoded sections are now valid).11939 $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';11940 11941 // Now replace any bytes that aren't allowed with their pct-encoded versions11942 $position = 0;11943 $strlen = strlen($string);11944 while (($position += strspn($string, $valid_chars, $position)) < $strlen)11945 {11946 $value = ord($string[$position]);11947 11948 // Start position11949 $start = $position;11950 11951 // By default we are valid11952 $valid = true;11953 11954 // No one byte sequences are valid due to the while.11955 // Two byte sequence:11956 if (($value & 0xE0) === 0xC0)11957 {11958 $character = ($value & 0x1F) << 6;11959 $length = 2;11960 $remaining = 1;11961 }11962 // Three byte sequence:11963 elseif (($value & 0xF0) === 0xE0)11964 {11965 $character = ($value & 0x0F) << 12;11966 $length = 3;11967 $remaining = 2;11968 }11969 // Four byte sequence:11970 elseif (($value & 0xF8) === 0xF0)11971 {11972 $character = ($value & 0x07) << 18;11973 $length = 4;11974 $remaining = 3;11975 }11976 // Invalid byte:11977 else11978 {11979 $valid = false;11980 $length = 1;11981 $remaining = 0;11982 }11983 11984 if ($remaining)11985 {11986 if ($position + $length <= $strlen)11987 {11988 for ($position++; $remaining; $position++)11989 {11990 $value = ord($string[$position]);11991 11992 // Check that the byte is valid, then add it to the character:11993 if (($value & 0xC0) === 0x80)11994 {11995 $character |= ($value & 0x3F) << (--$remaining * 6);11996 }11997 // If it is invalid, count the sequence as invalid and reprocess the current byte:11998 else11999 {12000 $valid = false;12001 $position--;12002 break;12003 }12004 }12005 }12006 else12007 {12008 $position = $strlen - 1;12009 $valid = false;12010 }12011 }12012 12013 // Percent encode anything invalid or not in ucschar12014 if (12015 // Invalid sequences12016 !$valid12017 // Non-shortest form sequences are invalid12018 || $length > 1 && $character <= 0x7F12019 || $length > 2 && $character <= 0x7FF12020 || $length > 3 && $character <= 0xFFFF12021 // Outside of range of ucschar codepoints12022 // Noncharacters12023 || ($character & 0xFFFE) === 0xFFFE12024 || $character >= 0xFDD0 && $character <= 0xFDEF12025 || (12026 // Everything else not in ucschar12027 $character > 0xD7FF && $character < 0xF90012028 || $character < 0xA012029 || $character > 0xEFFFD12030 )12031 && (12032 // Everything not in iprivate, if it applies12033 !$iprivate12034 || $character < 0xE00012035 || $character > 0x10FFFD12036 )12037 )12038 {12039 // If we were a character, pretend we weren't, but rather an error.12040 if ($valid)12041 $position--;12042 12043 for ($j = $start; $j <= $position; $j++)12044 {12045 $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);12046 $j += 2;12047 $position += 2;12048 $strlen += 2;12049 }12050 }12051 }12052 12053 // Normalise case12054 if ($case & SIMPLEPIE_LOWERCASE)12055 {12056 $string = strtolower($string);12057 }12058 elseif ($case & SIMPLEPIE_UPPERCASE)12059 {12060 $string = strtoupper($string);12061 }12062 12063 return $string;12064 }12065 12066 /**12067 * Callback function for preg_replace_callback.12068 *12069 * Removes sequences of percent encoded bytes that represent UTF-812070 * encoded characters in iunreserved12071 *12072 * @access private12073 * @param array $match PCRE match12074 * @return string Replacement12075 */12076 function remove_iunreserved_percent_encoded($match)12077 {12078 // As we just have valid percent encoded sequences we can just explode12079 // and ignore the first member of the returned array (an empty string).12080 $bytes = explode('%', $match[0]);12081 12082 // Initialize the new string (this is what will be returned) and that12083 // there are no bytes remaining in the current sequence (unsurprising12084 // at the first byte!).12085 $string = '';12086 $remaining = 0;12087 12088 // Loop over each and every byte, and set $value to its value12089 for ($i = 1, $len = count($bytes); $i < $len; $i++)12090 {12091 $value = hexdec($bytes[$i]);12092 12093 // If we're the first byte of sequence:12094 if (!$remaining)12095 {12096 // Start position12097 $start = $i;12098 12099 // By default we are valid12100 $valid = true;12101 12102 // One byte sequence:12103 if ($value <= 0x7F)12104 {12105 $character = $value;12106 $length = 1;12107 }12108 // Two byte sequence:12109 elseif (($value & 0xE0) === 0xC0)12110 {12111 $character = ($value & 0x1F) << 6;12112 $length = 2;12113 $remaining = 1;12114 }12115 // Three byte sequence:12116 elseif (($value & 0xF0) === 0xE0)12117 {12118 $character = ($value & 0x0F) << 12;12119 $length = 3;12120 $remaining = 2;12121 }12122 // Four byte sequence:12123 elseif (($value & 0xF8) === 0xF0)12124 {12125 $character = ($value & 0x07) << 18;12126 $length = 4;12127 $remaining = 3;12128 }12129 // Invalid byte:12130 else12131 {12132 $valid = false;12133 $remaining = 0;12134 }12135 }12136 // Continuation byte:12137 else12138 {12139 // Check that the byte is valid, then add it to the character:12140 if (($value & 0xC0) === 0x80)12141 {12142 $remaining--;12143 $character |= ($value & 0x3F) << ($remaining * 6);12144 }12145 // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:12146 else12147 {12148 $valid = false;12149 $remaining = 0;12150 $i--;12151 }12152 }12153 12154 // If we've reached the end of the current byte sequence, append it to Unicode::$data12155 if (!$remaining)12156 {12157 // Percent encode anything invalid or not in iunreserved12158 if (12159 // Invalid sequences12160 !$valid12161 // Non-shortest form sequences are invalid12162 || $length > 1 && $character <= 0x7F12163 || $length > 2 && $character <= 0x7FF12164 || $length > 3 && $character <= 0xFFFF12165 // Outside of range of iunreserved codepoints12166 || $character < 0x2D12167 || $character > 0xEFFFD12168 // Noncharacters12169 || ($character & 0xFFFE) === 0xFFFE12170 || $character >= 0xFDD0 && $character <= 0xFDEF12171 // Everything else not in iunreserved (this is all BMP)12172 || $character === 0x2F12173 || $character > 0x39 && $character < 0x4112174 || $character > 0x5A && $character < 0x6112175 || $character > 0x7A && $character < 0x7E12176 || $character > 0x7E && $character < 0xA012177 || $character > 0xD7FF && $character < 0xF90012178 )12179 {12180 for ($j = $start; $j <= $i; $j++)12181 {12182 $string .= '%' . strtoupper($bytes[$j]);12183 }12184 }12185 else12186 {12187 for ($j = $start; $j <= $i; $j++)12188 {12189 $string .= chr(hexdec($bytes[$j]));12190 }12191 }12192 }12193 }12194 12195 // If we have any bytes left over they are invalid (i.e., we are12196 // mid-way through a multi-byte sequence)12197 if ($remaining)12198 {12199 for ($j = $start; $j < $len; $j++)12200 {12201 $string .= '%' . strtoupper($bytes[$j]);12202 }12203 }12204 12205 return $string;12206 }12207 12208 /**12209 * Check if the object represents a valid IRI12210 *12211 * @access public12212 * @return bool12213 */12214 function is_valid()12215 {12216 return array_sum($this->valid) === count($this->valid);12217 }12218 12219 /**12220 * Set the scheme. Returns true on success, false on failure (if there are12221 * any invalid characters).12222 *12223 * @access public12224 * @param string $scheme12225 * @return bool12226 */12227 function set_scheme($scheme)12228 {12229 if ($scheme === null || $scheme === '')12230 {12231 $this->scheme = null;12232 }12233 else12234 {12235 $len = strlen($scheme);12236 switch (true)12237 {12238 case $len > 1:12239 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))12240 {12241 $this->scheme = null;12242 $this->valid[__FUNCTION__] = false;12243 return false;12244 }12245 12246 case $len > 0:12247 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))12248 {12249 $this->scheme = null;12250 $this->valid[__FUNCTION__] = false;12251 return false;12252 }12253 }12254 $this->scheme = strtolower($scheme);12255 }12256 $this->valid[__FUNCTION__] = true;12257 return true;12258 }12259 12260 /**12261 * Set the authority. Returns true on success, false on failure (if there are12262 * any invalid characters).12263 *12264 * @access public12265 * @param string $authority12266 * @return bool12267 */12268 function set_authority($authority)12269 {12270 if (($userinfo_end = strrpos($authority, '@')) !== false)12271 {12272 $userinfo = substr($authority, 0, $userinfo_end);12273 $authority = substr($authority, $userinfo_end + 1);12274 }12275 else12276 {12277 $userinfo = null;12278 }12279 12280 if (($port_start = strpos($authority, ':')) !== false)12281 {12282 $port = substr($authority, $port_start + 1);12283 $authority = substr($authority, 0, $port_start);12284 }12285 else12286 {12287 $port = null;12288 }12289 12290 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);12291 }12292 12293 /**12294 * Set the userinfo.12295 *12296 * @access public12297 * @param string $userinfo12298 * @return bool12299 */12300 function set_userinfo($userinfo)12301 {12302 if ($userinfo === null || $userinfo === '')12303 {12304 $this->userinfo = null;12305 }12306 else12307 {12308 $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');12309 }12310 $this->valid[__FUNCTION__] = true;12311 return true;12312 }12313 12314 /**12315 * Set the host. Returns true on success, false on failure (if there are12316 * any invalid characters).12317 *12318 * @access public12319 * @param string $host12320 * @return bool12321 */12322 function set_host($host)12323 {12324 if ($host === null || $host === '')12325 {12326 $this->host = null;12327 $this->valid[__FUNCTION__] = true;12328 return true;12329 }12330 elseif ($host[0] === '[' && substr($host, -1) === ']')12331 {12332 if (SimplePie_Net_IPv6::checkIPv6(substr($host, 1, -1)))12333 {12334 $this->host = $host;12335 $this->valid[__FUNCTION__] = true;12336 return true;12337 }12338 else12339 {12340 $this->host = null;12341 $this->valid[__FUNCTION__] = false;12342 return false;12343 }12344 }12345 else12346 {12347 $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);12348 $this->valid[__FUNCTION__] = true;12349 return true;12350 }12351 }12352 12353 /**12354 * Set the port. Returns true on success, false on failure (if there are12355 * any invalid characters).12356 *12357 * @access public12358 * @param string $port12359 * @return bool12360 */12361 function set_port($port)12362 {12363 if ($port === null || $port === '')12364 {12365 $this->port = null;12366 $this->valid[__FUNCTION__] = true;12367 return true;12368 }12369 elseif (strspn($port, '0123456789') === strlen($port))12370 {12371 $this->port = (int) $port;12372 $this->valid[__FUNCTION__] = true;12373 return true;12374 }12375 else12376 {12377 $this->port = null;12378 $this->valid[__FUNCTION__] = false;12379 return false;12380 }12381 }12382 12383 /**12384 * Set the path.12385 *12386 * @access public12387 * @param string $path12388 * @return bool12389 */12390 function set_path($path)12391 {12392 if ($path === null || $path === '')12393 {12394 $this->path = null;12395 $this->valid[__FUNCTION__] = true;12396 return true;12397 }12398 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)12399 {12400 $this->path = null;12401 $this->valid[__FUNCTION__] = false;12402 return false;12403 }12404 else12405 {12406 $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');12407 if ($this->scheme !== null)12408 {12409 $this->path = $this->remove_dot_segments($this->path);12410 }12411 $this->valid[__FUNCTION__] = true;12412 return true;12413 }12414 }12415 12416 /**12417 * Set the query.12418 *12419 * @access public12420 * @param string $query12421 * @return bool12422 */12423 function set_query($query)12424 {12425 if ($query === null || $query === '')12426 {12427 $this->query = null;12428 }12429 else12430 {12431 $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');12432 }12433 $this->valid[__FUNCTION__] = true;12434 return true;12435 }12436 12437 /**12438 * Set the fragment.12439 *12440 * @access public12441 * @param string $fragment12442 * @return bool12443 */12444 function set_fragment($fragment)12445 {12446 if ($fragment === null || $fragment === '')12447 {12448 $this->fragment = null;12449 }12450 else12451 {12452 $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');12453 }12454 $this->valid[__FUNCTION__] = true;12455 return true;12456 }12457 12458 /**12459 * Get the complete IRI12460 *12461 * @access public12462 * @return string12463 */12464 function get_iri()12465 {12466 $iri = '';12467 if ($this->scheme !== null)12468 {12469 $iri .= $this->scheme . ':';12470 }12471 if (($authority = $this->get_authority()) !== null)12472 {12473 $iri .= '//' . $authority;12474 }12475 if ($this->path !== null)12476 {12477 $iri .= $this->path;12478 }12479 if ($this->query !== null)12480 {12481 $iri .= '?' . $this->query;12482 }12483 if ($this->fragment !== null)12484 {12485 $iri .= '#' . $this->fragment;12486 }12487 12488 if ($iri !== '')12489 {12490 return $iri;12491 }12492 else12493 {12494 return null;12495 }12496 }12497 12498 /**12499 * Get the scheme12500 *12501 * @access public12502 * @return string12503 */12504 function get_scheme()12505 {12506 return $this->scheme;12507 }12508 12509 /**12510 * Get the complete authority12511 *12512 * @access public12513 * @return string12514 */12515 function get_authority()12516 {12517 $authority = '';12518 if ($this->userinfo !== null)12519 {12520 $authority .= $this->userinfo . '@';12521 }12522 if ($this->host !== null)12523 {12524 $authority .= $this->host;12525 }12526 if ($this->port !== null)12527 {12528 $authority .= ':' . $this->port;12529 }12530 12531 if ($authority !== '')12532 {12533 return $authority;12534 }12535 else12536 {12537 return null;12538 }12539 }12540 12541 /**12542 * Get the user information12543 *12544 * @access public12545 * @return string12546 */12547 function get_userinfo()12548 {12549 return $this->userinfo;12550 }12551 12552 /**12553 * Get the host12554 *12555 * @access public12556 * @return string12557 */12558 function get_host()12559 {12560 return $this->host;12561 }12562 12563 /**12564 * Get the port12565 *12566 * @access public12567 * @return string12568 */12569 function get_port()12570 {12571 return $this->port;12572 }12573 12574 /**12575 * Get the path12576 *12577 * @access public12578 * @return string12579 */12580 function get_path()12581 {12582 return $this->path;12583 }12584 12585 /**12586 * Get the query12587 *12588 * @access public12589 * @return string12590 */12591 function get_query()12592 {12593 return $this->query;12594 }12595 12596 /**12597 * Get the fragment12598 *12599 * @access public12600 * @return string12601 */12602 function get_fragment()12603 {12604 return $this->fragment;12605 }12606 }12607 12608 /**12609 * Class to validate and to work with IPv6 addresses.12610 *12611 * @package SimplePie12612 * @copyright 2003-2005 The PHP Group12613 * @license http://www.opensource.org/licenses/bsd-license.php12614 * @link http://pear.php.net/package/Net_IPv612615 * @author Alexander Merz <alexander.merz@web.de>12616 * @author elfrink at introweb dot nl12617 * @author Josh Peck <jmp at joshpeck dot org>12618 * @author Geoffrey Sneddon <geoffers@gmail.com>12619 */12620 class SimplePie_Net_IPv612621 {12622 /**12623 * Removes a possible existing netmask specification of an IP address.12624 *12625 * @param string $ip the (compressed) IP as Hex representation12626 * @return string the IP the without netmask12627 * @since 1.1.012628 * @access public12629 * @static12630 */12631 function removeNetmaskSpec($ip)12632 {12633 if (strpos($ip, '/') !== false)12634 {12635 list($addr, $nm) = explode('/', $ip);12636 }12637 else12638 {12639 $addr = $ip;12640 }12641 return $addr;12642 }12643 12644 /**12645 * Uncompresses an IPv6 address12646 *12647 * RFC 2373 allows you to compress zeros in an address to '::'. This12648 * function expects an valid IPv6 address and expands the '::' to12649 * the required zeros.12650 *12651 * Example: FF01::101 -> FF01:0:0:0:0:0:0:10112652 * ::1 -> 0:0:0:0:0:0:0:112653 *12654 * @access public12655 * @static12656 * @param string $ip a valid IPv6-address (hex format)12657 * @return string the uncompressed IPv6-address (hex format)12658 */12659 function Uncompress($ip)12660 {12661 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);12662 $c1 = -1;12663 $c2 = -1;12664 if (strpos($ip, '::') !== false)12665 {12666 list($ip1, $ip2) = explode('::', $ip);12667 if ($ip1 === '')12668 {12669 $c1 = -1;12670 }12671 else12672 {12673 $pos = 0;12674 if (($pos = substr_count($ip1, ':')) > 0)12675 {12676 $c1 = $pos;12677 }12678 else12679 {12680 $c1 = 0;12681 }12682 }12683 if ($ip2 === '')12684 {12685 $c2 = -1;12686 }12687 else12688 {12689 $pos = 0;12690 if (($pos = substr_count($ip2, ':')) > 0)12691 {12692 $c2 = $pos;12693 }12694 else12695 {12696 $c2 = 0;12697 }12698 }12699 if (strstr($ip2, '.'))12700 {12701 $c2++;12702 }12703 // ::12704 if ($c1 === -1 && $c2 === -1)12705 {12706 $uip = '0:0:0:0:0:0:0:0';12707 }12708 // ::xxx12709 else if ($c1 === -1)12710 {12711 $fill = str_repeat('0:', 7 - $c2);12712 $uip = str_replace('::', $fill, $uip);12713 }12714 // xxx::12715 else if ($c2 === -1)12716 {12717 $fill = str_repeat(':0', 7 - $c1);12718 $uip = str_replace('::', $fill, $uip);12719 }12720 // xxx::xxx12721 else12722 {12723 $fill = str_repeat(':0:', 6 - $c2 - $c1);12724 $uip = str_replace('::', $fill, $uip);12725 $uip = str_replace('::', ':', $uip);12726 }12727 }12728 return $uip;12729 }12730 12731 /**12732 * Splits an IPv6 address into the IPv6 and a possible IPv4 part12733 *12734 * RFC 2373 allows you to note the last two parts of an IPv6 address as12735 * an IPv4 compatible address12736 *12737 * Example: 0:0:0:0:0:0:13.1.68.312738 * 0:0:0:0:0:FFFF:129.144.52.3812739 *12740 * @access public12741 * @static12742 * @param string $ip a valid IPv6-address (hex format)12743 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)12744 */12745 function SplitV64($ip)12746 {12747 $ip = SimplePie_Net_IPv6::Uncompress($ip);12748 if (strstr($ip, '.'))12749 {12750 $pos = strrpos($ip, ':');12751 $ip[$pos] = '_';12752 $ipPart = explode('_', $ip);12753 return $ipPart;12754 }12755 else12756 {12757 return array($ip, '');12758 }12759 }12760 12761 /**12762 * Checks an IPv6 address12763 *12764 * Checks if the given IP is IPv6-compatible12765 *12766 * @access public12767 * @static12768 * @param string $ip a valid IPv6-address12769 * @return bool true if $ip is an IPv6 address12770 */12771 function checkIPv6($ip)12772 {12773 $ipPart = SimplePie_Net_IPv6::SplitV64($ip);12774 $count = 0;12775 if (!empty($ipPart[0]))12776 {12777 $ipv6 = explode(':', $ipPart[0]);12778 for ($i = 0; $i < count($ipv6); $i++)12779 {12780 $dec = hexdec($ipv6[$i]);12781 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));12782 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))12783 {12784 $count++;12785 }12786 }12787 if ($count === 8)12788 {12789 return true;12790 }12791 elseif ($count === 6 && !empty($ipPart[1]))12792 {12793 $ipv4 = explode('.', $ipPart[1]);12794 $count = 0;12795 foreach ($ipv4 as $ipv4_part)12796 {12797 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))12798 {12799 $count++;12800 }12801 }12802 if ($count === 4)12803 {12804 return true;12805 }12806 }12807 else12808 {12809 return false;12810 }12811 12812 }12813 else12814 {12815 return false;12816 }12817 }12818 }12819 12820 /**12821 * Date Parser12822 *12823 * @package SimplePie12824 */12825 class SimplePie_Parse_Date12826 {12827 /**12828 * Input data12829 *12830 * @access protected12831 * @var string12832 */12833 var $date;12834 12835 /**12836 * List of days, calendar day name => ordinal day number in the week12837 *12838 * @access protected12839 * @var array12840 */12841 var $day = array(12842 // English12843 'mon' => 1,12844 'monday' => 1,12845 'tue' => 2,12846 'tuesday' => 2,12847 'wed' => 3,12848 'wednesday' => 3,12849 'thu' => 4,12850 'thursday' => 4,12851 'fri' => 5,12852 'friday' => 5,12853 'sat' => 6,12854 'saturday' => 6,12855 'sun' => 7,12856 'sunday' => 7,12857 // Dutch12858 'maandag' => 1,12859 'dinsdag' => 2,12860 'woensdag' => 3,12861 'donderdag' => 4,12862 'vrijdag' => 5,12863 'zaterdag' => 6,12864 'zondag' => 7,12865 // French12866 'lundi' => 1,12867 'mardi' => 2,12868 'mercredi' => 3,12869 'jeudi' => 4,12870 'vendredi' => 5,12871 'samedi' => 6,12872 'dimanche' => 7,12873 // German12874 'montag' => 1,12875 'dienstag' => 2,12876 'mittwoch' => 3,12877 'donnerstag' => 4,12878 'freitag' => 5,12879 'samstag' => 6,12880 'sonnabend' => 6,12881 'sonntag' => 7,12882 // Italian12883 'lunedì' => 1,12884 'martedì' => 2,12885 'mercoledì' => 3,12886 'giovedì' => 4,12887 'venerdì' => 5,12888 'sabato' => 6,12889 'domenica' => 7,12890 // Spanish12891 'lunes' => 1,12892 'martes' => 2,12893 'miércoles' => 3,12894 'jueves' => 4,12895 'viernes' => 5,12896 'sábado' => 6,12897 'domingo' => 7,12898 // Finnish12899 'maanantai' => 1,12900 'tiistai' => 2,12901 'keskiviikko' => 3,12902 'torstai' => 4,12903 'perjantai' => 5,12904 'lauantai' => 6,12905 'sunnuntai' => 7,12906 // Hungarian12907 'hétfő' => 1,12908 'kedd' => 2,12909 'szerda' => 3,12910 'csütörtok' => 4,12911 'péntek' => 5,12912 'szombat' => 6,12913 'vasárnap' => 7,12914 // Greek12915 'Δευ' => 1,12916 'Τρι' => 2,12917 'Τετ' => 3,12918 'Πεμ' => 4,12919 'Παρ' => 5,12920 'Σαβ' => 6,12921 'Κυρ' => 7,12922 );12923 12924 /**12925 * List of months, calendar month name => calendar month number12926 *12927 * @access protected12928 * @var array12929 */12930 var $month = array(12931 // English12932 'jan' => 1,12933 'january' => 1,12934 'feb' => 2,12935 'february' => 2,12936 'mar' => 3,12937 'march' => 3,12938 'apr' => 4,12939 'april' => 4,12940 'may' => 5,12941 // No long form of May12942 'jun' => 6,12943 'june' => 6,12944 'jul' => 7,12945 'july' => 7,12946 'aug' => 8,12947 'august' => 8,12948 'sep' => 9,12949 'september' => 8,12950 'oct' => 10,12951 'october' => 10,12952 'nov' => 11,12953 'november' => 11,12954 'dec' => 12,12955 'december' => 12,12956 // Dutch12957 'januari' => 1,12958 'februari' => 2,12959 'maart' => 3,12960 'april' => 4,12961 'mei' => 5,12962 'juni' => 6,12963 'juli' => 7,12964 'augustus' => 8,12965 'september' => 9,12966 'oktober' => 10,12967 'november' => 11,12968 'december' => 12,12969 // French12970 'janvier' => 1,12971 'février' => 2,12972 'mars' => 3,12973 'avril' => 4,12974 'mai' => 5,12975 'juin' => 6,12976 'juillet' => 7,12977 'août' => 8,12978 'septembre' => 9,12979 'octobre' => 10,12980 'novembre' => 11,12981 'décembre' => 12,12982 // German12983 'januar' => 1,12984 'februar' => 2,12985 'märz' => 3,12986 'april' => 4,12987 'mai' => 5,12988 'juni' => 6,12989 'juli' => 7,12990 'august' => 8,12991 'september' => 9,12992 'oktober' => 10,12993 'november' => 11,12994 'dezember' => 12,12995 // Italian12996 'gennaio' => 1,12997 'febbraio' => 2,12998 'marzo' => 3,12999 'aprile' => 4,13000 'maggio' => 5,13001 'giugno' => 6,13002 'luglio' => 7,13003 'agosto' => 8,13004 'settembre' => 9,13005 'ottobre' => 10,13006 'novembre' => 11,13007 'dicembre' => 12,13008 // Spanish13009 'enero' => 1,13010 'febrero' => 2,13011 'marzo' => 3,13012 'abril' => 4,13013 'mayo' => 5,13014 'junio' => 6,13015 'julio' => 7,13016 'agosto' => 8,13017 'septiembre' => 9,13018 'setiembre' => 9,13019 'octubre' => 10,13020 'noviembre' => 11,13021 'diciembre' => 12,13022 // Finnish13023 'tammikuu' => 1,13024 'helmikuu' => 2,13025 'maaliskuu' => 3,13026 'huhtikuu' => 4,13027 'toukokuu' => 5,13028 'kesäkuu' => 6,13029 'heinäkuu' => 7,13030 'elokuu' => 8,13031 'suuskuu' => 9,13032 'lokakuu' => 10,13033 'marras' => 11,13034 'joulukuu' => 12,13035 // Hungarian13036 'január' => 1,13037 'február' => 2,13038 'március' => 3,13039 'április' => 4,13040 'május' => 5,13041 'június' => 6,13042 'július' => 7,13043 'augusztus' => 8,13044 'szeptember' => 9,13045 'október' => 10,13046 'november' => 11,13047 'december' => 12,13048 // Greek13049 'Ιαν' => 1,13050 'Φεβ' => 2,13051 'Μάώ' => 3,13052 'Μαώ' => 3,13053 'Απρ' => 4,13054 'Μάι' => 5,13055 'Μαϊ' => 5,13056 'Μαι' => 5,13057 'Ιούν' => 6,13058 'Ιον' => 6,13059 'Ιούλ' => 7,13060 'Ιολ' => 7,13061 'Αύγ' => 8,13062 'Αυγ' => 8,13063 'Σεπ' => 9,13064 'Οκτ' => 10,13065 'Νοέ' => 11,13066 'Δεκ' => 12,13067 );13068 13069 /**13070 * List of timezones, abbreviation => offset from UTC13071 *13072 * @access protected13073 * @var array13074 */13075 var $timezone = array(13076 'ACDT' => 37800,13077 'ACIT' => 28800,13078 'ACST' => 34200,13079 'ACT' => -18000,13080 'ACWDT' => 35100,13081 'ACWST' => 31500,13082 'AEDT' => 39600,13083 'AEST' => 36000,13084 'AFT' => 16200,13085 'AKDT' => -28800,13086 'AKST' => -32400,13087 'AMDT' => 18000,13088 'AMT' => -14400,13089 'ANAST' => 46800,13090 'ANAT' => 43200,13091 'ART' => -10800,13092 'AZOST' => -3600,13093 'AZST' => 18000,13094 'AZT' => 14400,13095 'BIOT' => 21600,13096 'BIT' => -43200,13097 'BOT' => -14400,13098 'BRST' => -7200,13099 'BRT' => -10800,13100 'BST' => 3600,13101 'BTT' => 21600,13102 'CAST' => 18000,13103 'CAT' => 7200,13104 'CCT' => 23400,13105 'CDT' => -18000,13106 'CEDT' => 7200,13107 'CET' => 3600,13108 'CGST' => -7200,13109 'CGT' => -10800,13110 'CHADT' => 49500,13111 'CHAST' => 45900,13112 'CIST' => -28800,13113 'CKT' => -36000,13114 'CLDT' => -10800,13115 'CLST' => -14400,13116 'COT' => -18000,13117 'CST' => -21600,13118 'CVT' => -3600,13119 'CXT' => 25200,13120 'DAVT' => 25200,13121 'DTAT' => 36000,13122 'EADT' => -18000,13123 'EAST' => -21600,13124 'EAT' => 10800,13125 'ECT' => -18000,13126 'EDT' => -14400,13127 'EEST' => 10800,13128 'EET' => 7200,13129 'EGT' => -3600,13130 'EKST' => 21600,13131 'EST' => -18000,13132 'FJT' => 43200,13133 'FKDT' => -10800,13134 'FKST' => -14400,13135 'FNT' => -7200,13136 'GALT' => -21600,13137 'GEDT' => 14400,13138 'GEST' => 10800,13139 'GFT' => -10800,13140 'GILT' => 43200,13141 'GIT' => -32400,13142 'GST' => 14400,13143 'GST' => -7200,13144 'GYT' => -14400,13145 'HAA' => -10800,13146 'HAC' => -18000,13147 'HADT' => -32400,13148 'HAE' => -14400,13149 'HAP' => -25200,13150 'HAR' => -21600,13151 'HAST' => -36000,13152 'HAT' => -9000,13153 'HAY' => -28800,13154 'HKST' => 28800,13155 'HMT' => 18000,13156 'HNA' => -14400,13157 'HNC' => -21600,13158 'HNE' => -18000,13159 'HNP' => -28800,13160 'HNR' => -25200,13161 'HNT' => -12600,13162 'HNY' => -32400,13163 'IRDT' => 16200,13164 'IRKST' => 32400,13165 'IRKT' => 28800,13166 'IRST' => 12600,13167 'JFDT' => -10800,13168 'JFST' => -14400,13169 'JST' => 32400,13170 'KGST' => 21600,13171 'KGT' => 18000,13172 'KOST' => 39600,13173 'KOVST' => 28800,13174 'KOVT' => 25200,13175 'KRAST' => 28800,13176 'KRAT' => 25200,13177 'KST' => 32400,13178 'LHDT' => 39600,13179 'LHST' => 37800,13180 'LINT' => 50400,13181 'LKT' => 21600,13182 'MAGST' => 43200,13183 'MAGT' => 39600,13184 'MAWT' => 21600,13185 'MDT' => -21600,13186 'MESZ' => 7200,13187 'MEZ' => 3600,13188 'MHT' => 43200,13189 'MIT' => -34200,13190 'MNST' => 32400,13191 'MSDT' => 14400,13192 'MSST' => 10800,13193 'MST' => -25200,13194 'MUT' => 14400,13195 'MVT' => 18000,13196 'MYT' => 28800,13197 'NCT' => 39600,13198 'NDT' => -9000,13199 'NFT' => 41400,13200 'NMIT' => 36000,13201 'NOVST' => 25200,13202 'NOVT' => 21600,13203 'NPT' => 20700,13204 'NRT' => 43200,13205 'NST' => -12600,13206 'NUT' => -39600,13207 'NZDT' => 46800,13208 'NZST' => 43200,13209 'OMSST' => 25200,13210 'OMST' => 21600,13211 'PDT' => -25200,13212 'PET' => -18000,13213 'PETST' => 46800,13214 'PETT' => 43200,13215 'PGT' => 36000,13216 'PHOT' => 46800,13217 'PHT' => 28800,13218 'PKT' => 18000,13219 'PMDT' => -7200,13220 'PMST' => -10800,13221 'PONT' => 39600,13222 'PST' => -28800,13223 'PWT' => 32400,13224 'PYST' => -10800,13225 'PYT' => -14400,13226 'RET' => 14400,13227 'ROTT' => -10800,13228 'SAMST' => 18000,13229 'SAMT' => 14400,13230 'SAST' => 7200,13231 'SBT' => 39600,13232 'SCDT' => 46800,13233 'SCST' => 43200,13234 'SCT' => 14400,13235 'SEST' => 3600,13236 'SGT' => 28800,13237 'SIT' => 28800,13238 'SRT' => -10800,13239 'SST' => -39600,13240 'SYST' => 10800,13241 'SYT' => 7200,13242 'TFT' => 18000,13243 'THAT' => -36000,13244 'TJT' => 18000,13245 'TKT' => -36000,13246 'TMT' => 18000,13247 'TOT' => 46800,13248 'TPT' => 32400,13249 'TRUT' => 36000,13250 'TVT' => 43200,13251 'TWT' => 28800,13252 'UYST' => -7200,13253 'UYT' => -10800,13254 'UZT' => 18000,13255 'VET' => -14400,13256 'VLAST' => 39600,13257 'VLAT' => 36000,13258 'VOST' => 21600,13259 'VUT' => 39600,13260 'WAST' => 7200,13261 'WAT' => 3600,13262 'WDT' => 32400,13263 'WEST' => 3600,13264 'WFT' => 43200,13265 'WIB' => 25200,13266 'WIT' => 32400,13267 'WITA' => 28800,13268 'WKST' => 18000,13269 'WST' => 28800,13270 'YAKST' => 36000,13271 'YAKT' => 32400,13272 'YAPT' => 36000,13273 'YEKST' => 21600,13274 'YEKT' => 18000,13275 );13276 13277 /**13278 * Cached PCRE for SimplePie_Parse_Date::$day13279 *13280 * @access protected13281 * @var string13282 */13283 var $day_pcre;13284 13285 /**13286 * Cached PCRE for SimplePie_Parse_Date::$month13287 *13288 * @access protected13289 * @var string13290 */13291 var $month_pcre;13292 13293 /**13294 * Array of user-added callback methods13295 *13296 * @access private13297 * @var array13298 */13299 var $built_in = array();13300 13301 /**13302 * Array of user-added callback methods13303 *13304 * @access private13305 * @var array13306 */13307 var $user = array();13308 13309 /**13310 * Create new SimplePie_Parse_Date object, and set self::day_pcre,13311 * self::month_pcre, and self::built_in13312 *13313 * @access private13314 */13315 function SimplePie_Parse_Date()13316 {13317 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';13318 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';13319 13320 static $cache;13321 if (!isset($cache[get_class($this)]))13322 {13323 $all_methods = get_class_methods($this);13324 13325 foreach ($all_methods as $method)13326 {13327 if (strtolower(substr($method, 0, 5)) === 'date_')13328 {13329 $cache[get_class($this)][] = $method;13330 }13331 }13332 }13333 13334 foreach ($cache[get_class($this)] as $method)13335 {13336 $this->built_in[] = $method;13337 }13338 }13339 13340 /**13341 * Get the object13342 *13343 * @access public13344 */13345 function get()13346 {13347 static $object;13348 if (!$object)13349 {13350 $object =& new SimplePie_Parse_Date;13351 }13352 return $object;13353 }13354 13355 /**13356 * Parse a date13357 *13358 * @final13359 * @access public13360 * @param string $date Date to parse13361 * @return int Timestamp corresponding to date string, or false on failure13362 */13363 function parse($date)13364 {13365 foreach ($this->user as $method)13366 {13367 if (($returned = call_user_func($method, $date)) !== false)13368 {13369 return $returned;13370 }13371 }13372 13373 foreach ($this->built_in as $method)13374 {13375 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)13376 {13377 return $returned;13378 }13379 }13380 13381 return false;13382 }13383 13384 /**13385 * Add a callback method to parse a date13386 *13387 * @final13388 * @access public13389 * @param callback $callback13390 */13391 function add_callback($callback)13392 {13393 if (is_callable($callback))13394 {13395 $this->user[] = $callback;13396 }13397 else13398 {13399 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);13400 }13401 }13402 13403 /**13404 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as13405 * well as allowing any of upper or lower case "T", horizontal tabs, or13406 * spaces to be used as the time seperator (including more than one))13407 *13408 * @access protected13409 * @return int Timestamp13410 */13411 function date_w3cdtf($date)13412 {13413 static $pcre;13414 if (!$pcre)13415 {13416 $year = '([0-9]{4})';13417 $month = $day = $hour = $minute = $second = '([0-9]{2})';13418 $decimal = '([0-9]*)';13419 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';13420 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';13421 }13422 if (preg_match($pcre, $date, $match))13423 {13424 /*13425 Capturing subpatterns:13426 1: Year13427 2: Month13428 3: Day13429 4: Hour13430 5: Minute13431 6: Second13432 7: Decimal fraction of a second13433 8: Zulu13434 9: Timezone ±13435 10: Timezone hours13436 11: Timezone minutes13437 */13438 13439 // Fill in empty matches13440 for ($i = count($match); $i <= 3; $i++)13441 {13442 $match[$i] = '1';13443 }13444 13445 for ($i = count($match); $i <= 7; $i++)13446 {13447 $match[$i] = '0';13448 }13449 13450 // Numeric timezone13451 if (isset($match[9]) && $match[9] !== '')13452 {13453 $timezone = $match[10] * 3600;13454 $timezone += $match[11] * 60;13455 if ($match[9] === '-')13456 {13457 $timezone = 0 - $timezone;13458 }13459 }13460 else13461 {13462 $timezone = 0;13463 }13464 13465 // Convert the number of seconds to an integer, taking decimals into account13466 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));13467 13468 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;13469 }13470 else13471 {13472 return false;13473 }13474 }13475 13476 /**13477 * Remove RFC822 comments13478 *13479 * @access protected13480 * @param string $data Data to strip comments from13481 * @return string Comment stripped string13482 */13483 function remove_rfc2822_comments($string)13484 {13485 $string = (string) $string;13486 $position = 0;13487 $length = strlen($string);13488 $depth = 0;13489 13490 $output = '';13491 13492 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)13493 {13494 $output .= substr($string, $position, $pos - $position);13495 $position = $pos + 1;13496 if ($string[$pos - 1] !== '\\')13497 {13498 $depth++;13499 while ($depth && $position < $length)13500 {13501 $position += strcspn($string, '()', $position);13502 if ($string[$position - 1] === '\\')13503 {13504 $position++;13505 continue;13506 }13507 elseif (isset($string[$position]))13508 {13509 switch ($string[$position])13510 {13511 case '(':13512 $depth++;13513 break;13514 13515 case ')':13516 $depth--;13517 break;13518 }13519 $position++;13520 }13521 else13522 {13523 break;13524 }13525 }13526 }13527 else13528 {13529 $output .= '(';13530 }13531 }13532 $output .= substr($string, $position);13533 13534 return $output;13535 }13536 13537 /**13538 * Parse RFC2822's date format13539 *13540 * @access protected13541 * @return int Timestamp13542 */13543 function date_rfc2822($date)13544 {13545 static $pcre;13546 if (!$pcre)13547 {13548 $wsp = '[\x09\x20]';13549 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';13550 $optional_fws = $fws . '?';13551 $day_name = $this->day_pcre;13552 $month = $this->month_pcre;13553 $day = '([0-9]{1,2})';13554 $hour = $minute = $second = '([0-9]{2})';13555 $year = '([0-9]{2,4})';13556 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';13557 $character_zone = '([A-Z]{1,5})';13558 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';13559 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';13560 }13561 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))13562 {13563 /*13564 Capturing subpatterns:13565 1: Day name13566 2: Day13567 3: Month13568 4: Year13569 5: Hour13570 6: Minute13571 7: Second13572 8: Timezone ±13573 9: Timezone hours13574 10: Timezone minutes13575 11: Alphabetic timezone13576 */13577 13578 // Find the month number13579 $month = $this->month[strtolower($match[3])];13580 13581 // Numeric timezone13582 if ($match[8] !== '')13583 {13584 $timezone = $match[9] * 3600;13585 $timezone += $match[10] * 60;13586 if ($match[8] === '-')13587 {13588 $timezone = 0 - $timezone;13589 }13590 }13591 // Character timezone13592 elseif (isset($this->timezone[strtoupper($match[11])]))13593 {13594 $timezone = $this->timezone[strtoupper($match[11])];13595 }13596 // Assume everything else to be -000013597 else13598 {13599 $timezone = 0;13600 }13601 13602 // Deal with 2/3 digit years13603 if ($match[4] < 50)13604 {13605 $match[4] += 2000;13606 }13607 elseif ($match[4] < 1000)13608 {13609 $match[4] += 1900;13610 }13611 13612 // Second is optional, if it is empty set it to zero13613 if ($match[7] !== '')13614 {13615 $second = $match[7];13616 }13617 else13618 {13619 $second = 0;13620 }13621 13622 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;13623 }13624 else13625 {13626 return false;13627 }13628 }13629 13630 /**13631 * Parse RFC850's date format13632 *13633 * @access protected13634 * @return int Timestamp13635 */13636 function date_rfc850($date)13637 {13638 static $pcre;13639 if (!$pcre)13640 {13641 $space = '[\x09\x20]+';13642 $day_name = $this->day_pcre;13643 $month = $this->month_pcre;13644 $day = '([0-9]{1,2})';13645 $year = $hour = $minute = $second = '([0-9]{2})';13646 $zone = '([A-Z]{1,5})';13647 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';13648 }13649 if (preg_match($pcre, $date, $match))13650 {13651 /*13652 Capturing subpatterns:13653 1: Day name13654 2: Day13655 3: Month13656 4: Year13657 5: Hour13658 6: Minute13659 7: Second13660 8: Timezone13661 */13662 13663 // Month13664 $month = $this->month[strtolower($match[3])];13665 13666 // Character timezone13667 if (isset($this->timezone[strtoupper($match[8])]))13668 {13669 $timezone = $this->timezone[strtoupper($match[8])];13670 }13671 // Assume everything else to be -000013672 else13673 {13674 $timezone = 0;13675 }13676 13677 // Deal with 2 digit year13678 if ($match[4] < 50)13679 {13680 $match[4] += 2000;13681 }13682 else13683 {13684 $match[4] += 1900;13685 }13686 13687 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;13688 }13689 else13690 {13691 return false;13692 }13693 }13694 13695 /**13696 * Parse C99's asctime()'s date format13697 *13698 * @access protected13699 * @return int Timestamp13700 */13701 function date_asctime($date)13702 {13703 static $pcre;13704 if (!$pcre)13705 {13706 $space = '[\x09\x20]+';13707 $wday_name = $this->day_pcre;13708 $mon_name = $this->month_pcre;13709 $day = '([0-9]{1,2})';13710 $hour = $sec = $min = '([0-9]{2})';13711 $year = '([0-9]{4})';13712 $terminator = '\x0A?\x00?';13713 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';13714 }13715 if (preg_match($pcre, $date, $match))13716 {13717 /*13718 Capturing subpatterns:13719 1: Day name13720 2: Month13721 3: Day13722 4: Hour13723 5: Minute13724 6: Second13725 7: Year13726 */13727 13728 $month = $this->month[strtolower($match[2])];13729 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);13730 }13731 else13732 {13733 return false;13734 }13735 }13736 13737 /**13738 * Parse dates using strtotime()13739 *13740 * @access protected13741 * @return int Timestamp13742 */13743 function date_strtotime($date)13744 {13745 $strtotime = strtotime($date);13746 if ($strtotime === -1 || $strtotime === false)13747 {13748 return false;13749 }13750 else13751 {13752 return $strtotime;13753 }13754 }13755 }13756 13757 /**13758 * Content-type sniffing13759 *13760 * @package SimplePie13761 */13762 class SimplePie_Content_Type_Sniffer13763 {13764 /**13765 * File object13766 *13767 * @var SimplePie_File13768 * @access private13769 */13770 var $file;13771 13772 /**13773 * Create an instance of the class with the input file13774 *13775 * @access public13776 * @param SimplePie_Content_Type_Sniffer $file Input file13777 */13778 function SimplePie_Content_Type_Sniffer($file)13779 {13780 $this->file = $file;13781 }13782 13783 /**13784 * Get the Content-Type of the specified file13785 *13786 * @access public13787 * @return string Actual Content-Type13788 */13789 function get_type()13790 {13791 if (isset($this->file->headers['content-type']))13792 {13793 if (!isset($this->file->headers['content-encoding'])13794 && ($this->file->headers['content-type'] === 'text/plain'13795 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'13796 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))13797 {13798 return $this->text_or_binary();13799 }13800 13801 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)13802 {13803 $official = substr($this->file->headers['content-type'], 0, $pos);13804 }13805 else13806 {13807 $official = $this->file->headers['content-type'];13808 }13809 $official = strtolower($official);13810 13811 if ($official === 'unknown/unknown'13812 || $official === 'application/unknown')13813 {13814 return $this->unknown();13815 }13816 elseif (substr($official, -4) === '+xml'13817 || $official === 'text/xml'13818 || $official === 'application/xml')13819 {13820 return $official;13821 }13822 elseif (substr($official, 0, 6) === 'image/')13823 {13824 if ($return = $this->image())13825 {13826 return $return;13827 }13828 else13829 {13830 return $official;13831 }13832 }13833 elseif ($official === 'text/html')13834 {13835 return $this->feed_or_html();13836 }13837 else13838 {13839 return $official;13840 }13841 }13842 else13843 {13844 return $this->unknown();13845 }13846 }13847 13848 /**13849 * Sniff text or binary13850 *13851 * @access private13852 * @return string Actual Content-Type13853 */13854 function text_or_binary()13855 {13856 if (substr($this->file->body, 0, 2) === "\xFE\xFF"13857 || substr($this->file->body, 0, 2) === "\xFF\xFE"13858 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"13859 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")13860 {13861 return 'text/plain';13862 }13863 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))13864 {13865 return 'application/octect-stream';13866 }13867 else13868 {13869 return 'text/plain';13870 }13871 }13872 13873 /**13874 * Sniff unknown13875 *13876 * @access private13877 * @return string Actual Content-Type13878 */13879 function unknown()13880 {13881 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");13882 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'13883 || strtolower(substr($this->file->body, $ws, 5)) === '<html'13884 || strtolower(substr($this->file->body, $ws, 7)) === '<script')13885 {13886 return 'text/html';13887 }13888 elseif (substr($this->file->body, 0, 5) === '%PDF-')13889 {13890 return 'application/pdf';13891 }13892 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')13893 {13894 return 'application/postscript';13895 }13896 elseif (substr($this->file->body, 0, 6) === 'GIF87a'13897 || substr($this->file->body, 0, 6) === 'GIF89a')13898 {13899 return 'image/gif';13900 }13901 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")13902 {13903 return 'image/png';13904 }13905 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")13906 {13907 return 'image/jpeg';13908 }13909 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")13910 {13911 return 'image/bmp';13912 }13913 else13914 {13915 return $this->text_or_binary();13916 }13917 }13918 13919 /**13920 * Sniff images13921 *13922 * @access private13923 * @return string Actual Content-Type13924 */13925 function image()13926 {13927 if (substr($this->file->body, 0, 6) === 'GIF87a'13928 || substr($this->file->body, 0, 6) === 'GIF89a')13929 {13930 return 'image/gif';13931 }13932 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")13933 {13934 return 'image/png';13935 }13936 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")13937 {13938 return 'image/jpeg';13939 }13940 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")13941 {13942 return 'image/bmp';13943 }13944 else13945 {13946 return false;13947 }13948 }13949 13950 /**13951 * Sniff HTML13952 *13953 * @access private13954 * @return string Actual Content-Type13955 */13956 function feed_or_html()13957 {13958 $len = strlen($this->file->body);13959 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");13960 13961 while ($pos < $len)13962 {13963 switch ($this->file->body[$pos])13964 {13965 case "\x09":13966 case "\x0A":13967 case "\x0D":13968 case "\x20":13969 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);13970 continue 2;13971 13972 case '<':13973 $pos++;13974 break;13975 13976 default:13977 return 'text/html';13978 }13979 13980 if (substr($this->file->body, $pos, 3) === '!--')13981 {13982 $pos += 3;13983 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)13984 {13985 $pos += 3;13986 }13987 else13988 {13989 return 'text/html';13990 }13991 }13992 elseif (substr($this->file->body, $pos, 1) === '!')13993 {13994 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)13995 {13996 $pos++;13997 }13998 else13999 {14000 return 'text/html';14001 }14002 }14003 elseif (substr($this->file->body, $pos, 1) === '?')14004 {14005 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)14006 {14007 $pos += 2;14008 }14009 else14010 {14011 return 'text/html';14012 }14013 }14014 elseif (substr($this->file->body, $pos, 3) === 'rss'14015 || substr($this->file->body, $pos, 7) === 'rdf:RDF')14016 {14017 return 'application/rss+xml';14018 }14019 elseif (substr($this->file->body, $pos, 4) === 'feed')14020 {14021 return 'application/atom+xml';14022 }14023 else14024 {14025 return 'text/html';14026 }14027 }14028 14029 return 'text/html';14030 }14031 }14032 14033 /**14034 * Parses the XML Declaration14035 *14036 * @package SimplePie14037 */14038 class SimplePie_XML_Declaration_Parser14039 {14040 /**14041 * XML Version14042 *14043 * @access public14044 * @var string14045 */14046 var $version = '1.0';14047 14048 /**14049 * Encoding14050 *14051 * @access public14052 * @var string14053 */14054 var $encoding = 'UTF-8';14055 14056 /**14057 * Standalone14058 *14059 * @access public14060 * @var bool14061 */14062 var $standalone = false;14063 14064 /**14065 * Current state of the state machine14066 *14067 * @access private14068 * @var string14069 */14070 var $state = 'before_version_name';14071 14072 /**14073 * Input data14074 *14075 * @access private14076 * @var string14077 */14078 var $data = '';14079 14080 /**14081 * Input data length (to avoid calling strlen() everytime this is needed)14082 *14083 * @access private14084 * @var int14085 */14086 var $data_length = 0;14087 14088 /**14089 * Current position of the pointer14090 *14091 * @var int14092 * @access private14093 */14094 var $position = 0;14095 14096 /**14097 * Create an instance of the class with the input data14098 *14099 * @access public14100 * @param string $data Input data14101 */14102 function SimplePie_XML_Declaration_Parser($data)14103 {14104 $this->data = $data;14105 $this->data_length = strlen($this->data);14106 }14107 14108 /**14109 * Parse the input data14110 *14111 * @access public14112 * @return bool true on success, false on failure14113 */14114 function parse()14115 {14116 while ($this->state && $this->state !== 'emit' && $this->has_data())14117 {14118 $state = $this->state;14119 $this->$state();14120 }14121 $this->data = '';14122 if ($this->state === 'emit')14123 {14124 return true;14125 }14126 else14127 {14128 $this->version = '';14129 $this->encoding = '';14130 $this->standalone = '';14131 return false;14132 }14133 }14134 14135 /**14136 * Check whether there is data beyond the pointer14137 *14138 * @access private14139 * @return bool true if there is further data, false if not14140 */14141 function has_data()14142 {14143 return (bool) ($this->position < $this->data_length);14144 }14145 14146 /**14147 * Advance past any whitespace14148 *14149 * @return int Number of whitespace characters passed14150 */14151 function skip_whitespace()14152 {14153 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);14154 $this->position += $whitespace;14155 return $whitespace;14156 }14157 14158 /**14159 * Read value14160 */14161 function get_value()14162 {14163 $quote = substr($this->data, $this->position, 1);14164 if ($quote === '"' || $quote === "'")14165 {14166 $this->position++;14167 $len = strcspn($this->data, $quote, $this->position);14168 if ($this->has_data())14169 {14170 $value = substr($this->data, $this->position, $len);14171 $this->position += $len + 1;14172 return $value;14173 }14174 }14175 return false;14176 }14177 14178 function before_version_name()14179 {14180 if ($this->skip_whitespace())14181 {14182 $this->state = 'version_name';14183 }14184 else14185 {14186 $this->state = false;14187 }14188 }14189 14190 function version_name()14191 {14192 if (substr($this->data, $this->position, 7) === 'version')14193 {14194 $this->position += 7;14195 $this->skip_whitespace();14196 $this->state = 'version_equals';14197 }14198 else14199 {14200 $this->state = false;14201 }14202 }14203 14204 function version_equals()14205 {14206 if (substr($this->data, $this->position, 1) === '=')14207 {14208 $this->position++;14209 $this->skip_whitespace();14210 $this->state = 'version_value';14211 }14212 else14213 {14214 $this->state = false;14215 }14216 }14217 14218 function version_value()14219 {14220 if ($this->version = $this->get_value())14221 {14222 $this->skip_whitespace();14223 if ($this->has_data())14224 {14225 $this->state = 'encoding_name';14226 }14227 else14228 {14229 $this->state = 'emit';14230 }14231 }14232 else14233 {14234 $this->state = false;14235 }14236 }14237 14238 function encoding_name()14239 {14240 if (substr($this->data, $this->position, 8) === 'encoding')14241 {14242 $this->position += 8;14243 $this->skip_whitespace();14244 $this->state = 'encoding_equals';14245 }14246 else14247 {14248 $this->state = 'standalone_name';14249 }14250 }14251 14252 function encoding_equals()14253 {14254 if (substr($this->data, $this->position, 1) === '=')14255 {14256 $this->position++;14257 $this->skip_whitespace();14258 $this->state = 'encoding_value';14259 }14260 else14261 {14262 $this->state = false;14263 }14264 }14265 14266 function encoding_value()14267 {14268 if ($this->encoding = $this->get_value())14269 {14270 $this->skip_whitespace();14271 if ($this->has_data())14272 {14273 $this->state = 'standalone_name';14274 }14275 else14276 {14277 $this->state = 'emit';14278 }14279 }14280 else14281 {14282 $this->state = false;14283 }14284 }14285 14286 function standalone_name()14287 {14288 if (substr($this->data, $this->position, 10) === 'standalone')14289 {14290 $this->position += 10;14291 $this->skip_whitespace();14292 $this->state = 'standalone_equals';14293 }14294 else14295 {14296 $this->state = false;14297 }14298 }14299 14300 function standalone_equals()14301 {14302 if (substr($this->data, $this->position, 1) === '=')14303 {14304 $this->position++;14305 $this->skip_whitespace();14306 $this->state = 'standalone_value';14307 }14308 else14309 {14310 $this->state = false;14311 }14312 }14313 14314 function standalone_value()14315 {14316 if ($standalone = $this->get_value())14317 {14318 switch ($standalone)14319 {14320 case 'yes':14321 $this->standalone = true;14322 break;14323 14324 case 'no':14325 $this->standalone = false;14326 break;14327 14328 default:14329 $this->state = false;14330 return;14331 }14332 14333 $this->skip_whitespace();14334 if ($this->has_data())14335 {14336 $this->state = false;14337 }14338 else14339 {14340 $this->state = 'emit';14341 }14342 }14343 else14344 {14345 $this->state = false;14346 }14347 }14348 }14349 14350 class SimplePie_Locator14351 {14352 var $useragent;14353 var $timeout;14354 var $file;14355 var $local = array();14356 var $elsewhere = array();14357 var $file_class = 'SimplePie_File';14358 var $cached_entities = array();14359 var $http_base;14360 var $base;14361 var $base_location = 0;14362 var $checked_feeds = 0;14363 var $max_checked_feeds = 10;14364 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';14365 14366 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')14367 {14368 $this->file =& $file;14369 $this->file_class = $file_class;14370 $this->useragent = $useragent;14371 $this->timeout = $timeout;14372 $this->max_checked_feeds = $max_checked_feeds;14373 $this->content_type_sniffer_class = $content_type_sniffer_class;14374 }14375 14376 function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)14377 {14378 if ($this->is_feed($this->file))14379 {14380 return $this->file;14381 }14382 14383 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)14384 {14385 $sniffer =& new $this->content_type_sniffer_class($this->file);14386 if ($sniffer->get_type() !== 'text/html')14387 {14388 return null;14389 }14390 }14391 14392 if ($type & ~SIMPLEPIE_LOCATOR_NONE)14393 {14394 $this->get_base();14395 }14396 14397 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())14398 {14399 return $working[0];14400 }14401 14402 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())14403 {14404 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))14405 {14406 return $working;14407 }14408 14409 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))14410 {14411 return $working;14412 }14413 14414 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))14415 {14416 return $working;14417 }14418 14419 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))14420 {14421 return $working;14422 }14423 }14424 return null;14425 }14426 14427 function is_feed(&$file)14428 {14429 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)14430 {14431 $sniffer =& new $this->content_type_sniffer_class($file);14432 $sniffed = $sniffer->get_type();14433 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))14434 {14435 return true;14436 }14437 else14438 {14439 return false;14440 }14441 }14442 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)14443 {14444 return true;14445 }14446 else14447 {14448 return false;14449 }14450 }14451 14452 function get_base()14453 {14454 $this->http_base = $this->file->url;14455 $this->base = $this->http_base;14456 $elements = SimplePie_Misc::get_element('base', $this->file->body);14457 foreach ($elements as $element)14458 {14459 if ($element['attribs']['href']['data'] !== '')14460 {14461 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);14462 $this->base_location = $element['offset'];14463 break;14464 }14465 }14466 }14467 14468 function autodiscovery()14469 {14470 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));14471 $done = array();14472 $feeds = array();14473 foreach ($links as $link)14474 {14475 if ($this->checked_feeds === $this->max_checked_feeds)14476 {14477 break;14478 }14479 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))14480 {14481 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));14482 14483 if ($this->base_location < $link['offset'])14484 {14485 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);14486 }14487 else14488 {14489 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);14490 }14491 14492 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))14493 {14494 $this->checked_feeds++;14495 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);14496 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))14497 {14498 $feeds[$href] = $feed;14499 }14500 }14501 $done[] = $href;14502 }14503 }14504 14505 if (!empty($feeds))14506 {14507 return array_values($feeds);14508 }14509 else {14510 return null;14511 }14512 }14513 14514 function get_links()14515 {14516 $links = SimplePie_Misc::get_element('a', $this->file->body);14517 foreach ($links as $link)14518 {14519 if (isset($link['attribs']['href']['data']))14520 {14521 $href = trim($link['attribs']['href']['data']);14522 $parsed = SimplePie_Misc::parse_url($href);14523 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))14524 {14525 if ($this->base_location < $link['offset'])14526 {14527 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);14528 }14529 else14530 {14531 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);14532 }14533 14534 $current = SimplePie_Misc::parse_url($this->file->url);14535 14536 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])14537 {14538 $this->local[] = $href;14539 }14540 else14541 {14542 $this->elsewhere[] = $href;14543 }14544 }14545 }14546 }14547 $this->local = array_unique($this->local);14548 $this->elsewhere = array_unique($this->elsewhere);14549 if (!empty($this->local) || !empty($this->elsewhere))14550 {14551 return true;14552 }14553 return null;14554 }14555 14556 function extension(&$array)14557 {14558 foreach ($array as $key => $value)14559 {14560 if ($this->checked_feeds === $this->max_checked_feeds)14561 {14562 break;14563 }14564 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))14565 {14566 $this->checked_feeds++;14567 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);14568 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))14569 {14570 return $feed;14571 }14572 else14573 {14574 unset($array[$key]);14575 }14576 }14577 }14578 return null;14579 }14580 14581 function body(&$array)14582 {14583 foreach ($array as $key => $value)14584 {14585 if ($this->checked_feeds === $this->max_checked_feeds)14586 {14587 break;14588 }14589 if (preg_match('/(rss|rdf|atom|xml)/i', $value))14590 {14591 $this->checked_feeds++;14592 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);14593 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))14594 {14595 return $feed;14596 }14597 else14598 {14599 unset($array[$key]);14600 }14601 }14602 }14603 return null;14604 }14605 }14606 14607 class SimplePie_Parser14608 {14609 var $error_code;14610 var $error_string;14611 var $current_line;14612 var $current_column;14613 var $current_byte;14614 var $separator = ' ';14615 var $namespace = array('');14616 var $element = array('');14617 var $xml_base = array('');14618 var $xml_base_explicit = array(false);14619 var $xml_lang = array('');14620 var $data = array();14621 var $datas = array(array());14622 var $current_xhtml_construct = -1;14623 var $encoding;14624 14625 function parse(&$data, $encoding)14626 {14627 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character14628 if (strtoupper($encoding) === 'US-ASCII')14629 {14630 $this->encoding = 'UTF-8';14631 }14632 else14633 {14634 $this->encoding = $encoding;14635 }14636 14637 // Strip BOM:14638 // UTF-32 Big Endian BOM14639 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")14640 {14641 $data = substr($data, 4);14642 }14643 // UTF-32 Little Endian BOM14644 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")14645 {14646 $data = substr($data, 4);14647 }14648 // UTF-16 Big Endian BOM14649 elseif (substr($data, 0, 2) === "\xFE\xFF")14650 {14651 $data = substr($data, 2);14652 }14653 // UTF-16 Little Endian BOM14654 elseif (substr($data, 0, 2) === "\xFF\xFE")14655 {14656 $data = substr($data, 2);14657 }14658 // UTF-8 BOM14659 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")14660 {14661 $data = substr($data, 3);14662 }14663 14664 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)14665 {14666 $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));14667 if ($declaration->parse())14668 {14669 $data = substr($data, $pos + 2);14670 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;14671 }14672 else14673 {14674 $this->error_string = 'SimplePie bug! Please report this!';14675 return false;14676 }14677 }14678 14679 $return = true;14680 14681 static $xml_is_sane = null;14682 if ($xml_is_sane === null)14683 {14684 $parser_check = xml_parser_create();14685 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);14686 xml_parser_free($parser_check);14687 $xml_is_sane = isset($values[0]['value']);14688 }14689 14690 // Create the parser14691 if ($xml_is_sane)14692 {14693 $xml = xml_parser_create_ns($this->encoding, $this->separator);14694 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);14695 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);14696 xml_set_object($xml, $this);14697 xml_set_character_data_handler($xml, 'cdata');14698 xml_set_element_handler($xml, 'tag_open', 'tag_close');14699 14700 // Parse!14701 if (!xml_parse($xml, $data, true))14702 {14703 $this->error_code = xml_get_error_code($xml);14704 $this->error_string = xml_error_string($this->error_code);14705 $return = false;14706 }14707 $this->current_line = xml_get_current_line_number($xml);14708 $this->current_column = xml_get_current_column_number($xml);14709 $this->current_byte = xml_get_current_byte_index($xml);14710 xml_parser_free($xml);14711 return $return;14712 }14713 else14714 {14715 libxml_clear_errors();14716 $xml =& new XMLReader();14717 $xml->xml($data);14718 while (@$xml->read())14719 {14720 switch ($xml->nodeType)14721 {14722 14723 case constant('XMLReader::END_ELEMENT'):14724 if ($xml->namespaceURI !== '')14725 {14726 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;14727 }14728 else14729 {14730 $tagName = $xml->localName;14731 }14732 $this->tag_close(null, $tagName);14733 break;14734 case constant('XMLReader::ELEMENT'):14735 $empty = $xml->isEmptyElement;14736 if ($xml->namespaceURI !== '')14737 {14738 $tagName = $xml->namespaceURI . $this->separator . $xml->localName;14739 }14740 else14741 {14742 $tagName = $xml->localName;14743 }14744 $attributes = array();14745 while ($xml->moveToNextAttribute())14746 {14747 if ($xml->namespaceURI !== '')14748 {14749 $attrName = $xml->namespaceURI . $this->separator . $xml->localName;14750 }14751 else14752 {14753 $attrName = $xml->localName;14754 }14755 $attributes[$attrName] = $xml->value;14756 }14757 $this->tag_open(null, $tagName, $attributes);14758 if ($empty)14759 {14760 $this->tag_close(null, $tagName);14761 }14762 break;14763 case constant('XMLReader::TEXT'):14764 14765 case constant('XMLReader::CDATA'):14766 $this->cdata(null, $xml->value);14767 break;14768 }14769 }14770 if ($error = libxml_get_last_error())14771 {14772 $this->error_code = $error->code;14773 $this->error_string = $error->message;14774 $this->current_line = $error->line;14775 $this->current_column = $error->column;14776 return false;14777 }14778 else14779 {14780 return true;14781 }14782 }14783 }14784 14785 function get_error_code()14786 {14787 return $this->error_code;14788 }14789 14790 function get_error_string()14791 {14792 return $this->error_string;14793 }14794 14795 function get_current_line()14796 {14797 return $this->current_line;14798 }14799 14800 function get_current_column()14801 {14802 return $this->current_column;14803 }14804 14805 function get_current_byte()14806 {14807 return $this->current_byte;14808 }14809 14810 function get_data()14811 {14812 return $this->data;14813 }14814 14815 function tag_open($parser, $tag, $attributes)14816 {14817 list($this->namespace[], $this->element[]) = $this->split_ns($tag);14818 14819 $attribs = array();14820 foreach ($attributes as $name => $value)14821 {14822 list($attrib_namespace, $attribute) = $this->split_ns($name);14823 $attribs[$attrib_namespace][$attribute] = $value;14824 }14825 14826 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))14827 {14828 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));14829 $this->xml_base_explicit[] = true;14830 }14831 else14832 {14833 $this->xml_base[] = end($this->xml_base);14834 $this->xml_base_explicit[] = end($this->xml_base_explicit);14835 }14836 14837 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))14838 {14839 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];14840 }14841 else14842 {14843 $this->xml_lang[] = end($this->xml_lang);14844 }14845 14846 if ($this->current_xhtml_construct >= 0)14847 {14848 $this->current_xhtml_construct++;14849 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)14850 {14851 $this->data['data'] .= '<' . end($this->element);14852 if (isset($attribs['']))14853 {14854 foreach ($attribs[''] as $name => $value)14855 {14856 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';14857 }14858 }14859 $this->data['data'] .= '>';14860 }14861 }14862 else14863 {14864 $this->datas[] =& $this->data;14865 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];14866 $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));14867 if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')14868 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml'))14869 {14870 $this->current_xhtml_construct = 0;14871 }14872 }14873 }14874 14875 function cdata($parser, $cdata)14876 {14877 if ($this->current_xhtml_construct >= 0)14878 {14879 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);14880 }14881 else14882 {14883 $this->data['data'] .= $cdata;14884 }14885 }14886 14887 function tag_close($parser, $tag)14888 {14889 if ($this->current_xhtml_construct >= 0)14890 {14891 $this->current_xhtml_construct--;14892 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))14893 {14894 $this->data['data'] .= '</' . end($this->element) . '>';14895 }14896 }14897 if ($this->current_xhtml_construct === -1)14898 {14899 $this->data =& $this->datas[count($this->datas) - 1];14900 array_pop($this->datas);14901 }14902 14903 array_pop($this->element);14904 array_pop($this->namespace);14905 array_pop($this->xml_base);14906 array_pop($this->xml_base_explicit);14907 array_pop($this->xml_lang);14908 }14909 14910 function split_ns($string)14911 {14912 static $cache = array();14913 if (!isset($cache[$string]))14914 {14915 if ($pos = strpos($string, $this->separator))14916 {14917 static $separator_length;14918 if (!$separator_length)14919 {14920 $separator_length = strlen($this->separator);14921 }14922 $namespace = substr($string, 0, $pos);14923 $local_name = substr($string, $pos + $separator_length);14924 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)14925 {14926 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;14927 }14928 14929 // Normalize the Media RSS namespaces14930 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)14931 {14932 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;14933 }14934 $cache[$string] = array($namespace, $local_name);14935 }14936 else14937 {14938 $cache[$string] = array('', $string);14939 }14940 }14941 return $cache[$string];14942 }14943 }14944 14945 /**14946 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags14947 */14948 class SimplePie_Sanitize14949 {14950 // Private vars14951 var $base;14952 14953 // Options14954 var $remove_div = true;14955 var $image_handler = '';14956 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');14957 var $encode_instead_of_strip = false;14958 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');14959 var $strip_comments = false;14960 var $output_encoding = 'UTF-8';14961 var $enable_cache = true;14962 var $cache_location = './cache';14963 var $cache_name_function = 'md5';14964 var $cache_class = 'SimplePie_Cache';14965 var $file_class = 'SimplePie_File';14966 var $timeout = 10;14967 var $useragent = '';14968 var $force_fsockopen = false;14969 14970 var $replace_url_attributes = array(14971 'a' => 'href',14972 'area' => 'href',14973 'blockquote' => 'cite',14974 'del' => 'cite',14975 'form' => 'action',14976 'img' => array('longdesc', 'src'),14977 'input' => 'src',14978 'ins' => 'cite',14979 'q' => 'cite'14980 );14981 14982 function remove_div($enable = true)14983 {14984 $this->remove_div = (bool) $enable;14985 }14986 14987 function set_image_handler($page = false)14988 {14989 if ($page)14990 {14991 $this->image_handler = (string) $page;14992 }14993 else14994 {14995 $this->image_handler = false;14996 }14997 }14998 14999 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')15000 {15001 if (isset($enable_cache))15002 {15003 $this->enable_cache = (bool) $enable_cache;15004 }15005 15006 if ($cache_location)15007 {15008 $this->cache_location = (string) $cache_location;15009 }15010 15011 if ($cache_name_function)15012 {15013 $this->cache_name_function = (string) $cache_name_function;15014 }15015 15016 if ($cache_class)15017 {15018 $this->cache_class = (string) $cache_class;15019 }15020 }15021 15022 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)15023 {15024 if ($file_class)15025 {15026 $this->file_class = (string) $file_class;15027 }15028 15029 if ($timeout)15030 {15031 $this->timeout = (string) $timeout;15032 }15033 15034 if ($useragent)15035 {15036 $this->useragent = (string) $useragent;15037 }15038 15039 if ($force_fsockopen)15040 {15041 $this->force_fsockopen = (string) $force_fsockopen;15042 }15043 }15044 15045 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))15046 {15047 if ($tags)15048 {15049 if (is_array($tags))15050 {15051 $this->strip_htmltags = $tags;15052 }15053 else15054 {15055 $this->strip_htmltags = explode(',', $tags);15056 }15057 }15058 else15059 {15060 $this->strip_htmltags = false;15061 }15062 }15063 15064 function encode_instead_of_strip($encode = false)15065 {15066 $this->encode_instead_of_strip = (bool) $encode;15067 }15068 15069 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))15070 {15071 if ($attribs)15072 {15073 if (is_array($attribs))15074 {15075 $this->strip_attributes = $attribs;15076 }15077 else15078 {15079 $this->strip_attributes = explode(',', $attribs);15080 }15081 }15082 else15083 {15084 $this->strip_attributes = false;15085 }15086 }15087 15088 function strip_comments($strip = false)15089 {15090 $this->strip_comments = (bool) $strip;15091 }15092 15093 function set_output_encoding($encoding = 'UTF-8')15094 {15095 $this->output_encoding = (string) $encoding;15096 }15097 15098 /**15099 * Set element/attribute key/value pairs of HTML attributes15100 * containing URLs that need to be resolved relative to the feed15101 *15102 * @access public15103 * @since 1.015104 * @param array $element_attribute Element/attribute key/value pairs15105 */15106 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))15107 {15108 $this->replace_url_attributes = (array) $element_attribute;15109 }15110 15111 function sanitize($data, $type, $base = '')15112 {15113 $data = trim($data);15114 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)15115 {15116 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)15117 {15118 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))15119 {15120 $type |= SIMPLEPIE_CONSTRUCT_HTML;15121 }15122 else15123 {15124 $type |= SIMPLEPIE_CONSTRUCT_TEXT;15125 }15126 }15127 15128 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)15129 {15130 $data = base64_decode($data);15131 }15132 15133 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)15134 {15135 if ($this->remove_div)15136 {15137 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);15138 $data = preg_replace('/<\/div>$/', '', $data);15139 }15140 else15141 {15142 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);15143 }15144 }15145 15146 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))15147 {15148 // Strip comments15149 if ($this->strip_comments)15150 {15151 $data = SimplePie_Misc::strip_comments($data);15152 }15153 15154 // Strip out HTML tags and attributes that might cause various security problems.15155 // Based on recommendations by Mark Pilgrim at:15156 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely15157 if ($this->strip_htmltags)15158 {15159 foreach ($this->strip_htmltags as $tag)15160 {15161 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';15162 while (preg_match($pcre, $data))15163 {15164 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);15165 }15166 }15167 }15168 15169 if ($this->strip_attributes)15170 {15171 foreach ($this->strip_attributes as $attrib)15172 {15173 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);15174 }15175 }15176 15177 // Replace relative URLs15178 $this->base = $base;15179 foreach ($this->replace_url_attributes as $element => $attributes)15180 {15181 $data = $this->replace_urls($data, $element, $attributes);15182 }15183 15184 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.15185 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)15186 {15187 $images = SimplePie_Misc::get_element('img', $data);15188 foreach ($images as $img)15189 {15190 if (isset($img['attribs']['src']['data']))15191 {15192 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);15193 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');15194 15195 if ($cache->load())15196 {15197 $img['attribs']['src']['data'] = $this->image_handler . $image_url;15198 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);15199 }15200 else15201 {15202 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);15203 $headers = $file->headers;15204 15205 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))15206 {15207 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))15208 {15209 $img['attribs']['src']['data'] = $this->image_handler . $image_url;15210 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);15211 }15212 else15213 {15214 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);15215 }15216 }15217 }15218 }15219 }15220 }15221 15222 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data15223 $data = trim($data);15224 }15225 15226 if ($type & SIMPLEPIE_CONSTRUCT_IRI)15227 {15228 $data = SimplePie_Misc::absolutize_url($data, $base);15229 }15230 15231 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))15232 {15233 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');15234 }15235 15236 if ($this->output_encoding !== 'UTF-8')15237 {15238 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);15239 }15240 }15241 return $data;15242 }15243 15244 function replace_urls($data, $tag, $attributes)15245 {15246 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))15247 {15248 $elements = SimplePie_Misc::get_element($tag, $data);15249 foreach ($elements as $element)15250 {15251 if (is_array($attributes))15252 {15253 foreach ($attributes as $attribute)15254 {15255 if (isset($element['attribs'][$attribute]['data']))15256 {15257 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);15258 $new_element = SimplePie_Misc::element_implode($element);15259 $data = str_replace($element['full'], $new_element, $data);15260 $element['full'] = $new_element;15261 }15262 }15263 }15264 elseif (isset($element['attribs'][$attributes]['data']))15265 {15266 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);15267 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);15268 }15269 }15270 }15271 return $data;15272 }15273 15274 function do_strip_htmltags($match)15275 {15276 if ($this->encode_instead_of_strip)15277 {15278 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))15279 {15280 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');15281 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');15282 return "<$match[1]$match[2]>$match[3]</$match[1]>";15283 }15284 else15285 {15286 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');15287 }15288 }15289 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))15290 {15291 return $match[4];15292 }15293 else15294 {15295 return '';15296 }15297 }15298 }15299 3038 endif; 15300 ?>
Note: See TracChangeset
for help on using the changeset viewer.