Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SimplePie often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SimplePie, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 448 | class SimplePie |
||
| 449 | { |
||
| 450 | /** |
||
| 451 | * @var array Raw data |
||
| 452 | * @access private |
||
| 453 | */ |
||
| 454 | public $data = array(); |
||
| 455 | |||
| 456 | /** |
||
| 457 | * @var mixed Error string |
||
| 458 | * @access private |
||
| 459 | */ |
||
| 460 | public $error; |
||
| 461 | |||
| 462 | /** |
||
| 463 | * @var object Instance of SimplePie_Sanitize (or other class) |
||
| 464 | * @see SimplePie::set_sanitize_class() |
||
| 465 | * @access private |
||
| 466 | */ |
||
| 467 | public $sanitize; |
||
| 468 | |||
| 469 | /** |
||
| 470 | * @var string SimplePie Useragent |
||
| 471 | * @see SimplePie::set_useragent() |
||
| 472 | * @access private |
||
| 473 | */ |
||
| 474 | public $useragent = SIMPLEPIE_USERAGENT; |
||
| 475 | |||
| 476 | /** |
||
| 477 | * @var string Feed URL |
||
| 478 | * @see SimplePie::set_feed_url() |
||
| 479 | * @access private |
||
| 480 | */ |
||
| 481 | public $feed_url; |
||
| 482 | |||
| 483 | /** |
||
| 484 | * @var object Instance of SimplePie_File to use as a feed |
||
| 485 | * @see SimplePie::set_file() |
||
| 486 | * @access private |
||
| 487 | */ |
||
| 488 | public $file; |
||
| 489 | |||
| 490 | /** |
||
| 491 | * @var string Raw feed data |
||
| 492 | * @see SimplePie::set_raw_data() |
||
| 493 | * @access private |
||
| 494 | */ |
||
| 495 | public $raw_data; |
||
| 496 | |||
| 497 | /** |
||
| 498 | * @var int Timeout for fetching remote files |
||
| 499 | * @see SimplePie::set_timeout() |
||
| 500 | * @access private |
||
| 501 | */ |
||
| 502 | public $timeout = 10; |
||
| 503 | |||
| 504 | /** |
||
| 505 | * @var bool Forces fsockopen() to be used for remote files instead |
||
| 506 | * of cURL, even if a new enough version is installed |
||
| 507 | * @see SimplePie::force_fsockopen() |
||
| 508 | * @access private |
||
| 509 | */ |
||
| 510 | public $force_fsockopen = false; |
||
| 511 | |||
| 512 | /** |
||
| 513 | * @var bool Force the given data/URL to be treated as a feed no matter what |
||
| 514 | * it appears like |
||
| 515 | * @see SimplePie::force_feed() |
||
| 516 | * @access private |
||
| 517 | */ |
||
| 518 | public $force_feed = false; |
||
| 519 | |||
| 520 | /** |
||
| 521 | * @var bool Enable/Disable Caching |
||
| 522 | * @see SimplePie::enable_cache() |
||
| 523 | * @access private |
||
| 524 | */ |
||
| 525 | public $cache = true; |
||
| 526 | |||
| 527 | /** |
||
| 528 | * @var int Cache duration (in seconds) |
||
| 529 | * @see SimplePie::set_cache_duration() |
||
| 530 | * @access private |
||
| 531 | */ |
||
| 532 | public $cache_duration = 3600; |
||
| 533 | |||
| 534 | /** |
||
| 535 | * @var int Auto-discovery cache duration (in seconds) |
||
| 536 | * @see SimplePie::set_autodiscovery_cache_duration() |
||
| 537 | * @access private |
||
| 538 | */ |
||
| 539 | public $autodiscovery_cache_duration = 604800; // 7 Days. |
||
| 540 | |||
| 541 | /** |
||
| 542 | * @var string Cache location (relative to executing script) |
||
| 543 | * @see SimplePie::set_cache_location() |
||
| 544 | * @access private |
||
| 545 | */ |
||
| 546 | public $cache_location = './cache'; |
||
| 547 | |||
| 548 | /** |
||
| 549 | * @var string Function that creates the cache filename |
||
| 550 | * @see SimplePie::set_cache_name_function() |
||
| 551 | * @access private |
||
| 552 | */ |
||
| 553 | public $cache_name_function = 'md5'; |
||
| 554 | |||
| 555 | /** |
||
| 556 | * @var bool Reorder feed by date descending |
||
| 557 | * @see SimplePie::enable_order_by_date() |
||
| 558 | * @access private |
||
| 559 | */ |
||
| 560 | public $order_by_date = true; |
||
| 561 | |||
| 562 | /** |
||
| 563 | * @var mixed Force input encoding to be set to the follow value |
||
| 564 | * (false, or anything type-cast to false, disables this feature) |
||
| 565 | * @see SimplePie::set_input_encoding() |
||
| 566 | * @access private |
||
| 567 | */ |
||
| 568 | public $input_encoding = false; |
||
| 569 | |||
| 570 | /** |
||
| 571 | * @var int Feed Autodiscovery Level |
||
| 572 | * @see SimplePie::set_autodiscovery_level() |
||
| 573 | * @access private |
||
| 574 | */ |
||
| 575 | public $autodiscovery = SIMPLEPIE_LOCATOR_ALL; |
||
| 576 | |||
| 577 | /** |
||
| 578 | * Class registry object |
||
| 579 | * |
||
| 580 | * @var SimplePie_Registry |
||
| 581 | */ |
||
| 582 | public $registry; |
||
| 583 | |||
| 584 | /** |
||
| 585 | * @var int Maximum number of feeds to check with autodiscovery |
||
| 586 | * @see SimplePie::set_max_checked_feeds() |
||
| 587 | * @access private |
||
| 588 | */ |
||
| 589 | public $max_checked_feeds = 10; |
||
| 590 | |||
| 591 | /** |
||
| 592 | * @var array All the feeds found during the autodiscovery process |
||
| 593 | * @see SimplePie::get_all_discovered_feeds() |
||
| 594 | * @access private |
||
| 595 | */ |
||
| 596 | public $all_discovered_feeds = array(); |
||
| 597 | |||
| 598 | /** |
||
| 599 | * @var string Web-accessible path to the handler_image.php file. |
||
| 600 | * @see SimplePie::set_image_handler() |
||
| 601 | * @access private |
||
| 602 | */ |
||
| 603 | public $image_handler = ''; |
||
| 604 | |||
| 605 | /** |
||
| 606 | * @var array Stores the URLs when multiple feeds are being initialized. |
||
| 607 | * @see SimplePie::set_feed_url() |
||
| 608 | * @access private |
||
| 609 | */ |
||
| 610 | public $multifeed_url = array(); |
||
| 611 | |||
| 612 | /** |
||
| 613 | * @var array Stores SimplePie objects when multiple feeds initialized. |
||
| 614 | * @access private |
||
| 615 | */ |
||
| 616 | public $multifeed_objects = array(); |
||
| 617 | |||
| 618 | /** |
||
| 619 | * @var array Stores the get_object_vars() array for use with multifeeds. |
||
| 620 | * @see SimplePie::set_feed_url() |
||
| 621 | * @access private |
||
| 622 | */ |
||
| 623 | public $config_settings = null; |
||
| 624 | |||
| 625 | /** |
||
| 626 | * @var integer Stores the number of items to return per-feed with multifeeds. |
||
| 627 | * @see SimplePie::set_item_limit() |
||
| 628 | * @access private |
||
| 629 | */ |
||
| 630 | public $item_limit = 0; |
||
| 631 | |||
| 632 | /** |
||
| 633 | * @var array Stores the default attributes to be stripped by strip_attributes(). |
||
| 634 | * @see SimplePie::strip_attributes() |
||
| 635 | * @access private |
||
| 636 | */ |
||
| 637 | public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); |
||
| 638 | |||
| 639 | /** |
||
| 640 | * @var array Stores the default tags to be stripped by strip_htmltags(). |
||
| 641 | * @see SimplePie::strip_htmltags() |
||
| 642 | * @access private |
||
| 643 | */ |
||
| 644 | public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); |
||
| 645 | |||
| 646 | /** |
||
| 647 | * The SimplePie class contains feed level data and options |
||
| 648 | * |
||
| 649 | * To use SimplePie, create the SimplePie object with no parameters. You can |
||
| 650 | * then set configuration options using the provided methods. After setting |
||
| 651 | * them, you must initialise the feed using $feed->init(). At that point the |
||
| 652 | * object's methods and properties will be available to you. |
||
| 653 | * |
||
| 654 | * Previously, it was possible to pass in the feed URL along with cache |
||
| 655 | * options directly into the constructor. This has been removed as of 1.3 as |
||
| 656 | * it caused a lot of confusion. |
||
| 657 | * |
||
| 658 | * @since 1.0 Preview Release |
||
| 659 | */ |
||
| 660 | public function __construct() |
||
| 661 | { |
||
| 662 | if (version_compare(PHP_VERSION, '5.2', '<')) |
||
| 663 | { |
||
| 664 | trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.'); |
||
| 665 | die(); |
||
| 666 | } |
||
| 667 | |||
| 668 | // Other objects, instances created here so we can set options on them |
||
| 669 | $this->sanitize = new SimplePie_Sanitize(); |
||
| 670 | $this->registry = new SimplePie_Registry(); |
||
| 671 | |||
| 672 | if (func_num_args() > 0) |
||
| 673 | { |
||
| 674 | $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; |
||
| 675 | trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.', $level); |
||
| 676 | |||
| 677 | $args = func_get_args(); |
||
| 678 | switch (count($args)) { |
||
| 679 | case 3: |
||
| 680 | $this->set_cache_duration($args[2]); |
||
| 681 | case 2: |
||
| 682 | $this->set_cache_location($args[1]); |
||
| 683 | case 1: |
||
| 684 | $this->set_feed_url($args[0]); |
||
| 685 | $this->init(); |
||
| 686 | } |
||
| 687 | } |
||
| 688 | } |
||
| 689 | |||
| 690 | /** |
||
| 691 | * Used for converting object to a string |
||
| 692 | */ |
||
| 693 | public function __toString() |
||
| 694 | { |
||
| 695 | return md5(serialize($this->data)); |
||
| 696 | } |
||
| 697 | |||
| 698 | /** |
||
| 699 | * Remove items that link back to this before destroying this object |
||
| 700 | */ |
||
| 701 | public function __destruct() |
||
| 702 | { |
||
| 703 | if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) |
||
| 704 | { |
||
| 705 | if (!empty($this->data['items'])) |
||
| 706 | { |
||
| 707 | foreach ($this->data['items'] as $item) |
||
| 708 | { |
||
| 709 | $item->__destruct(); |
||
| 710 | } |
||
| 711 | unset($item, $this->data['items']); |
||
| 712 | } |
||
| 713 | if (!empty($this->data['ordered_items'])) |
||
| 714 | { |
||
| 715 | foreach ($this->data['ordered_items'] as $item) |
||
| 716 | { |
||
| 717 | $item->__destruct(); |
||
| 718 | } |
||
| 719 | unset($item, $this->data['ordered_items']); |
||
| 720 | } |
||
| 721 | } |
||
| 722 | } |
||
| 723 | |||
| 724 | /** |
||
| 725 | * Force the given data/URL to be treated as a feed |
||
| 726 | * |
||
| 727 | * This tells SimplePie to ignore the content-type provided by the server. |
||
| 728 | * Be careful when using this option, as it will also disable autodiscovery. |
||
| 729 | * |
||
| 730 | * @since 1.1 |
||
| 731 | * @param bool $enable Force the given data/URL to be treated as a feed |
||
| 732 | */ |
||
| 733 | public function force_feed($enable = false) |
||
| 734 | { |
||
| 735 | $this->force_feed = (bool) $enable; |
||
| 736 | } |
||
| 737 | |||
| 738 | /** |
||
| 739 | * Set the URL of the feed you want to parse |
||
| 740 | * |
||
| 741 | * This allows you to enter the URL of the feed you want to parse, or the |
||
| 742 | * website you want to try to use auto-discovery on. This takes priority |
||
| 743 | * over any set raw data. |
||
| 744 | * |
||
| 745 | * You can set multiple feeds to mash together by passing an array instead |
||
| 746 | * of a string for the $url. Remember that with each additional feed comes |
||
| 747 | * additional processing and resources. |
||
| 748 | * |
||
| 749 | * @since 1.0 Preview Release |
||
| 750 | * @see set_raw_data() |
||
| 751 | * @param string|array $url This is the URL (or array of URLs) that you want to parse. |
||
| 752 | */ |
||
| 753 | public function set_feed_url($url) |
||
| 754 | { |
||
| 755 | $this->multifeed_url = array(); |
||
| 756 | if (is_array($url)) |
||
| 757 | { |
||
| 758 | foreach ($url as $value) |
||
| 759 | { |
||
| 760 | $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1)); |
||
| 761 | } |
||
| 762 | } |
||
| 763 | else |
||
| 764 | { |
||
| 765 | $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1)); |
||
| 766 | } |
||
| 767 | } |
||
| 768 | |||
| 769 | /** |
||
| 770 | * Set an instance of {@see SimplePie_File} to use as a feed |
||
| 771 | * |
||
| 772 | * @param SimplePie_File &$file |
||
| 773 | * @return bool True on success, false on failure |
||
| 774 | */ |
||
| 775 | public function set_file(&$file) |
||
| 776 | { |
||
| 777 | if ($file instanceof SimplePie_File) |
||
| 778 | { |
||
| 779 | $this->feed_url = $file->url; |
||
| 780 | $this->file =& $file; |
||
| 781 | return true; |
||
| 782 | } |
||
| 783 | return false; |
||
| 784 | } |
||
| 785 | |||
| 786 | /** |
||
| 787 | * Set the raw XML data to parse |
||
| 788 | * |
||
| 789 | * Allows you to use a string of RSS/Atom data instead of a remote feed. |
||
| 790 | * |
||
| 791 | * If you have a feed available as a string in PHP, you can tell SimplePie |
||
| 792 | * to parse that data string instead of a remote feed. Any set feed URL |
||
| 793 | * takes precedence. |
||
| 794 | * |
||
| 795 | * @since 1.0 Beta 3 |
||
| 796 | * @param string $data RSS or Atom data as a string. |
||
| 797 | * @see set_feed_url() |
||
| 798 | */ |
||
| 799 | public function set_raw_data($data) |
||
| 800 | { |
||
| 801 | $this->raw_data = $data; |
||
| 802 | } |
||
| 803 | |||
| 804 | /** |
||
| 805 | * Set the the default timeout for fetching remote feeds |
||
| 806 | * |
||
| 807 | * This allows you to change the maximum time the feed's server to respond |
||
| 808 | * and send the feed back. |
||
| 809 | * |
||
| 810 | * @since 1.0 Beta 3 |
||
| 811 | * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. |
||
| 812 | */ |
||
| 813 | public function set_timeout($timeout = 10) |
||
| 814 | { |
||
| 815 | $this->timeout = (int) $timeout; |
||
| 816 | } |
||
| 817 | |||
| 818 | /** |
||
| 819 | * Force SimplePie to use fsockopen() instead of cURL |
||
| 820 | * |
||
| 821 | * @since 1.0 Beta 3 |
||
| 822 | * @param bool $enable Force fsockopen() to be used |
||
| 823 | */ |
||
| 824 | public function force_fsockopen($enable = false) |
||
| 825 | { |
||
| 826 | $this->force_fsockopen = (bool) $enable; |
||
| 827 | } |
||
| 828 | |||
| 829 | /** |
||
| 830 | * Enable/disable caching in SimplePie. |
||
| 831 | * |
||
| 832 | * This option allows you to disable caching all-together in SimplePie. |
||
| 833 | * However, disabling the cache can lead to longer load times. |
||
| 834 | * |
||
| 835 | * @since 1.0 Preview Release |
||
| 836 | * @param bool $enable Enable caching |
||
| 837 | */ |
||
| 838 | public function enable_cache($enable = true) |
||
| 839 | { |
||
| 840 | $this->cache = (bool) $enable; |
||
| 841 | } |
||
| 842 | |||
| 843 | /** |
||
| 844 | * Set the length of time (in seconds) that the contents of a feed will be |
||
| 845 | * cached |
||
| 846 | * |
||
| 847 | * @param int $seconds The feed content cache duration |
||
| 848 | */ |
||
| 849 | public function set_cache_duration($seconds = 3600) |
||
| 850 | { |
||
| 851 | $this->cache_duration = (int) $seconds; |
||
| 852 | } |
||
| 853 | |||
| 854 | /** |
||
| 855 | * Set the length of time (in seconds) that the autodiscovered feed URL will |
||
| 856 | * be cached |
||
| 857 | * |
||
| 858 | * @param int $seconds The autodiscovered feed URL cache duration. |
||
| 859 | */ |
||
| 860 | public function set_autodiscovery_cache_duration($seconds = 604800) |
||
| 861 | { |
||
| 862 | $this->autodiscovery_cache_duration = (int) $seconds; |
||
| 863 | } |
||
| 864 | |||
| 865 | /** |
||
| 866 | * Set the file system location where the cached files should be stored |
||
| 867 | * |
||
| 868 | * @param string $location The file system location. |
||
| 869 | */ |
||
| 870 | public function set_cache_location($location = './cache') |
||
| 871 | { |
||
| 872 | $this->cache_location = (string) $location; |
||
| 873 | } |
||
| 874 | |||
| 875 | /** |
||
| 876 | * Set whether feed items should be sorted into reverse chronological order |
||
| 877 | * |
||
| 878 | * @param bool $enable Sort as reverse chronological order. |
||
| 879 | */ |
||
| 880 | public function enable_order_by_date($enable = true) |
||
| 881 | { |
||
| 882 | $this->order_by_date = (bool) $enable; |
||
| 883 | } |
||
| 884 | |||
| 885 | /** |
||
| 886 | * Set the character encoding used to parse the feed |
||
| 887 | * |
||
| 888 | * This overrides the encoding reported by the feed, however it will fall |
||
| 889 | * back to the normal encoding detection if the override fails |
||
| 890 | * |
||
| 891 | * @param string $encoding Character encoding |
||
| 892 | */ |
||
| 893 | public function set_input_encoding($encoding = false) |
||
| 894 | { |
||
| 895 | if ($encoding) |
||
| 896 | { |
||
| 897 | $this->input_encoding = (string) $encoding; |
||
| 898 | } |
||
| 899 | else |
||
| 900 | { |
||
| 901 | $this->input_encoding = false; |
||
| 902 | } |
||
| 903 | } |
||
| 904 | |||
| 905 | /** |
||
| 906 | * Set how much feed autodiscovery to do |
||
| 907 | * |
||
| 908 | * @see SIMPLEPIE_LOCATOR_NONE |
||
| 909 | * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY |
||
| 910 | * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION |
||
| 911 | * @see SIMPLEPIE_LOCATOR_LOCAL_BODY |
||
| 912 | * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION |
||
| 913 | * @see SIMPLEPIE_LOCATOR_REMOTE_BODY |
||
| 914 | * @see SIMPLEPIE_LOCATOR_ALL |
||
| 915 | * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator) |
||
| 916 | */ |
||
| 917 | public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) |
||
| 918 | { |
||
| 919 | $this->autodiscovery = (int) $level; |
||
| 920 | } |
||
| 921 | |||
| 922 | /** |
||
| 923 | * Get the class registry |
||
| 924 | * |
||
| 925 | * Use this to override SimplePie's default classes |
||
| 926 | * @see SimplePie_Registry |
||
| 927 | * @return SimplePie_Registry |
||
| 928 | */ |
||
| 929 | public function &get_registry() |
||
| 930 | { |
||
| 931 | return $this->registry; |
||
| 932 | } |
||
| 933 | |||
| 934 | /**#@+ |
||
| 935 | * Useful when you are overloading or extending SimplePie's default classes. |
||
| 936 | * |
||
| 937 | * @deprecated Use {@see get_registry()} instead |
||
| 938 | * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation |
||
| 939 | * @param string $class Name of custom class |
||
| 940 | * @return boolean True on success, false otherwise |
||
| 941 | */ |
||
| 942 | /** |
||
| 943 | * Set which class SimplePie uses for caching |
||
| 944 | */ |
||
| 945 | public function set_cache_class($class = 'SimplePie_Cache') |
||
| 946 | { |
||
| 947 | return $this->registry->register('Cache', $class, true); |
||
| 948 | } |
||
| 949 | |||
| 950 | /** |
||
| 951 | * Set which class SimplePie uses for auto-discovery |
||
| 952 | */ |
||
| 953 | public function set_locator_class($class = 'SimplePie_Locator') |
||
| 954 | { |
||
| 955 | return $this->registry->register('Locator', $class, true); |
||
| 956 | } |
||
| 957 | |||
| 958 | /** |
||
| 959 | * Set which class SimplePie uses for XML parsing |
||
| 960 | */ |
||
| 961 | public function set_parser_class($class = 'SimplePie_Parser') |
||
| 962 | { |
||
| 963 | return $this->registry->register('Parser', $class, true); |
||
| 964 | } |
||
| 965 | |||
| 966 | /** |
||
| 967 | * Set which class SimplePie uses for remote file fetching |
||
| 968 | */ |
||
| 969 | public function set_file_class($class = 'SimplePie_File') |
||
| 970 | { |
||
| 971 | return $this->registry->register('File', $class, true); |
||
| 972 | } |
||
| 973 | |||
| 974 | /** |
||
| 975 | * Set which class SimplePie uses for data sanitization |
||
| 976 | */ |
||
| 977 | public function set_sanitize_class($class = 'SimplePie_Sanitize') |
||
| 978 | { |
||
| 979 | return $this->registry->register('Sanitize', $class, true); |
||
| 980 | } |
||
| 981 | |||
| 982 | /** |
||
| 983 | * Set which class SimplePie uses for handling feed items |
||
| 984 | */ |
||
| 985 | public function set_item_class($class = 'SimplePie_Item') |
||
| 986 | { |
||
| 987 | return $this->registry->register('Item', $class, true); |
||
| 988 | } |
||
| 989 | |||
| 990 | /** |
||
| 991 | * Set which class SimplePie uses for handling author data |
||
| 992 | */ |
||
| 993 | public function set_author_class($class = 'SimplePie_Author') |
||
| 994 | { |
||
| 995 | return $this->registry->register('Author', $class, true); |
||
| 996 | } |
||
| 997 | |||
| 998 | /** |
||
| 999 | * Set which class SimplePie uses for handling category data |
||
| 1000 | */ |
||
| 1001 | public function set_category_class($class = 'SimplePie_Category') |
||
| 1002 | { |
||
| 1003 | return $this->registry->register('Category', $class, true); |
||
| 1004 | } |
||
| 1005 | |||
| 1006 | /** |
||
| 1007 | * Set which class SimplePie uses for feed enclosures |
||
| 1008 | */ |
||
| 1009 | public function set_enclosure_class($class = 'SimplePie_Enclosure') |
||
| 1010 | { |
||
| 1011 | return $this->registry->register('Enclosure', $class, true); |
||
| 1012 | } |
||
| 1013 | |||
| 1014 | /** |
||
| 1015 | * Set which class SimplePie uses for `<media:text>` captions |
||
| 1016 | */ |
||
| 1017 | public function set_caption_class($class = 'SimplePie_Caption') |
||
| 1018 | { |
||
| 1019 | return $this->registry->register('Caption', $class, true); |
||
| 1020 | } |
||
| 1021 | |||
| 1022 | /** |
||
| 1023 | * Set which class SimplePie uses for `<media:copyright>` |
||
| 1024 | */ |
||
| 1025 | public function set_copyright_class($class = 'SimplePie_Copyright') |
||
| 1026 | { |
||
| 1027 | return $this->registry->register('Copyright', $class, true); |
||
| 1028 | } |
||
| 1029 | |||
| 1030 | /** |
||
| 1031 | * Set which class SimplePie uses for `<media:credit>` |
||
| 1032 | */ |
||
| 1033 | public function set_credit_class($class = 'SimplePie_Credit') |
||
| 1034 | { |
||
| 1035 | return $this->registry->register('Credit', $class, true); |
||
| 1036 | } |
||
| 1037 | |||
| 1038 | /** |
||
| 1039 | * Set which class SimplePie uses for `<media:rating>` |
||
| 1040 | */ |
||
| 1041 | public function set_rating_class($class = 'SimplePie_Rating') |
||
| 1042 | { |
||
| 1043 | return $this->registry->register('Rating', $class, true); |
||
| 1044 | } |
||
| 1045 | |||
| 1046 | /** |
||
| 1047 | * Set which class SimplePie uses for `<media:restriction>` |
||
| 1048 | */ |
||
| 1049 | public function set_restriction_class($class = 'SimplePie_Restriction') |
||
| 1050 | { |
||
| 1051 | return $this->registry->register('Restriction', $class, true); |
||
| 1052 | } |
||
| 1053 | |||
| 1054 | /** |
||
| 1055 | * Set which class SimplePie uses for content-type sniffing |
||
| 1056 | */ |
||
| 1057 | public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') |
||
| 1058 | { |
||
| 1059 | return $this->registry->register('Content_Type_Sniffer', $class, true); |
||
| 1060 | } |
||
| 1061 | |||
| 1062 | /** |
||
| 1063 | * Set which class SimplePie uses item sources |
||
| 1064 | */ |
||
| 1065 | public function set_source_class($class = 'SimplePie_Source') |
||
| 1066 | { |
||
| 1067 | return $this->registry->register('Source', $class, true); |
||
| 1068 | } |
||
| 1069 | /**#@-*/ |
||
| 1070 | |||
| 1071 | /** |
||
| 1072 | * Set the user agent string |
||
| 1073 | * |
||
| 1074 | * @param string $ua New user agent string. |
||
| 1075 | */ |
||
| 1076 | public function set_useragent($ua = SIMPLEPIE_USERAGENT) |
||
| 1077 | { |
||
| 1078 | $this->useragent = (string) $ua; |
||
| 1079 | } |
||
| 1080 | |||
| 1081 | /** |
||
| 1082 | * Set callback function to create cache filename with |
||
| 1083 | * |
||
| 1084 | * @param mixed $function Callback function |
||
| 1085 | */ |
||
| 1086 | public function set_cache_name_function($function = 'md5') |
||
| 1087 | { |
||
| 1088 | if (is_callable($function)) |
||
| 1089 | { |
||
| 1090 | $this->cache_name_function = $function; |
||
| 1091 | } |
||
| 1092 | } |
||
| 1093 | |||
| 1094 | /** |
||
| 1095 | * Set options to make SP as fast as possible |
||
| 1096 | * |
||
| 1097 | * Forgoes a substantial amount of data sanitization in favor of speed. This |
||
| 1098 | * turns SimplePie into a dumb parser of feeds. |
||
| 1099 | * |
||
| 1100 | * @param bool $set Whether to set them or not |
||
| 1101 | */ |
||
| 1102 | public function set_stupidly_fast($set = false) |
||
| 1103 | { |
||
| 1104 | if ($set) |
||
| 1105 | { |
||
| 1106 | $this->enable_order_by_date(false); |
||
| 1107 | $this->remove_div(false); |
||
| 1108 | $this->strip_comments(false); |
||
| 1109 | $this->strip_htmltags(false); |
||
| 1110 | $this->strip_attributes(false); |
||
| 1111 | $this->set_image_handler(false); |
||
| 1112 | } |
||
| 1113 | } |
||
| 1114 | |||
| 1115 | /** |
||
| 1116 | * Set maximum number of feeds to check with autodiscovery |
||
| 1117 | * |
||
| 1118 | * @param int $max Maximum number of feeds to check |
||
| 1119 | */ |
||
| 1120 | public function set_max_checked_feeds($max = 10) |
||
| 1121 | { |
||
| 1122 | $this->max_checked_feeds = (int) $max; |
||
| 1123 | } |
||
| 1124 | |||
| 1125 | public function remove_div($enable = true) |
||
| 1126 | { |
||
| 1127 | $this->sanitize->remove_div($enable); |
||
| 1128 | } |
||
| 1129 | |||
| 1130 | public function strip_htmltags($tags = '', $encode = null) |
||
| 1131 | { |
||
| 1132 | if ($tags === '') |
||
| 1133 | { |
||
| 1134 | $tags = $this->strip_htmltags; |
||
| 1135 | } |
||
| 1136 | $this->sanitize->strip_htmltags($tags); |
||
| 1137 | if ($encode !== null) |
||
| 1138 | { |
||
| 1139 | $this->sanitize->encode_instead_of_strip($tags); |
||
| 1140 | } |
||
| 1141 | } |
||
| 1142 | |||
| 1143 | public function encode_instead_of_strip($enable = true) |
||
| 1144 | { |
||
| 1145 | $this->sanitize->encode_instead_of_strip($enable); |
||
| 1146 | } |
||
| 1147 | |||
| 1148 | public function strip_attributes($attribs = '') |
||
| 1149 | { |
||
| 1150 | if ($attribs === '') |
||
| 1151 | { |
||
| 1152 | $attribs = $this->strip_attributes; |
||
| 1153 | } |
||
| 1154 | $this->sanitize->strip_attributes($attribs); |
||
| 1155 | } |
||
| 1156 | |||
| 1157 | /** |
||
| 1158 | * Set the output encoding |
||
| 1159 | * |
||
| 1160 | * Allows you to override SimplePie's output to match that of your webpage. |
||
| 1161 | * This is useful for times when your webpages are not being served as |
||
| 1162 | * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and |
||
| 1163 | * is similar to {@see set_input_encoding()}. |
||
| 1164 | * |
||
| 1165 | * It should be noted, however, that not all character encodings can support |
||
| 1166 | * all characters. If your page is being served as ISO-8859-1 and you try |
||
| 1167 | * to display a Japanese feed, you'll likely see garbled characters. |
||
| 1168 | * Because of this, it is highly recommended to ensure that your webpages |
||
| 1169 | * are served as UTF-8. |
||
| 1170 | * |
||
| 1171 | * The number of supported character encodings depends on whether your web |
||
| 1172 | * host supports {@link http://php.net/mbstring mbstring}, |
||
| 1173 | * {@link http://php.net/iconv iconv}, or both. See |
||
| 1174 | * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for |
||
| 1175 | * more information. |
||
| 1176 | * |
||
| 1177 | * @param string $encoding |
||
| 1178 | */ |
||
| 1179 | public function set_output_encoding($encoding = 'UTF-8') |
||
| 1180 | { |
||
| 1181 | $this->sanitize->set_output_encoding($encoding); |
||
| 1182 | } |
||
| 1183 | |||
| 1184 | public function strip_comments($strip = false) |
||
| 1185 | { |
||
| 1186 | $this->sanitize->strip_comments($strip); |
||
| 1187 | } |
||
| 1188 | |||
| 1189 | /** |
||
| 1190 | * Set element/attribute key/value pairs of HTML attributes |
||
| 1191 | * containing URLs that need to be resolved relative to the feed |
||
| 1192 | * |
||
| 1193 | * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite, |
||
| 1194 | * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite, |
||
| 1195 | * |q|@cite |
||
| 1196 | * |
||
| 1197 | * @since 1.0 |
||
| 1198 | * @param array|null $element_attribute Element/attribute key/value pairs, null for default |
||
| 1199 | */ |
||
| 1200 | public function set_url_replacements($element_attribute = null) |
||
| 1201 | { |
||
| 1202 | $this->sanitize->set_url_replacements($element_attribute); |
||
| 1203 | } |
||
| 1204 | |||
| 1205 | /** |
||
| 1206 | * Set the handler to enable the display of cached images. |
||
| 1207 | * |
||
| 1208 | * @param str $page Web-accessible path to the handler_image.php file. |
||
| 1209 | * @param str $qs The query string that the value should be passed to. |
||
| 1210 | */ |
||
| 1211 | public function set_image_handler($page = false, $qs = 'i') |
||
| 1212 | { |
||
| 1213 | if ($page !== false) |
||
| 1214 | { |
||
| 1215 | $this->sanitize->set_image_handler($page . '?' . $qs . '='); |
||
| 1216 | } |
||
| 1217 | else |
||
| 1218 | { |
||
| 1219 | $this->image_handler = ''; |
||
| 1220 | } |
||
| 1221 | } |
||
| 1222 | |||
| 1223 | /** |
||
| 1224 | * Set the limit for items returned per-feed with multifeeds |
||
| 1225 | * |
||
| 1226 | * @param integer $limit The maximum number of items to return. |
||
| 1227 | */ |
||
| 1228 | public function set_item_limit($limit = 0) |
||
| 1229 | { |
||
| 1230 | $this->item_limit = (int) $limit; |
||
| 1231 | } |
||
| 1232 | |||
| 1233 | /** |
||
| 1234 | * Initialize the feed object |
||
| 1235 | * |
||
| 1236 | * This is what makes everything happen. Period. This is where all of the |
||
| 1237 | * configuration options get processed, feeds are fetched, cached, and |
||
| 1238 | * parsed, and all of that other good stuff. |
||
| 1239 | * |
||
| 1240 | * @return boolean True if successful, false otherwise |
||
| 1241 | */ |
||
| 1242 | public function init() |
||
| 1243 | { |
||
| 1244 | // Check absolute bare minimum requirements. |
||
| 1245 | if (!extension_loaded('xml') || !extension_loaded('pcre')) |
||
| 1246 | { |
||
| 1247 | return false; |
||
| 1248 | } |
||
| 1249 | // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader. |
||
| 1250 | elseif (!extension_loaded('xmlreader')) |
||
| 1251 | { |
||
| 1252 | static $xml_is_sane = null; |
||
| 1253 | if ($xml_is_sane === null) |
||
| 1254 | { |
||
| 1255 | $parser_check = xml_parser_create(); |
||
| 1256 | xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); |
||
| 1257 | xml_parser_free($parser_check); |
||
| 1258 | $xml_is_sane = isset($values[0]['value']); |
||
| 1259 | } |
||
| 1260 | if (!$xml_is_sane) |
||
| 1261 | { |
||
| 1262 | return false; |
||
| 1263 | } |
||
| 1264 | } |
||
| 1265 | |||
| 1266 | if (method_exists($this->sanitize, 'set_registry')) |
||
| 1267 | { |
||
| 1268 | $this->sanitize->set_registry($this->registry); |
||
| 1269 | } |
||
| 1270 | |||
| 1271 | // Pass whatever was set with config options over to the sanitizer. |
||
| 1272 | // Pass the classes in for legacy support; new classes should use the registry instead |
||
| 1273 | $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache')); |
||
| 1274 | $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen); |
||
| 1275 | |||
| 1276 | if (!empty($this->multifeed_url)) |
||
| 1277 | { |
||
| 1278 | $i = 0; |
||
| 1279 | $success = 0; |
||
| 1280 | $this->multifeed_objects = array(); |
||
| 1281 | $this->error = array(); |
||
| 1282 | foreach ($this->multifeed_url as $url) |
||
| 1283 | { |
||
| 1284 | $this->multifeed_objects[$i] = clone $this; |
||
| 1285 | $this->multifeed_objects[$i]->set_feed_url($url); |
||
| 1286 | $single_success = $this->multifeed_objects[$i]->init(); |
||
| 1287 | $success |= $single_success; |
||
| 1288 | if (!$single_success) |
||
| 1289 | { |
||
| 1290 | $this->error[$i] = $this->multifeed_objects[$i]->error(); |
||
| 1291 | } |
||
| 1292 | $i++; |
||
| 1293 | } |
||
| 1294 | return (bool) $success; |
||
| 1295 | } |
||
| 1296 | elseif ($this->feed_url === null && $this->raw_data === null) |
||
| 1297 | { |
||
| 1298 | return false; |
||
| 1299 | } |
||
| 1300 | |||
| 1301 | $this->error = null; |
||
| 1302 | $this->data = array(); |
||
| 1303 | $this->multifeed_objects = array(); |
||
| 1304 | $cache = false; |
||
| 1305 | |||
| 1306 | if ($this->feed_url !== null) |
||
| 1307 | { |
||
| 1308 | $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url)); |
||
| 1309 | |||
| 1310 | // Decide whether to enable caching |
||
| 1311 | if ($this->cache && $parsed_feed_url['scheme'] !== '') |
||
| 1312 | { |
||
| 1313 | $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc')); |
||
| 1314 | } |
||
| 1315 | |||
| 1316 | // Fetch the data via SimplePie_File into $this->raw_data |
||
| 1317 | if (($fetched = $this->fetch_data($cache)) === true) |
||
| 1318 | { |
||
| 1319 | return true; |
||
| 1320 | } |
||
| 1321 | elseif ($fetched === false) { |
||
| 1322 | return false; |
||
| 1323 | } |
||
| 1324 | |||
| 1325 | list($headers, $sniffed) = $fetched; |
||
| 1326 | } |
||
| 1327 | |||
| 1328 | // Set up array of possible encodings |
||
| 1329 | $encodings = array(); |
||
| 1330 | |||
| 1331 | // First check to see if input has been overridden. |
||
| 1332 | if ($this->input_encoding !== false) |
||
| 1333 | { |
||
| 1334 | $encodings[] = $this->input_encoding; |
||
| 1335 | } |
||
| 1336 | |||
| 1337 | $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); |
||
| 1338 | $text_types = array('text/xml', 'text/xml-external-parsed-entity'); |
||
| 1339 | |||
| 1340 | // RFC 3023 (only applies to sniffed content) |
||
| 1341 | if (isset($sniffed)) |
||
| 1342 | { |
||
| 1343 | if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') |
||
| 1344 | { |
||
| 1345 | if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) |
||
| 1346 | { |
||
| 1347 | $encodings[] = strtoupper($charset[1]); |
||
| 1348 | } |
||
| 1349 | $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry))); |
||
| 1350 | $encodings[] = 'UTF-8'; |
||
| 1351 | } |
||
| 1352 | elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') |
||
| 1353 | { |
||
| 1354 | if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) |
||
| 1355 | { |
||
| 1356 | $encodings[] = $charset[1]; |
||
| 1357 | } |
||
| 1358 | $encodings[] = 'US-ASCII'; |
||
| 1359 | } |
||
| 1360 | // Text MIME-type default |
||
| 1361 | elseif (substr($sniffed, 0, 5) === 'text/') |
||
| 1362 | { |
||
| 1363 | $encodings[] = 'US-ASCII'; |
||
| 1364 | } |
||
| 1365 | } |
||
| 1366 | |||
| 1367 | // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 |
||
| 1368 | $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry))); |
||
| 1369 | $encodings[] = 'UTF-8'; |
||
| 1370 | $encodings[] = 'ISO-8859-1'; |
||
| 1371 | |||
| 1372 | // There's no point in trying an encoding twice |
||
| 1373 | $encodings = array_unique($encodings); |
||
| 1374 | |||
| 1375 | // Loop through each possible encoding, till we return something, or run out of possibilities |
||
| 1376 | foreach ($encodings as $encoding) |
||
| 1377 | { |
||
| 1378 | // Change the encoding to UTF-8 (as we always use UTF-8 internally) |
||
| 1379 | if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8'))) |
||
| 1380 | { |
||
| 1381 | // Create new parser |
||
| 1382 | $parser = $this->registry->create('Parser'); |
||
| 1383 | |||
| 1384 | // If it's parsed fine |
||
| 1385 | if ($parser->parse($utf8_data, 'UTF-8')) |
||
| 1386 | { |
||
| 1387 | $this->data = $parser->get_data(); |
||
| 1388 | if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE)) |
||
| 1389 | { |
||
| 1390 | $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed."; |
||
| 1391 | $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); |
||
| 1392 | return false; |
||
| 1393 | } |
||
| 1394 | |||
| 1395 | if (isset($headers)) |
||
| 1396 | { |
||
| 1397 | $this->data['headers'] = $headers; |
||
| 1398 | } |
||
| 1399 | $this->data['build'] = SIMPLEPIE_BUILD; |
||
| 1400 | |||
| 1401 | // Cache the file if caching is enabled |
||
| 1402 | if ($cache && !$cache->save($this)) |
||
| 1403 | { |
||
| 1404 | 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); |
||
| 1405 | } |
||
| 1406 | return true; |
||
| 1407 | } |
||
| 1408 | } |
||
| 1409 | } |
||
| 1410 | |||
| 1411 | if (isset($parser)) |
||
| 1412 | { |
||
| 1413 | // We have an error, just set SimplePie_Misc::error to it and quit |
||
| 1414 | $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()); |
||
| 1415 | } |
||
| 1416 | else |
||
| 1417 | { |
||
| 1418 | $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.'; |
||
| 1419 | } |
||
| 1420 | |||
| 1421 | $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); |
||
| 1422 | |||
| 1423 | return false; |
||
| 1424 | } |
||
| 1425 | |||
| 1426 | /** |
||
| 1427 | * Fetch the data via SimplePie_File |
||
| 1428 | * |
||
| 1429 | * If the data is already cached, attempt to fetch it from there instead |
||
| 1430 | * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache |
||
| 1431 | * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type |
||
| 1432 | */ |
||
| 1433 | protected function fetch_data(&$cache) |
||
| 1434 | { |
||
| 1435 | // If it's enabled, use the cache |
||
| 1436 | if ($cache) |
||
| 1437 | { |
||
| 1438 | // Load the Cache |
||
| 1439 | $this->data = $cache->load(); |
||
| 1440 | if (!empty($this->data)) |
||
| 1441 | { |
||
| 1442 | // If the cache is for an outdated build of SimplePie |
||
| 1443 | if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) |
||
| 1444 | { |
||
| 1445 | $cache->unlink(); |
||
| 1446 | $this->data = array(); |
||
| 1447 | } |
||
| 1448 | // If we've hit a collision just rerun it with caching disabled |
||
| 1449 | elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) |
||
| 1450 | { |
||
| 1451 | $cache = false; |
||
| 1452 | $this->data = array(); |
||
| 1453 | } |
||
| 1454 | // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. |
||
| 1455 | elseif (isset($this->data['feed_url'])) |
||
| 1456 | { |
||
| 1457 | // If the autodiscovery cache is still valid use it. |
||
| 1458 | if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) |
||
| 1459 | { |
||
| 1460 | // Do not need to do feed autodiscovery yet. |
||
| 1461 | if ($this->data['feed_url'] !== $this->data['url']) |
||
| 1462 | { |
||
| 1463 | $this->set_feed_url($this->data['feed_url']); |
||
| 1464 | return $this->init(); |
||
| 1465 | } |
||
| 1466 | |||
| 1467 | $cache->unlink(); |
||
| 1468 | $this->data = array(); |
||
| 1469 | } |
||
| 1470 | } |
||
| 1471 | // Check if the cache has been updated |
||
| 1472 | elseif ($cache->mtime() + $this->cache_duration < time()) |
||
| 1473 | { |
||
| 1474 | // If we have last-modified and/or etag set |
||
| 1475 | if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) |
||
| 1476 | { |
||
| 1477 | $headers = array( |
||
| 1478 | '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', |
||
| 1479 | ); |
||
| 1480 | if (isset($this->data['headers']['last-modified'])) |
||
| 1481 | { |
||
| 1482 | $headers['if-modified-since'] = $this->data['headers']['last-modified']; |
||
| 1483 | } |
||
| 1484 | if (isset($this->data['headers']['etag'])) |
||
| 1485 | { |
||
| 1486 | $headers['if-none-match'] = $this->data['headers']['etag']; |
||
| 1487 | } |
||
| 1488 | |||
| 1489 | $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen)); |
||
| 1490 | |||
| 1491 | if ($file->success) |
||
| 1492 | { |
||
| 1493 | if ($file->status_code === 304) |
||
| 1494 | { |
||
| 1495 | $cache->touch(); |
||
| 1496 | return true; |
||
| 1497 | } |
||
| 1498 | } |
||
| 1499 | else |
||
| 1500 | { |
||
| 1501 | unset($file); |
||
| 1502 | } |
||
| 1503 | } |
||
| 1504 | } |
||
| 1505 | // If the cache is still valid, just return true |
||
| 1506 | else |
||
| 1507 | { |
||
| 1508 | $this->raw_data = false; |
||
| 1509 | return true; |
||
| 1510 | } |
||
| 1511 | } |
||
| 1512 | // If the cache is empty, delete it |
||
| 1513 | else |
||
| 1514 | { |
||
| 1515 | $cache->unlink(); |
||
| 1516 | $this->data = array(); |
||
| 1517 | } |
||
| 1518 | } |
||
| 1519 | // 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. |
||
| 1520 | if (!isset($file)) |
||
| 1521 | { |
||
| 1522 | if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url) |
||
| 1523 | { |
||
| 1524 | $file =& $this->file; |
||
| 1525 | } |
||
| 1526 | else |
||
| 1527 | { |
||
| 1528 | $headers = array( |
||
| 1529 | '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', |
||
| 1530 | ); |
||
| 1531 | $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen)); |
||
| 1532 | } |
||
| 1533 | } |
||
| 1534 | // If the file connection has an error, set SimplePie::error to that and quit |
||
| 1535 | if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) |
||
| 1536 | { |
||
| 1537 | $this->error = $file->error; |
||
| 1538 | return !empty($this->data); |
||
| 1539 | } |
||
| 1540 | |||
| 1541 | if (!$this->force_feed) |
||
| 1542 | { |
||
| 1543 | // Check if the supplied URL is a feed, if it isn't, look for it. |
||
| 1544 | $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds)); |
||
| 1545 | |||
| 1546 | if (!$locate->is_feed($file)) |
||
| 1547 | { |
||
| 1548 | // We need to unset this so that if SimplePie::set_file() has been called that object is untouched |
||
| 1549 | unset($file); |
||
| 1550 | try |
||
| 1551 | { |
||
| 1552 | if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))) |
||
| 1553 | { |
||
| 1554 | $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."; |
||
| 1555 | $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); |
||
| 1556 | return false; |
||
| 1557 | } |
||
| 1558 | } |
||
| 1559 | catch (SimplePie_Exception $e) |
||
| 1560 | { |
||
| 1561 | // This is usually because DOMDocument doesn't exist |
||
| 1562 | $this->error = $e->getMessage(); |
||
| 1563 | $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine())); |
||
| 1564 | return false; |
||
| 1565 | } |
||
| 1566 | if ($cache) |
||
| 1567 | { |
||
| 1568 | $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); |
||
| 1569 | if (!$cache->save($this)) |
||
| 1570 | { |
||
| 1571 | 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); |
||
| 1572 | } |
||
| 1573 | $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc')); |
||
| 1574 | } |
||
| 1575 | $this->feed_url = $file->url; |
||
| 1576 | } |
||
| 1577 | $locate = null; |
||
| 1578 | } |
||
| 1579 | |||
| 1580 | $this->raw_data = $file->body; |
||
| 1581 | |||
| 1582 | $headers = $file->headers; |
||
| 1583 | $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file)); |
||
| 1584 | $sniffed = $sniffer->get_type(); |
||
| 1585 | |||
| 1586 | return array($headers, $sniffed); |
||
| 1587 | } |
||
| 1588 | |||
| 1589 | /** |
||
| 1590 | * Get the error message for the occurred error. |
||
| 1591 | * |
||
| 1592 | * @return string|array Error message, or array of messages for multifeeds |
||
| 1593 | */ |
||
| 1594 | public function error() |
||
| 1595 | { |
||
| 1596 | return $this->error; |
||
| 1597 | } |
||
| 1598 | |||
| 1599 | /** |
||
| 1600 | * Get the raw XML |
||
| 1601 | * |
||
| 1602 | * This is the same as the old `$feed->enable_xml_dump(true)`, but returns |
||
| 1603 | * the data instead of printing it. |
||
| 1604 | * |
||
| 1605 | * @return string|boolean Raw XML data, false if the cache is used |
||
| 1606 | */ |
||
| 1607 | public function get_raw_data() |
||
| 1608 | { |
||
| 1609 | return $this->raw_data; |
||
| 1610 | } |
||
| 1611 | |||
| 1612 | /** |
||
| 1613 | * Get the character encoding used for output |
||
| 1614 | * |
||
| 1615 | * @since Preview Release |
||
| 1616 | * @return string |
||
| 1617 | */ |
||
| 1618 | public function get_encoding() |
||
| 1619 | { |
||
| 1620 | return $this->sanitize->output_encoding; |
||
| 1621 | } |
||
| 1622 | |||
| 1623 | /** |
||
| 1624 | * Send the content-type header with correct encoding |
||
| 1625 | * |
||
| 1626 | * This method ensures that the SimplePie-enabled page is being served with |
||
| 1627 | * the correct {@link http://www.iana.org/assignments/media-types/ mime-type} |
||
| 1628 | * and character encoding HTTP headers (character encoding determined by the |
||
| 1629 | * {@see set_output_encoding} config option). |
||
| 1630 | * |
||
| 1631 | * This won't work properly if any content or whitespace has already been |
||
| 1632 | * sent to the browser, because it relies on PHP's |
||
| 1633 | * {@link http://php.net/header header()} function, and these are the |
||
| 1634 | * circumstances under which the function works. |
||
| 1635 | * |
||
| 1636 | * Because it's setting these settings for the entire page (as is the nature |
||
| 1637 | * of HTTP headers), this should only be used once per page (again, at the |
||
| 1638 | * top). |
||
| 1639 | * |
||
| 1640 | * @param string $mime MIME type to serve the page as |
||
| 1641 | */ |
||
| 1642 | public function handle_content_type($mime = 'text/html') |
||
| 1643 | { |
||
| 1644 | if (!headers_sent()) |
||
| 1645 | { |
||
| 1646 | $header = "Content-type: $mime;"; |
||
| 1647 | if ($this->get_encoding()) |
||
| 1648 | { |
||
| 1649 | $header .= ' charset=' . $this->get_encoding(); |
||
| 1650 | } |
||
| 1651 | else |
||
| 1652 | { |
||
| 1653 | $header .= ' charset=UTF-8'; |
||
| 1654 | } |
||
| 1655 | header($header); |
||
| 1656 | } |
||
| 1657 | } |
||
| 1658 | |||
| 1659 | /** |
||
| 1660 | * Get the type of the feed |
||
| 1661 | * |
||
| 1662 | * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against |
||
| 1663 | * using {@link http://php.net/language.operators.bitwise bitwise operators} |
||
| 1664 | * |
||
| 1665 | * @since 0.8 (usage changed to using constants in 1.0) |
||
| 1666 | * @see SIMPLEPIE_TYPE_NONE Unknown. |
||
| 1667 | * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90. |
||
| 1668 | * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape). |
||
| 1669 | * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland). |
||
| 1670 | * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91. |
||
| 1671 | * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92. |
||
| 1672 | * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93. |
||
| 1673 | * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94. |
||
| 1674 | * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0. |
||
| 1675 | * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x. |
||
| 1676 | * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS. |
||
| 1677 | * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format). |
||
| 1678 | * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS. |
||
| 1679 | * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3. |
||
| 1680 | * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0. |
||
| 1681 | * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom. |
||
| 1682 | * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type. |
||
| 1683 | * @return int SIMPLEPIE_TYPE_* constant |
||
| 1684 | */ |
||
| 1685 | public function get_type() |
||
| 1686 | { |
||
| 1687 | if (!isset($this->data['type'])) |
||
| 1688 | { |
||
| 1689 | $this->data['type'] = SIMPLEPIE_TYPE_ALL; |
||
| 1690 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) |
||
| 1691 | { |
||
| 1692 | $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; |
||
| 1693 | } |
||
| 1694 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) |
||
| 1695 | { |
||
| 1696 | $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; |
||
| 1697 | } |
||
| 1698 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) |
||
| 1699 | { |
||
| 1700 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) |
||
| 1701 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) |
||
| 1702 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) |
||
| 1703 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) |
||
| 1704 | { |
||
| 1705 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; |
||
| 1706 | } |
||
| 1707 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) |
||
| 1708 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) |
||
| 1709 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) |
||
| 1710 | || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) |
||
| 1711 | { |
||
| 1712 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; |
||
| 1713 | } |
||
| 1714 | } |
||
| 1715 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'])) |
||
| 1716 | { |
||
| 1717 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; |
||
| 1718 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) |
||
| 1719 | { |
||
| 1720 | switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) |
||
| 1721 | { |
||
| 1722 | case '0.91': |
||
| 1723 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; |
||
| 1724 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) |
||
| 1725 | { |
||
| 1726 | switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) |
||
| 1727 | { |
||
| 1728 | case '0': |
||
| 1729 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; |
||
| 1730 | break; |
||
| 1731 | |||
| 1732 | case '24': |
||
| 1733 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; |
||
| 1734 | break; |
||
| 1735 | } |
||
| 1736 | } |
||
| 1737 | break; |
||
| 1738 | |||
| 1739 | case '0.92': |
||
| 1740 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; |
||
| 1741 | break; |
||
| 1742 | |||
| 1743 | case '0.93': |
||
| 1744 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; |
||
| 1745 | break; |
||
| 1746 | |||
| 1747 | case '0.94': |
||
| 1748 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; |
||
| 1749 | break; |
||
| 1750 | |||
| 1751 | case '2.0': |
||
| 1752 | $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; |
||
| 1753 | break; |
||
| 1754 | } |
||
| 1755 | } |
||
| 1756 | } |
||
| 1757 | else |
||
| 1758 | { |
||
| 1759 | $this->data['type'] = SIMPLEPIE_TYPE_NONE; |
||
| 1760 | } |
||
| 1761 | } |
||
| 1762 | return $this->data['type']; |
||
| 1763 | } |
||
| 1764 | |||
| 1765 | /** |
||
| 1766 | * Get the URL for the feed |
||
| 1767 | * |
||
| 1768 | * May or may not be different from the URL passed to {@see set_feed_url()}, |
||
| 1769 | * depending on whether auto-discovery was used. |
||
| 1770 | * |
||
| 1771 | * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.) |
||
| 1772 | * @todo If we have a perm redirect we should return the new URL |
||
| 1773 | * @todo When we make the above change, let's support <itunes:new-feed-url> as well |
||
| 1774 | * @todo Also, |atom:link|@rel=self |
||
| 1775 | * @return string|null |
||
| 1776 | */ |
||
| 1777 | public function subscribe_url() |
||
| 1778 | { |
||
| 1779 | if ($this->feed_url !== null) |
||
| 1780 | { |
||
| 1781 | return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); |
||
| 1782 | } |
||
| 1783 | else |
||
| 1784 | { |
||
| 1785 | return null; |
||
| 1786 | } |
||
| 1787 | } |
||
| 1788 | |||
| 1789 | /** |
||
| 1790 | * Get data for an feed-level element |
||
| 1791 | * |
||
| 1792 | * This method allows you to get access to ANY element/attribute that is a |
||
| 1793 | * sub-element of the opening feed tag. |
||
| 1794 | * |
||
| 1795 | * The return value is an indexed array of elements matching the given |
||
| 1796 | * namespace and tag name. Each element has `attribs`, `data` and `child` |
||
| 1797 | * subkeys. For `attribs` and `child`, these contain namespace subkeys. |
||
| 1798 | * `attribs` then has one level of associative name => value data (where |
||
| 1799 | * `value` is a string) after the namespace. `child` has tag-indexed keys |
||
| 1800 | * after the namespace, each member of which is an indexed array matching |
||
| 1801 | * this same format. |
||
| 1802 | * |
||
| 1803 | * For example: |
||
| 1804 | * <pre> |
||
| 1805 | * // This is probably a bad example because we already support |
||
| 1806 | * // <media:content> natively, but it shows you how to parse through |
||
| 1807 | * // the nodes. |
||
| 1808 | * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group'); |
||
| 1809 | * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']; |
||
| 1810 | * $file = $content[0]['attribs']['']['url']; |
||
| 1811 | * echo $file; |
||
| 1812 | * </pre> |
||
| 1813 | * |
||
| 1814 | * @since 1.0 |
||
| 1815 | * @see http://simplepie.org/wiki/faq/supported_xml_namespaces |
||
| 1816 | * @param string $namespace The URL of the XML namespace of the elements you're trying to access |
||
| 1817 | * @param string $tag Tag name |
||
| 1818 | * @return array |
||
| 1819 | */ |
||
| 1820 | public function get_feed_tags($namespace, $tag) |
||
| 1821 | { |
||
| 1822 | $type = $this->get_type(); |
||
| 1823 | if ($type & SIMPLEPIE_TYPE_ATOM_10) |
||
| 1824 | { |
||
| 1825 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) |
||
| 1826 | { |
||
| 1827 | return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; |
||
| 1828 | } |
||
| 1829 | } |
||
| 1830 | if ($type & SIMPLEPIE_TYPE_ATOM_03) |
||
| 1831 | { |
||
| 1832 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) |
||
| 1833 | { |
||
| 1834 | return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; |
||
| 1835 | } |
||
| 1836 | } |
||
| 1837 | if ($type & SIMPLEPIE_TYPE_RSS_RDF) |
||
| 1838 | { |
||
| 1839 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) |
||
| 1840 | { |
||
| 1841 | return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; |
||
| 1842 | } |
||
| 1843 | } |
||
| 1844 | if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) |
||
| 1845 | { |
||
| 1846 | if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag])) |
||
| 1847 | { |
||
| 1848 | return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]; |
||
| 1849 | } |
||
| 1850 | } |
||
| 1851 | return null; |
||
| 1852 | } |
||
| 1853 | |||
| 1854 | /** |
||
| 1855 | * Get data for an channel-level element |
||
| 1856 | * |
||
| 1857 | * This method allows you to get access to ANY element/attribute in the |
||
| 1858 | * channel/header section of the feed. |
||
| 1859 | * |
||
| 1860 | * See {@see SimplePie::get_feed_tags()} for a description of the return value |
||
| 1861 | * |
||
| 1862 | * @since 1.0 |
||
| 1863 | * @see http://simplepie.org/wiki/faq/supported_xml_namespaces |
||
| 1864 | * @param string $namespace The URL of the XML namespace of the elements you're trying to access |
||
| 1865 | * @param string $tag Tag name |
||
| 1866 | * @return array |
||
| 1867 | */ |
||
| 1868 | public function get_channel_tags($namespace, $tag) |
||
| 1869 | { |
||
| 1870 | $type = $this->get_type(); |
||
| 1871 | if ($type & SIMPLEPIE_TYPE_ATOM_ALL) |
||
| 1872 | { |
||
| 1873 | if ($return = $this->get_feed_tags($namespace, $tag)) |
||
| 1874 | { |
||
| 1875 | return $return; |
||
| 1876 | } |
||
| 1877 | } |
||
| 1878 | if ($type & SIMPLEPIE_TYPE_RSS_10) |
||
| 1879 | { |
||
| 1880 | if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) |
||
| 1881 | { |
||
| 1882 | if (isset($channel[0]['child'][$namespace][$tag])) |
||
| 1883 | { |
||
| 1884 | return $channel[0]['child'][$namespace][$tag]; |
||
| 1885 | } |
||
| 1886 | } |
||
| 1887 | } |
||
| 1888 | if ($type & SIMPLEPIE_TYPE_RSS_090) |
||
| 1889 | { |
||
| 1890 | if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) |
||
| 1891 | { |
||
| 1892 | if (isset($channel[0]['child'][$namespace][$tag])) |
||
| 1893 | { |
||
| 1894 | return $channel[0]['child'][$namespace][$tag]; |
||
| 1895 | } |
||
| 1896 | } |
||
| 1897 | } |
||
| 1898 | if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) |
||
| 1899 | { |
||
| 1900 | if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel')) |
||
| 1901 | { |
||
| 1902 | if (isset($channel[0]['child'][$namespace][$tag])) |
||
| 1903 | { |
||
| 1904 | return $channel[0]['child'][$namespace][$tag]; |
||
| 1905 | } |
||
| 1906 | } |
||
| 1907 | } |
||
| 1908 | return null; |
||
| 1909 | } |
||
| 1910 | |||
| 1911 | /** |
||
| 1912 | * Get data for an channel-level element |
||
| 1913 | * |
||
| 1914 | * This method allows you to get access to ANY element/attribute in the |
||
| 1915 | * image/logo section of the feed. |
||
| 1916 | * |
||
| 1917 | * See {@see SimplePie::get_feed_tags()} for a description of the return value |
||
| 1918 | * |
||
| 1919 | * @since 1.0 |
||
| 1920 | * @see http://simplepie.org/wiki/faq/supported_xml_namespaces |
||
| 1921 | * @param string $namespace The URL of the XML namespace of the elements you're trying to access |
||
| 1922 | * @param string $tag Tag name |
||
| 1923 | * @return array |
||
| 1924 | */ |
||
| 1925 | public function get_image_tags($namespace, $tag) |
||
| 1926 | { |
||
| 1927 | $type = $this->get_type(); |
||
| 1928 | if ($type & SIMPLEPIE_TYPE_RSS_10) |
||
| 1929 | { |
||
| 1930 | if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) |
||
| 1931 | { |
||
| 1932 | if (isset($image[0]['child'][$namespace][$tag])) |
||
| 1933 | { |
||
| 1934 | return $image[0]['child'][$namespace][$tag]; |
||
| 1935 | } |
||
| 1936 | } |
||
| 1937 | } |
||
| 1938 | if ($type & SIMPLEPIE_TYPE_RSS_090) |
||
| 1939 | { |
||
| 1940 | if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) |
||
| 1941 | { |
||
| 1942 | if (isset($image[0]['child'][$namespace][$tag])) |
||
| 1943 | { |
||
| 1944 | return $image[0]['child'][$namespace][$tag]; |
||
| 1945 | } |
||
| 1946 | } |
||
| 1947 | } |
||
| 1948 | if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) |
||
| 1949 | { |
||
| 1950 | if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image')) |
||
| 1951 | { |
||
| 1952 | if (isset($image[0]['child'][$namespace][$tag])) |
||
| 1953 | { |
||
| 1954 | return $image[0]['child'][$namespace][$tag]; |
||
| 1955 | } |
||
| 1956 | } |
||
| 1957 | } |
||
| 1958 | return null; |
||
| 1959 | } |
||
| 1960 | |||
| 1961 | /** |
||
| 1962 | * Get the base URL value from the feed |
||
| 1963 | * |
||
| 1964 | * Uses `<xml:base>` if available, otherwise uses the first link in the |
||
| 1965 | * feed, or failing that, the URL of the feed itself. |
||
| 1966 | * |
||
| 1967 | * @see get_link |
||
| 1968 | * @see subscribe_url |
||
| 1969 | * |
||
| 1970 | * @param array $element |
||
| 1971 | * @return string |
||
| 1972 | */ |
||
| 1973 | public function get_base($element = array()) |
||
| 1974 | { |
||
| 1975 | if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) |
||
| 1976 | { |
||
| 1977 | return $element['xml_base']; |
||
| 1978 | } |
||
| 1979 | elseif ($this->get_link() !== null) |
||
| 1980 | { |
||
| 1981 | return $this->get_link(); |
||
| 1982 | } |
||
| 1983 | else |
||
| 1984 | { |
||
| 1985 | return $this->subscribe_url(); |
||
| 1986 | } |
||
| 1987 | } |
||
| 1988 | |||
| 1989 | /** |
||
| 1990 | * Sanitize feed data |
||
| 1991 | * |
||
| 1992 | * @access private |
||
| 1993 | * @see SimplePie_Sanitize::sanitize() |
||
| 1994 | * @param string $data Data to sanitize |
||
| 1995 | * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants |
||
| 1996 | * @param string $base Base URL to resolve URLs against |
||
| 1997 | * @return string Sanitized data |
||
| 1998 | */ |
||
| 1999 | public function sanitize($data, $type, $base = '') |
||
| 2000 | { |
||
| 2001 | return $this->sanitize->sanitize($data, $type, $base); |
||
| 2002 | } |
||
| 2003 | |||
| 2004 | /** |
||
| 2005 | * Get the title of the feed |
||
| 2006 | * |
||
| 2007 | * Uses `<atom:title>`, `<title>` or `<dc:title>` |
||
| 2008 | * |
||
| 2009 | * @since 1.0 (previously called `get_feed_title` since 0.8) |
||
| 2010 | * @return string|null |
||
| 2011 | */ |
||
| 2012 | public function get_title() |
||
| 2013 | { |
||
| 2014 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) |
||
| 2015 | { |
||
| 2016 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2017 | } |
||
| 2018 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) |
||
| 2019 | { |
||
| 2020 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2021 | } |
||
| 2022 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) |
||
| 2023 | { |
||
| 2024 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); |
||
| 2025 | } |
||
| 2026 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) |
||
| 2027 | { |
||
| 2028 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); |
||
| 2029 | } |
||
| 2030 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) |
||
| 2031 | { |
||
| 2032 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); |
||
| 2033 | } |
||
| 2034 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) |
||
| 2035 | { |
||
| 2036 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2037 | } |
||
| 2038 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) |
||
| 2039 | { |
||
| 2040 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2041 | } |
||
| 2042 | else |
||
| 2043 | { |
||
| 2044 | return null; |
||
| 2045 | } |
||
| 2046 | } |
||
| 2047 | |||
| 2048 | /** |
||
| 2049 | * Get a category for the feed |
||
| 2050 | * |
||
| 2051 | * @since Unknown |
||
| 2052 | * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1 |
||
| 2053 | * @return SimplePie_Category|null |
||
| 2054 | */ |
||
| 2055 | public function get_category($key = 0) |
||
| 2056 | { |
||
| 2057 | $categories = $this->get_categories(); |
||
| 2058 | if (isset($categories[$key])) |
||
| 2059 | { |
||
| 2060 | return $categories[$key]; |
||
| 2061 | } |
||
| 2062 | else |
||
| 2063 | { |
||
| 2064 | return null; |
||
| 2065 | } |
||
| 2066 | } |
||
| 2067 | |||
| 2068 | /** |
||
| 2069 | * Get all categories for the feed |
||
| 2070 | * |
||
| 2071 | * Uses `<atom:category>`, `<category>` or `<dc:subject>` |
||
| 2072 | * |
||
| 2073 | * @since Unknown |
||
| 2074 | * @return array|null List of {@see SimplePie_Category} objects |
||
| 2075 | */ |
||
| 2076 | public function get_categories() |
||
| 2077 | { |
||
| 2078 | $categories = array(); |
||
| 2079 | |||
| 2080 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) |
||
| 2081 | { |
||
| 2082 | $term = null; |
||
| 2083 | $scheme = null; |
||
| 2084 | $label = null; |
||
| 2085 | if (isset($category['attribs']['']['term'])) |
||
| 2086 | { |
||
| 2087 | $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2088 | } |
||
| 2089 | if (isset($category['attribs']['']['scheme'])) |
||
| 2090 | { |
||
| 2091 | $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2092 | } |
||
| 2093 | if (isset($category['attribs']['']['label'])) |
||
| 2094 | { |
||
| 2095 | $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2096 | } |
||
| 2097 | $categories[] = $this->registry->create('Category', array($term, $scheme, $label)); |
||
| 2098 | } |
||
| 2099 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) |
||
| 2100 | { |
||
| 2101 | // This is really the label, but keep this as the term also for BC. |
||
| 2102 | // Label will also work on retrieving because that falls back to term. |
||
| 2103 | $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2104 | if (isset($category['attribs']['']['domain'])) |
||
| 2105 | { |
||
| 2106 | $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2107 | } |
||
| 2108 | else |
||
| 2109 | { |
||
| 2110 | $scheme = null; |
||
| 2111 | } |
||
| 2112 | $categories[] = $this->registry->create('Category', array($term, $scheme, null)); |
||
| 2113 | } |
||
| 2114 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) |
||
| 2115 | { |
||
| 2116 | $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); |
||
| 2117 | } |
||
| 2118 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) |
||
| 2119 | { |
||
| 2120 | $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); |
||
| 2121 | } |
||
| 2122 | |||
| 2123 | if (!empty($categories)) |
||
| 2124 | { |
||
| 2125 | return array_unique($categories); |
||
| 2126 | } |
||
| 2127 | else |
||
| 2128 | { |
||
| 2129 | return null; |
||
| 2130 | } |
||
| 2131 | } |
||
| 2132 | |||
| 2133 | /** |
||
| 2134 | * Get an author for the feed |
||
| 2135 | * |
||
| 2136 | * @since 1.1 |
||
| 2137 | * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1 |
||
| 2138 | * @return SimplePie_Author|null |
||
| 2139 | */ |
||
| 2140 | public function get_author($key = 0) |
||
| 2141 | { |
||
| 2142 | $authors = $this->get_authors(); |
||
| 2143 | if (isset($authors[$key])) |
||
| 2144 | { |
||
| 2145 | return $authors[$key]; |
||
| 2146 | } |
||
| 2147 | else |
||
| 2148 | { |
||
| 2149 | return null; |
||
| 2150 | } |
||
| 2151 | } |
||
| 2152 | |||
| 2153 | /** |
||
| 2154 | * Get all authors for the feed |
||
| 2155 | * |
||
| 2156 | * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>` |
||
| 2157 | * |
||
| 2158 | * @since 1.1 |
||
| 2159 | * @return array|null List of {@see SimplePie_Author} objects |
||
| 2160 | */ |
||
| 2161 | public function get_authors() |
||
| 2162 | { |
||
| 2163 | $authors = array(); |
||
| 2164 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) |
||
| 2165 | { |
||
| 2166 | $name = null; |
||
| 2167 | $uri = null; |
||
| 2168 | $email = null; |
||
| 2169 | if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) |
||
| 2170 | { |
||
| 2171 | $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2172 | } |
||
| 2173 | if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) |
||
| 2174 | { |
||
| 2175 | $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])); |
||
| 2176 | } |
||
| 2177 | if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) |
||
| 2178 | { |
||
| 2179 | $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2180 | } |
||
| 2181 | if ($name !== null || $email !== null || $uri !== null) |
||
| 2182 | { |
||
| 2183 | $authors[] = $this->registry->create('Author', array($name, $uri, $email)); |
||
| 2184 | } |
||
| 2185 | } |
||
| 2186 | if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) |
||
| 2187 | { |
||
| 2188 | $name = null; |
||
| 2189 | $url = null; |
||
| 2190 | $email = null; |
||
| 2191 | if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) |
||
| 2192 | { |
||
| 2193 | $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2194 | } |
||
| 2195 | if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) |
||
| 2196 | { |
||
| 2197 | $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])); |
||
| 2198 | } |
||
| 2199 | if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) |
||
| 2200 | { |
||
| 2201 | $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2202 | } |
||
| 2203 | if ($name !== null || $email !== null || $url !== null) |
||
| 2204 | { |
||
| 2205 | $authors[] = $this->registry->create('Author', array($name, $url, $email)); |
||
| 2206 | } |
||
| 2207 | } |
||
| 2208 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) |
||
| 2209 | { |
||
| 2210 | $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); |
||
| 2211 | } |
||
| 2212 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) |
||
| 2213 | { |
||
| 2214 | $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); |
||
| 2215 | } |
||
| 2216 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) |
||
| 2217 | { |
||
| 2218 | $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); |
||
| 2219 | } |
||
| 2220 | |||
| 2221 | if (!empty($authors)) |
||
| 2222 | { |
||
| 2223 | return array_unique($authors); |
||
| 2224 | } |
||
| 2225 | else |
||
| 2226 | { |
||
| 2227 | return null; |
||
| 2228 | } |
||
| 2229 | } |
||
| 2230 | |||
| 2231 | /** |
||
| 2232 | * Get a contributor for the feed |
||
| 2233 | * |
||
| 2234 | * @since 1.1 |
||
| 2235 | * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1 |
||
| 2236 | * @return SimplePie_Author|null |
||
| 2237 | */ |
||
| 2238 | public function get_contributor($key = 0) |
||
| 2239 | { |
||
| 2240 | $contributors = $this->get_contributors(); |
||
| 2241 | if (isset($contributors[$key])) |
||
| 2242 | { |
||
| 2243 | return $contributors[$key]; |
||
| 2244 | } |
||
| 2245 | else |
||
| 2246 | { |
||
| 2247 | return null; |
||
| 2248 | } |
||
| 2249 | } |
||
| 2250 | |||
| 2251 | /** |
||
| 2252 | * Get all contributors for the feed |
||
| 2253 | * |
||
| 2254 | * Uses `<atom:contributor>` |
||
| 2255 | * |
||
| 2256 | * @since 1.1 |
||
| 2257 | * @return array|null List of {@see SimplePie_Author} objects |
||
| 2258 | */ |
||
| 2259 | public function get_contributors() |
||
| 2260 | { |
||
| 2261 | $contributors = array(); |
||
| 2262 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) |
||
| 2263 | { |
||
| 2264 | $name = null; |
||
| 2265 | $uri = null; |
||
| 2266 | $email = null; |
||
| 2267 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) |
||
| 2268 | { |
||
| 2269 | $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2270 | } |
||
| 2271 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) |
||
| 2272 | { |
||
| 2273 | $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])); |
||
| 2274 | } |
||
| 2275 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) |
||
| 2276 | { |
||
| 2277 | $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2278 | } |
||
| 2279 | if ($name !== null || $email !== null || $uri !== null) |
||
| 2280 | { |
||
| 2281 | $contributors[] = $this->registry->create('Author', array($name, $uri, $email)); |
||
| 2282 | } |
||
| 2283 | } |
||
| 2284 | foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) |
||
| 2285 | { |
||
| 2286 | $name = null; |
||
| 2287 | $url = null; |
||
| 2288 | $email = null; |
||
| 2289 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) |
||
| 2290 | { |
||
| 2291 | $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2292 | } |
||
| 2293 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) |
||
| 2294 | { |
||
| 2295 | $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])); |
||
| 2296 | } |
||
| 2297 | if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) |
||
| 2298 | { |
||
| 2299 | $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2300 | } |
||
| 2301 | if ($name !== null || $email !== null || $url !== null) |
||
| 2302 | { |
||
| 2303 | $contributors[] = $this->registry->create('Author', array($name, $url, $email)); |
||
| 2304 | } |
||
| 2305 | } |
||
| 2306 | |||
| 2307 | if (!empty($contributors)) |
||
| 2308 | { |
||
| 2309 | return array_unique($contributors); |
||
| 2310 | } |
||
| 2311 | else |
||
| 2312 | { |
||
| 2313 | return null; |
||
| 2314 | } |
||
| 2315 | } |
||
| 2316 | |||
| 2317 | /** |
||
| 2318 | * Get a single link for the feed |
||
| 2319 | * |
||
| 2320 | * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8) |
||
| 2321 | * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1 |
||
| 2322 | * @param string $rel The relationship of the link to return |
||
| 2323 | * @return string|null Link URL |
||
| 2324 | */ |
||
| 2325 | public function get_link($key = 0, $rel = 'alternate') |
||
| 2326 | { |
||
| 2327 | $links = $this->get_links($rel); |
||
| 2328 | if (isset($links[$key])) |
||
| 2329 | { |
||
| 2330 | return $links[$key]; |
||
| 2331 | } |
||
| 2332 | else |
||
| 2333 | { |
||
| 2334 | return null; |
||
| 2335 | } |
||
| 2336 | } |
||
| 2337 | |||
| 2338 | /** |
||
| 2339 | * Get the permalink for the item |
||
| 2340 | * |
||
| 2341 | * Returns the first link available with a relationship of "alternate". |
||
| 2342 | * Identical to {@see get_link()} with key 0 |
||
| 2343 | * |
||
| 2344 | * @see get_link |
||
| 2345 | * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8) |
||
| 2346 | * @internal Added for parity between the parent-level and the item/entry-level. |
||
| 2347 | * @return string|null Link URL |
||
| 2348 | */ |
||
| 2349 | public function get_permalink() |
||
| 2350 | { |
||
| 2351 | return $this->get_link(0); |
||
| 2352 | } |
||
| 2353 | |||
| 2354 | /** |
||
| 2355 | * Get all links for the feed |
||
| 2356 | * |
||
| 2357 | * Uses `<atom:link>` or `<link>` |
||
| 2358 | * |
||
| 2359 | * @since Beta 2 |
||
| 2360 | * @param string $rel The relationship of links to return |
||
| 2361 | * @return array|null Links found for the feed (strings) |
||
| 2362 | */ |
||
| 2363 | public function get_links($rel = 'alternate') |
||
| 2364 | { |
||
| 2365 | if (!isset($this->data['links'])) |
||
| 2366 | { |
||
| 2367 | $this->data['links'] = array(); |
||
| 2368 | if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) |
||
| 2369 | { |
||
| 2370 | foreach ($links as $link) |
||
| 2371 | { |
||
| 2372 | if (isset($link['attribs']['']['href'])) |
||
| 2373 | { |
||
| 2374 | $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; |
||
| 2375 | $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); |
||
| 2376 | } |
||
| 2377 | } |
||
| 2378 | } |
||
| 2379 | if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) |
||
| 2380 | { |
||
| 2381 | foreach ($links as $link) |
||
| 2382 | { |
||
| 2383 | if (isset($link['attribs']['']['href'])) |
||
| 2384 | { |
||
| 2385 | $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; |
||
| 2386 | $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); |
||
| 2387 | |||
| 2388 | } |
||
| 2389 | } |
||
| 2390 | } |
||
| 2391 | if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) |
||
| 2392 | { |
||
| 2393 | $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); |
||
| 2394 | } |
||
| 2395 | if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) |
||
| 2396 | { |
||
| 2397 | $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); |
||
| 2398 | } |
||
| 2399 | if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) |
||
| 2400 | { |
||
| 2401 | $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); |
||
| 2402 | } |
||
| 2403 | |||
| 2404 | $keys = array_keys($this->data['links']); |
||
| 2405 | foreach ($keys as $key) |
||
| 2406 | { |
||
| 2407 | if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key))) |
||
| 2408 | { |
||
| 2409 | if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) |
||
| 2410 | { |
||
| 2411 | $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); |
||
| 2412 | $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; |
||
| 2413 | } |
||
| 2414 | else |
||
| 2415 | { |
||
| 2416 | $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; |
||
| 2417 | } |
||
| 2418 | } |
||
| 2419 | elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) |
||
| 2420 | { |
||
| 2421 | $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; |
||
| 2422 | } |
||
| 2423 | $this->data['links'][$key] = array_unique($this->data['links'][$key]); |
||
| 2424 | } |
||
| 2425 | } |
||
| 2426 | |||
| 2427 | if (isset($this->data['links'][$rel])) |
||
| 2428 | { |
||
| 2429 | return $this->data['links'][$rel]; |
||
| 2430 | } |
||
| 2431 | else |
||
| 2432 | { |
||
| 2433 | return null; |
||
| 2434 | } |
||
| 2435 | } |
||
| 2436 | |||
| 2437 | public function get_all_discovered_feeds() |
||
| 2438 | { |
||
| 2439 | return $this->all_discovered_feeds; |
||
| 2440 | } |
||
| 2441 | |||
| 2442 | /** |
||
| 2443 | * Get the content for the item |
||
| 2444 | * |
||
| 2445 | * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`, |
||
| 2446 | * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>` |
||
| 2447 | * |
||
| 2448 | * @since 1.0 (previously called `get_feed_description()` since 0.8) |
||
| 2449 | * @return string|null |
||
| 2450 | */ |
||
| 2451 | public function get_description() |
||
| 2452 | { |
||
| 2453 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) |
||
| 2454 | { |
||
| 2455 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2456 | } |
||
| 2457 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) |
||
| 2458 | { |
||
| 2459 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2460 | } |
||
| 2461 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) |
||
| 2462 | { |
||
| 2463 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); |
||
| 2464 | } |
||
| 2465 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) |
||
| 2466 | { |
||
| 2467 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); |
||
| 2468 | } |
||
| 2469 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) |
||
| 2470 | { |
||
| 2471 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); |
||
| 2472 | } |
||
| 2473 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) |
||
| 2474 | { |
||
| 2475 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2476 | } |
||
| 2477 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) |
||
| 2478 | { |
||
| 2479 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2480 | } |
||
| 2481 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) |
||
| 2482 | { |
||
| 2483 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); |
||
| 2484 | } |
||
| 2485 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) |
||
| 2486 | { |
||
| 2487 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); |
||
| 2488 | } |
||
| 2489 | else |
||
| 2490 | { |
||
| 2491 | return null; |
||
| 2492 | } |
||
| 2493 | } |
||
| 2494 | |||
| 2495 | /** |
||
| 2496 | * Get the copyright info for the feed |
||
| 2497 | * |
||
| 2498 | * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>` |
||
| 2499 | * |
||
| 2500 | * @since 1.0 (previously called `get_feed_copyright()` since 0.8) |
||
| 2501 | * @return string|null |
||
| 2502 | */ |
||
| 2503 | public function get_copyright() |
||
| 2504 | { |
||
| 2505 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) |
||
| 2506 | { |
||
| 2507 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2508 | } |
||
| 2509 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) |
||
| 2510 | { |
||
| 2511 | return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0])); |
||
| 2512 | } |
||
| 2513 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) |
||
| 2514 | { |
||
| 2515 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2516 | } |
||
| 2517 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) |
||
| 2518 | { |
||
| 2519 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2520 | } |
||
| 2521 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) |
||
| 2522 | { |
||
| 2523 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2524 | } |
||
| 2525 | else |
||
| 2526 | { |
||
| 2527 | return null; |
||
| 2528 | } |
||
| 2529 | } |
||
| 2530 | |||
| 2531 | /** |
||
| 2532 | * Get the language for the feed |
||
| 2533 | * |
||
| 2534 | * Uses `<language>`, `<dc:language>`, or @xml_lang |
||
| 2535 | * |
||
| 2536 | * @since 1.0 (previously called `get_feed_language()` since 0.8) |
||
| 2537 | * @return string|null |
||
| 2538 | */ |
||
| 2539 | public function get_language() |
||
| 2540 | { |
||
| 2541 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) |
||
| 2542 | { |
||
| 2543 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2544 | } |
||
| 2545 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) |
||
| 2546 | { |
||
| 2547 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2548 | } |
||
| 2549 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) |
||
| 2550 | { |
||
| 2551 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2552 | } |
||
| 2553 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) |
||
| 2554 | { |
||
| 2555 | return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2556 | } |
||
| 2557 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) |
||
| 2558 | { |
||
| 2559 | return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2560 | } |
||
| 2561 | elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) |
||
| 2562 | { |
||
| 2563 | return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2564 | } |
||
| 2565 | elseif (isset($this->data['headers']['content-language'])) |
||
| 2566 | { |
||
| 2567 | return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2568 | } |
||
| 2569 | else |
||
| 2570 | { |
||
| 2571 | return null; |
||
| 2572 | } |
||
| 2573 | } |
||
| 2574 | |||
| 2575 | /** |
||
| 2576 | * Get the latitude coordinates for the item |
||
| 2577 | * |
||
| 2578 | * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications |
||
| 2579 | * |
||
| 2580 | * Uses `<geo:lat>` or `<georss:point>` |
||
| 2581 | * |
||
| 2582 | * @since 1.0 |
||
| 2583 | * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo |
||
| 2584 | * @link http://www.georss.org/ GeoRSS |
||
| 2585 | * @return string|null |
||
| 2586 | */ |
||
| 2587 | public function get_latitude() |
||
| 2588 | { |
||
| 2589 | |||
| 2590 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) |
||
| 2591 | { |
||
| 2592 | return (float) $return[0]['data']; |
||
| 2593 | } |
||
| 2594 | elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) |
||
| 2595 | { |
||
| 2596 | return (float) $match[1]; |
||
| 2597 | } |
||
| 2598 | else |
||
| 2599 | { |
||
| 2600 | return null; |
||
| 2601 | } |
||
| 2602 | } |
||
| 2603 | |||
| 2604 | /** |
||
| 2605 | * Get the longitude coordinates for the feed |
||
| 2606 | * |
||
| 2607 | * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications |
||
| 2608 | * |
||
| 2609 | * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>` |
||
| 2610 | * |
||
| 2611 | * @since 1.0 |
||
| 2612 | * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo |
||
| 2613 | * @link http://www.georss.org/ GeoRSS |
||
| 2614 | * @return string|null |
||
| 2615 | */ |
||
| 2616 | public function get_longitude() |
||
| 2617 | { |
||
| 2618 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) |
||
| 2619 | { |
||
| 2620 | return (float) $return[0]['data']; |
||
| 2621 | } |
||
| 2622 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) |
||
| 2623 | { |
||
| 2624 | return (float) $return[0]['data']; |
||
| 2625 | } |
||
| 2626 | elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) |
||
| 2627 | { |
||
| 2628 | return (float) $match[2]; |
||
| 2629 | } |
||
| 2630 | else |
||
| 2631 | { |
||
| 2632 | return null; |
||
| 2633 | } |
||
| 2634 | } |
||
| 2635 | |||
| 2636 | /** |
||
| 2637 | * Get the feed logo's title |
||
| 2638 | * |
||
| 2639 | * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title. |
||
| 2640 | * |
||
| 2641 | * Uses `<image><title>` or `<image><dc:title>` |
||
| 2642 | * |
||
| 2643 | * @return string|null |
||
| 2644 | */ |
||
| 2645 | public function get_image_title() |
||
| 2646 | { |
||
| 2647 | if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) |
||
| 2648 | { |
||
| 2649 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2650 | } |
||
| 2651 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) |
||
| 2652 | { |
||
| 2653 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2654 | } |
||
| 2655 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) |
||
| 2656 | { |
||
| 2657 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2658 | } |
||
| 2659 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) |
||
| 2660 | { |
||
| 2661 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2662 | } |
||
| 2663 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) |
||
| 2664 | { |
||
| 2665 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); |
||
| 2666 | } |
||
| 2667 | else |
||
| 2668 | { |
||
| 2669 | return null; |
||
| 2670 | } |
||
| 2671 | } |
||
| 2672 | |||
| 2673 | /** |
||
| 2674 | * Get the feed logo's URL |
||
| 2675 | * |
||
| 2676 | * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to |
||
| 2677 | * have a "feed logo" URL. This points directly to the image itself. |
||
| 2678 | * |
||
| 2679 | * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`, |
||
| 2680 | * `<image><title>` or `<image><dc:title>` |
||
| 2681 | * |
||
| 2682 | * @return string|null |
||
| 2683 | */ |
||
| 2684 | public function get_image_url() |
||
| 2685 | { |
||
| 2686 | if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) |
||
| 2687 | { |
||
| 2688 | return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); |
||
| 2689 | } |
||
| 2690 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) |
||
| 2691 | { |
||
| 2692 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2693 | } |
||
| 2694 | elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) |
||
| 2695 | { |
||
| 2696 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2697 | } |
||
| 2698 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) |
||
| 2699 | { |
||
| 2700 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2701 | } |
||
| 2702 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) |
||
| 2703 | { |
||
| 2704 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2705 | } |
||
| 2706 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) |
||
| 2707 | { |
||
| 2708 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2709 | } |
||
| 2710 | else |
||
| 2711 | { |
||
| 2712 | return null; |
||
| 2713 | } |
||
| 2714 | } |
||
| 2715 | |||
| 2716 | |||
| 2717 | /** |
||
| 2718 | * Get the feed logo's link |
||
| 2719 | * |
||
| 2720 | * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This |
||
| 2721 | * points to a human-readable page that the image should link to. |
||
| 2722 | * |
||
| 2723 | * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`, |
||
| 2724 | * `<image><title>` or `<image><dc:title>` |
||
| 2725 | * |
||
| 2726 | * @return string|null |
||
| 2727 | */ |
||
| 2728 | public function get_image_link() |
||
| 2729 | { |
||
| 2730 | if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) |
||
| 2731 | { |
||
| 2732 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2733 | } |
||
| 2734 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) |
||
| 2735 | { |
||
| 2736 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2737 | } |
||
| 2738 | elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) |
||
| 2739 | { |
||
| 2740 | return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); |
||
| 2741 | } |
||
| 2742 | else |
||
| 2743 | { |
||
| 2744 | return null; |
||
| 2745 | } |
||
| 2746 | } |
||
| 2747 | |||
| 2748 | /** |
||
| 2749 | * Get the feed logo's link |
||
| 2750 | * |
||
| 2751 | * RSS 2.0 feeds are allowed to have a "feed logo" width. |
||
| 2752 | * |
||
| 2753 | * Uses `<image><width>` or defaults to 88.0 if no width is specified and |
||
| 2754 | * the feed is an RSS 2.0 feed. |
||
| 2755 | * |
||
| 2756 | * @return int|float|null |
||
| 2757 | */ |
||
| 2758 | public function get_image_width() |
||
| 2759 | { |
||
| 2760 | if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width')) |
||
| 2761 | { |
||
| 2762 | return round($return[0]['data']); |
||
| 2763 | } |
||
| 2764 | elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) |
||
| 2765 | { |
||
| 2766 | return 88.0; |
||
| 2767 | } |
||
| 2768 | else |
||
| 2769 | { |
||
| 2770 | return null; |
||
| 2771 | } |
||
| 2772 | } |
||
| 2773 | |||
| 2774 | /** |
||
| 2775 | * Get the feed logo's height |
||
| 2776 | * |
||
| 2777 | * RSS 2.0 feeds are allowed to have a "feed logo" height. |
||
| 2778 | * |
||
| 2779 | * Uses `<image><height>` or defaults to 31.0 if no height is specified and |
||
| 2780 | * the feed is an RSS 2.0 feed. |
||
| 2781 | * |
||
| 2782 | * @return int|float|null |
||
| 2783 | */ |
||
| 2784 | public function get_image_height() |
||
| 2785 | { |
||
| 2786 | if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height')) |
||
| 2787 | { |
||
| 2788 | return round($return[0]['data']); |
||
| 2789 | } |
||
| 2790 | elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) |
||
| 2791 | { |
||
| 2792 | return 31.0; |
||
| 2793 | } |
||
| 2794 | else |
||
| 2795 | { |
||
| 2796 | return null; |
||
| 2797 | } |
||
| 2798 | } |
||
| 2799 | |||
| 2800 | /** |
||
| 2801 | * Get the number of items in the feed |
||
| 2802 | * |
||
| 2803 | * This is well-suited for {@link http://php.net/for for()} loops with |
||
| 2804 | * {@see get_item()} |
||
| 2805 | * |
||
| 2806 | * @param int $max Maximum value to return. 0 for no limit |
||
| 2807 | * @return int Number of items in the feed |
||
| 2808 | */ |
||
| 2809 | public function get_item_quantity($max = 0) |
||
| 2810 | { |
||
| 2811 | $max = (int) $max; |
||
| 2812 | $qty = count($this->get_items()); |
||
| 2813 | if ($max === 0) |
||
| 2814 | { |
||
| 2815 | return $qty; |
||
| 2816 | } |
||
| 2817 | else |
||
| 2818 | { |
||
| 2819 | return ($qty > $max) ? $max : $qty; |
||
| 2820 | } |
||
| 2821 | } |
||
| 2822 | |||
| 2823 | /** |
||
| 2824 | * Get a single item from the feed |
||
| 2825 | * |
||
| 2826 | * This is better suited for {@link http://php.net/for for()} loops, whereas |
||
| 2827 | * {@see get_items()} is better suited for |
||
| 2828 | * {@link http://php.net/foreach foreach()} loops. |
||
| 2829 | * |
||
| 2830 | * @see get_item_quantity() |
||
| 2831 | * @since Beta 2 |
||
| 2832 | * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1 |
||
| 2833 | * @return SimplePie_Item|null |
||
| 2834 | */ |
||
| 2835 | public function get_item($key = 0) |
||
| 2836 | { |
||
| 2837 | $items = $this->get_items(); |
||
| 2838 | if (isset($items[$key])) |
||
| 2839 | { |
||
| 2840 | return $items[$key]; |
||
| 2841 | } |
||
| 2842 | else |
||
| 2843 | { |
||
| 2844 | return null; |
||
| 2845 | } |
||
| 2846 | } |
||
| 2847 | |||
| 2848 | /** |
||
| 2849 | * Get all items from the feed |
||
| 2850 | * |
||
| 2851 | * This is better suited for {@link http://php.net/for for()} loops, whereas |
||
| 2852 | * {@see get_items()} is better suited for |
||
| 2853 | * {@link http://php.net/foreach foreach()} loops. |
||
| 2854 | * |
||
| 2855 | * @see get_item_quantity |
||
| 2856 | * @since Beta 2 |
||
| 2857 | * @param int $start Index to start at |
||
| 2858 | * @param int $end Number of items to return. 0 for all items after `$start` |
||
| 2859 | * @return array|null List of {@see SimplePie_Item} objects |
||
| 2860 | */ |
||
| 2861 | public function get_items($start = 0, $end = 0) |
||
| 2862 | { |
||
| 2863 | if (!isset($this->data['items'])) |
||
| 2864 | { |
||
| 2865 | if (!empty($this->multifeed_objects)) |
||
| 2866 | { |
||
| 2867 | $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); |
||
| 2868 | } |
||
| 2869 | else |
||
| 2870 | { |
||
| 2871 | $this->data['items'] = array(); |
||
| 2872 | if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) |
||
| 2873 | { |
||
| 2874 | $keys = array_keys($items); |
||
| 2875 | foreach ($keys as $key) |
||
| 2876 | { |
||
| 2877 | $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); |
||
| 2878 | } |
||
| 2879 | } |
||
| 2880 | if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) |
||
| 2881 | { |
||
| 2882 | $keys = array_keys($items); |
||
| 2883 | foreach ($keys as $key) |
||
| 2884 | { |
||
| 2885 | $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); |
||
| 2886 | } |
||
| 2887 | } |
||
| 2888 | if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) |
||
| 2889 | { |
||
| 2890 | $keys = array_keys($items); |
||
| 2891 | foreach ($keys as $key) |
||
| 2892 | { |
||
| 2893 | $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); |
||
| 2894 | } |
||
| 2895 | } |
||
| 2896 | if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) |
||
| 2897 | { |
||
| 2898 | $keys = array_keys($items); |
||
| 2899 | foreach ($keys as $key) |
||
| 2900 | { |
||
| 2901 | $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); |
||
| 2902 | } |
||
| 2903 | } |
||
| 2904 | if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item')) |
||
| 2905 | { |
||
| 2906 | $keys = array_keys($items); |
||
| 2907 | foreach ($keys as $key) |
||
| 2908 | { |
||
| 2909 | $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key])); |
||
| 2910 | } |
||
| 2911 | } |
||
| 2912 | } |
||
| 2913 | } |
||
| 2914 | |||
| 2915 | if (!empty($this->data['items'])) |
||
| 2916 | { |
||
| 2917 | // If we want to order it by date, check if all items have a date, and then sort it |
||
| 2918 | if ($this->order_by_date && empty($this->multifeed_objects)) |
||
| 2919 | { |
||
| 2920 | if (!isset($this->data['ordered_items'])) |
||
| 2921 | { |
||
| 2922 | $do_sort = true; |
||
| 2923 | foreach ($this->data['items'] as $item) |
||
| 2924 | { |
||
| 2925 | if (!$item->get_date('U')) |
||
| 2926 | { |
||
| 2927 | $do_sort = false; |
||
| 2928 | break; |
||
| 2929 | } |
||
| 2930 | } |
||
| 2931 | $item = null; |
||
| 2932 | $this->data['ordered_items'] = $this->data['items']; |
||
| 2933 | if ($do_sort) |
||
| 2934 | { |
||
| 2935 | usort($this->data['ordered_items'], array(get_class($this), 'sort_items')); |
||
| 2936 | } |
||
| 2937 | } |
||
| 2938 | $items = $this->data['ordered_items']; |
||
| 2939 | } |
||
| 2940 | else |
||
| 2941 | { |
||
| 2942 | $items = $this->data['items']; |
||
| 2943 | } |
||
| 2944 | |||
| 2945 | // Slice the data as desired |
||
| 2946 | if ($end === 0) |
||
| 2947 | { |
||
| 2948 | return array_slice($items, $start); |
||
| 2949 | } |
||
| 2950 | else |
||
| 2951 | { |
||
| 2952 | return array_slice($items, $start, $end); |
||
| 2953 | } |
||
| 2954 | } |
||
| 2955 | else |
||
| 2956 | { |
||
| 2957 | return array(); |
||
| 2958 | } |
||
| 2959 | } |
||
| 2960 | |||
| 2961 | /** |
||
| 2962 | * Set the favicon handler |
||
| 2963 | * |
||
| 2964 | * @deprecated Use your own favicon handling instead |
||
| 2965 | */ |
||
| 2966 | public function set_favicon_handler($page = false, $qs = 'i') |
||
| 2967 | { |
||
| 2968 | $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; |
||
| 2969 | trigger_error('Favicon handling has been removed, please use your own handling', $level); |
||
| 2970 | return false; |
||
| 2971 | } |
||
| 2972 | |||
| 2973 | /** |
||
| 2974 | * Get the favicon for the current feed |
||
| 2975 | * |
||
| 2976 | * @deprecated Use your own favicon handling instead |
||
| 2977 | */ |
||
| 2978 | public function get_favicon() |
||
| 2979 | { |
||
| 2980 | $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; |
||
| 2981 | trigger_error('Favicon handling has been removed, please use your own handling', $level); |
||
| 2982 | |||
| 2983 | if (($url = $this->get_link()) !== null) |
||
| 2984 | { |
||
| 2985 | return 'http://g.etfv.co/' . urlencode($url); |
||
| 2986 | } |
||
| 2987 | |||
| 2988 | return false; |
||
| 2989 | } |
||
| 2990 | |||
| 2991 | /** |
||
| 2992 | * Magic method handler |
||
| 2993 | * |
||
| 2994 | * @param string $method Method name |
||
| 2995 | * @param array $args Arguments to the method |
||
| 2996 | * @return mixed |
||
| 2997 | */ |
||
| 2998 | public function __call($method, $args) |
||
| 2999 | { |
||
| 3000 | if (strpos($method, 'subscribe_') === 0) |
||
| 3001 | { |
||
| 3002 | $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; |
||
| 3003 | trigger_error('subscribe_*() has been deprecated, implement the callback yourself', $level); |
||
| 3004 | return ''; |
||
| 3005 | } |
||
| 3006 | if ($method === 'enable_xml_dump') |
||
| 3007 | { |
||
| 3008 | $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; |
||
| 3009 | trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level); |
||
| 3010 | return false; |
||
| 3011 | } |
||
| 3012 | |||
| 3013 | $class = get_class($this); |
||
| 3014 | $trace = debug_backtrace(); |
||
| 3015 | $file = $trace[0]['file']; |
||
| 3016 | $line = $trace[0]['line']; |
||
| 3017 | trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR); |
||
| 3018 | } |
||
| 3019 | |||
| 3020 | /** |
||
| 3021 | * Sorting callback for items |
||
| 3022 | * |
||
| 3023 | * @access private |
||
| 3024 | * @param SimplePie $a |
||
| 3025 | * @param SimplePie $b |
||
| 3026 | * @return boolean |
||
| 3027 | */ |
||
| 3028 | public static function sort_items($a, $b) |
||
| 3029 | { |
||
| 3030 | return $a->get_date('U') <= $b->get_date('U'); |
||
| 3031 | } |
||
| 3032 | |||
| 3033 | /** |
||
| 3034 | * Merge items from several feeds into one |
||
| 3035 | * |
||
| 3036 | * If you're merging multiple feeds together, they need to all have dates |
||
| 3037 | * for the items or else SimplePie will refuse to sort them. |
||
| 3038 | * |
||
| 3039 | * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings |
||
| 3040 | * @param array $urls List of SimplePie feed objects to merge |
||
| 3041 | * @param int $start Starting item |
||
| 3042 | * @param int $end Number of items to return |
||
| 3043 | * @param int $limit Maximum number of items per feed |
||
| 3044 | * @return array |
||
| 3045 | */ |
||
| 3046 | public static function merge_items($urls, $start = 0, $end = 0, $limit = 0) |
||
| 3047 | { |
||
| 3048 | if (is_array($urls) && sizeof($urls) > 0) |
||
| 3049 | { |
||
| 3050 | $items = array(); |
||
| 3051 | foreach ($urls as $arg) |
||
| 3052 | { |
||
| 3053 | if ($arg instanceof SimplePie) |
||
| 3054 | { |
||
| 3055 | $items = array_merge($items, $arg->get_items(0, $limit)); |
||
| 3056 | } |
||
| 3057 | else |
||
| 3058 | { |
||
| 3059 | trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); |
||
| 3060 | } |
||
| 3061 | } |
||
| 3062 | |||
| 3063 | $do_sort = true; |
||
| 3064 | foreach ($items as $item) |
||
| 3065 | { |
||
| 3066 | if (!$item->get_date('U')) |
||
| 3067 | { |
||
| 3068 | $do_sort = false; |
||
| 3069 | break; |
||
| 3070 | } |
||
| 3071 | } |
||
| 3072 | $item = null; |
||
| 3073 | if ($do_sort) |
||
| 3074 | { |
||
| 3075 | usort($items, array(get_class($urls[0]), 'sort_items')); |
||
| 3076 | } |
||
| 3077 | |||
| 3078 | if ($end === 0) |
||
| 3079 | { |
||
| 3080 | return array_slice($items, $start); |
||
| 3081 | } |
||
| 3082 | else |
||
| 3083 | { |
||
| 3084 | return array_slice($items, $start, $end); |
||
| 3085 | } |
||
| 3086 | } |
||
| 3087 | else |
||
| 3088 | { |
||
| 3089 | trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); |
||
| 3090 | return array(); |
||
| 3091 | } |
||
| 3092 | } |
||
| 3093 | } |
||
| 3094 | endif; |