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; |