5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 define('SIMPLEPIE_NAME', 'SimplePie');
54 define('SIMPLEPIE_VERSION', '1.2');
59 define('SIMPLEPIE_BUILD', '20090627192103');
62 * SimplePie Website URL
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
68 * @see SimplePie::set_useragent()
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
79 * @see SimplePie::set_autodiscovery_level()
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
122 define('SIMPLEPIE_TYPE_NONE', 0);
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
130 * RSS 0.91 (Netscape)
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
135 * RSS 0.91 (Userland)
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
140 * RSS 0.91 (both Netscape and Userland)
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
175 * Non-RDF-based RSS (truly intended as syndication format)
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
202 define('SIMPLEPIE_TYPE_ALL', 1023);
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
225 * base64-encoded construct
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
235 * A construct that might be HTML
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
247 define('SIMPLEPIE_SAME_CASE', 1);
250 * Change to lowercase
252 define('SIMPLEPIE_LOWERCASE', 2);
255 * Change to uppercase
257 define('SIMPLEPIE_UPPERCASE', 4);
260 * PCRE for HTML attributes
262 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
265 * PCRE for XML attributes
267 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
272 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
277 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
282 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
287 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
292 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
297 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
300 * RSS 1.0 Content Module Namespace
302 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
306 * (Stupid, I know, but I'm certain it will confuse people less with support.)
308 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
313 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
318 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
321 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
323 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
328 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
331 * Media RSS Namespace
333 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
336 * Wrong Media RSS Namespace
338 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
341 * iTunes RSS Namespace
343 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
348 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
351 * IANA Link Relations Registry
353 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
356 * Whether we're running on PHP5
358 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
363 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
368 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
373 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
376 * fsockopen() file source
378 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
383 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
386 * file_get_contents() file source
388 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
398 * @var array Raw data
404 * @var mixed Error string
410 * @var object Instance of SimplePie_Sanitize (or other class)
411 * @see SimplePie::set_sanitize_class()
417 * @var string SimplePie Useragent
418 * @see SimplePie::set_useragent()
421 var $useragent = SIMPLEPIE_USERAGENT;
424 * @var string Feed URL
425 * @see SimplePie::set_feed_url()
431 * @var object Instance of SimplePie_File to use as a feed
432 * @see SimplePie::set_file()
438 * @var string Raw feed data
439 * @see SimplePie::set_raw_data()
445 * @var int Timeout for fetching remote files
446 * @see SimplePie::set_timeout()
452 * @var bool Forces fsockopen() to be used for remote files instead
453 * of cURL, even if a new enough version is installed
454 * @see SimplePie::force_fsockopen()
457 var $force_fsockopen = false;
460 * @var bool Force the given data/URL to be treated as a feed no matter what
462 * @see SimplePie::force_feed()
465 var $force_feed = false;
468 * @var bool Enable/Disable XML dump
469 * @see SimplePie::enable_xml_dump()
472 var $xml_dump = false;
475 * @var bool Enable/Disable Caching
476 * @see SimplePie::enable_cache()
482 * @var int Cache duration (in seconds)
483 * @see SimplePie::set_cache_duration()
486 var $cache_duration = 3600;
489 * @var int Auto-discovery cache duration (in seconds)
490 * @see SimplePie::set_autodiscovery_cache_duration()
493 var $autodiscovery_cache_duration = 604800; // 7 Days.
496 * @var string Cache location (relative to executing script)
497 * @see SimplePie::set_cache_location()
500 var $cache_location = './cache';
503 * @var string Function that creates the cache filename
504 * @see SimplePie::set_cache_name_function()
507 var $cache_name_function = 'md5';
510 * @var bool Reorder feed by date descending
511 * @see SimplePie::enable_order_by_date()
514 var $order_by_date = true;
517 * @var mixed Force input encoding to be set to the follow value
518 * (false, or anything type-cast to false, disables this feature)
519 * @see SimplePie::set_input_encoding()
522 var $input_encoding = false;
525 * @var int Feed Autodiscovery Level
526 * @see SimplePie::set_autodiscovery_level()
529 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
532 * @var string Class used for caching feeds
533 * @see SimplePie::set_cache_class()
536 var $cache_class = 'SimplePie_Cache';
539 * @var string Class used for locating feeds
540 * @see SimplePie::set_locator_class()
543 var $locator_class = 'SimplePie_Locator';
546 * @var string Class used for parsing feeds
547 * @see SimplePie::set_parser_class()
550 var $parser_class = 'SimplePie_Parser';
553 * @var string Class used for fetching feeds
554 * @see SimplePie::set_file_class()
557 var $file_class = 'SimplePie_File';
560 * @var string Class used for items
561 * @see SimplePie::set_item_class()
564 var $item_class = 'SimplePie_Item';
567 * @var string Class used for authors
568 * @see SimplePie::set_author_class()
571 var $author_class = 'SimplePie_Author';
574 * @var string Class used for categories
575 * @see SimplePie::set_category_class()
578 var $category_class = 'SimplePie_Category';
581 * @var string Class used for enclosures
582 * @see SimplePie::set_enclosures_class()
585 var $enclosure_class = 'SimplePie_Enclosure';
588 * @var string Class used for Media RSS <media:text> captions
589 * @see SimplePie::set_caption_class()
592 var $caption_class = 'SimplePie_Caption';
595 * @var string Class used for Media RSS <media:copyright>
596 * @see SimplePie::set_copyright_class()
599 var $copyright_class = 'SimplePie_Copyright';
602 * @var string Class used for Media RSS <media:credit>
603 * @see SimplePie::set_credit_class()
606 var $credit_class = 'SimplePie_Credit';
609 * @var string Class used for Media RSS <media:rating>
610 * @see SimplePie::set_rating_class()
613 var $rating_class = 'SimplePie_Rating';
616 * @var string Class used for Media RSS <media:restriction>
617 * @see SimplePie::set_restriction_class()
620 var $restriction_class = 'SimplePie_Restriction';
623 * @var string Class used for content-type sniffing
624 * @see SimplePie::set_content_type_sniffer_class()
627 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
630 * @var string Class used for item sources.
631 * @see SimplePie::set_source_class()
634 var $source_class = 'SimplePie_Source';
637 * @var mixed Set javascript query string parameter (false, or
638 * anything type-cast to false, disables this feature)
639 * @see SimplePie::set_javascript()
642 var $javascript = 'js';
645 * @var int Maximum number of feeds to check with autodiscovery
646 * @see SimplePie::set_max_checked_feeds()
649 var $max_checked_feeds = 10;
652 * @var array All the feeds found during the autodiscovery process
653 * @see SimplePie::get_all_discovered_feeds()
656 var $all_discovered_feeds = array();
659 * @var string Web-accessible path to the handler_favicon.php file.
660 * @see SimplePie::set_favicon_handler()
663 var $favicon_handler = '';
666 * @var string Web-accessible path to the handler_image.php file.
667 * @see SimplePie::set_image_handler()
670 var $image_handler = '';
673 * @var array Stores the URLs when multiple feeds are being initialized.
674 * @see SimplePie::set_feed_url()
677 var $multifeed_url = array();
680 * @var array Stores SimplePie objects when multiple feeds initialized.
683 var $multifeed_objects = array();
686 * @var array Stores the get_object_vars() array for use with multifeeds.
687 * @see SimplePie::set_feed_url()
690 var $config_settings = null;
693 * @var integer Stores the number of items to return per-feed with multifeeds.
694 * @see SimplePie::set_item_limit()
700 * @var array Stores the default attributes to be stripped by strip_attributes().
701 * @see SimplePie::strip_attributes()
704 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
707 * @var array Stores the default tags to be stripped by strip_htmltags().
708 * @see SimplePie::strip_htmltags()
711 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
714 * The SimplePie class contains feed level data and options
716 * There are two ways that you can create a new SimplePie object. The first
717 * is by passing a feed URL as a parameter to the SimplePie constructor
718 * (as well as optionally setting the cache location and cache expiry). This
719 * will initialise the whole feed with all of the default settings, and you
720 * can begin accessing methods and properties immediately.
722 * The second way is to create the SimplePie object with no parameters
723 * at all. This will enable you to set configuration options. After setting
724 * them, you must initialise the feed using $feed->init(). At that point the
725 * object's methods and properties will be available to you. This format is
726 * what is used throughout this documentation.
729 * @since 1.0 Preview Release
730 * @param string $feed_url This is the URL you want to parse.
731 * @param string $cache_location This is where you want the cache to be stored.
732 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
734 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
736 // Other objects, instances created here so we can set options on them
737 $this->sanitize =& new SimplePie_Sanitize;
739 // Set options if they're passed to the constructor
740 if ($cache_location !== null)
742 $this->set_cache_location($cache_location);
745 if ($cache_duration !== null)
747 $this->set_cache_duration($cache_duration);
750 // Only init the script if we're passed a feed URL
751 if ($feed_url !== null)
753 $this->set_feed_url($feed_url);
759 * Used for converting object to a string
761 function __toString()
763 return md5(serialize($this->data));
767 * Remove items that link back to this before destroying this object
769 function __destruct()
771 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
773 if (!empty($this->data['items']))
775 foreach ($this->data['items'] as $item)
779 unset($item, $this->data['items']);
781 if (!empty($this->data['ordered_items']))
783 foreach ($this->data['ordered_items'] as $item)
787 unset($item, $this->data['ordered_items']);
793 * Force the given data/URL to be treated as a feed no matter what it
798 * @param bool $enable Force the given data/URL to be treated as a feed
800 function force_feed($enable = false)
802 $this->force_feed = (bool) $enable;
806 * This is the URL of the feed you want to parse.
808 * This allows you to enter the URL of the feed you want to parse, or the
809 * website you want to try to use auto-discovery on. This takes priority
810 * over any set raw data.
812 * You can set multiple feeds to mash together by passing an array instead
813 * of a string for the $url. Remember that with each additional feed comes
814 * additional processing and resources.
817 * @since 1.0 Preview Release
818 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
819 * @see SimplePie::set_raw_data()
821 function set_feed_url($url)
825 $this->multifeed_url = array();
826 foreach ($url as $value)
828 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
833 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
838 * Provides an instance of SimplePie_File to use as a feed
841 * @param object &$file Instance of SimplePie_File (or subclass)
842 * @return bool True on success, false on failure
844 function set_file(&$file)
846 if (is_a($file, 'SimplePie_File'))
848 $this->feed_url = $file->url;
849 $this->file =& $file;
856 * Allows you to use a string of RSS/Atom data instead of a remote feed.
858 * If you have a feed available as a string in PHP, you can tell SimplePie
859 * to parse that data string instead of a remote feed. Any set feed URL
864 * @param string $data RSS or Atom data as a string.
865 * @see SimplePie::set_feed_url()
867 function set_raw_data($data)
869 $this->raw_data = $data;
873 * Allows you to override the default timeout for fetching remote feeds.
875 * This allows you to change the maximum time the feed's server to respond
876 * and send the feed back.
880 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
882 function set_timeout($timeout = 10)
884 $this->timeout = (int) $timeout;
888 * Forces SimplePie to use fsockopen() instead of the preferred cURL
893 * @param bool $enable Force fsockopen() to be used
895 function force_fsockopen($enable = false)
897 $this->force_fsockopen = (bool) $enable;
901 * Outputs the raw XML content of the feed, after it has gone through
902 * SimplePie's filters.
904 * Used only for debugging, this function will output the XML content as
905 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
906 * before trying to parse it. Many parts of the feed are re-written in
907 * memory, and in the end, you have a parsable feed. XML dump shows you the
908 * actual XML that SimplePie tries to parse, which may or may not be very
909 * different from the original feed.
912 * @since 1.0 Preview Release
913 * @param bool $enable Enable XML dump
915 function enable_xml_dump($enable = false)
917 $this->xml_dump = (bool) $enable;
921 * Enables/disables caching in SimplePie.
923 * This option allows you to disable caching all-together in SimplePie.
924 * However, disabling the cache can lead to longer load times.
927 * @since 1.0 Preview Release
928 * @param bool $enable Enable caching
930 function enable_cache($enable = true)
932 $this->cache = (bool) $enable;
936 * Set the length of time (in seconds) that the contents of a feed
940 * @param int $seconds The feed content cache duration.
942 function set_cache_duration($seconds = 3600)
944 $this->cache_duration = (int) $seconds;
948 * Set the length of time (in seconds) that the autodiscovered feed
949 * URL will be cached.
952 * @param int $seconds The autodiscovered feed URL cache duration.
954 function set_autodiscovery_cache_duration($seconds = 604800)
956 $this->autodiscovery_cache_duration = (int) $seconds;
960 * Set the file system location where the cached files should be stored.
963 * @param string $location The file system location.
965 function set_cache_location($location = './cache')
967 $this->cache_location = (string) $location;
971 * Determines whether feed items should be sorted into reverse chronological order.
974 * @param bool $enable Sort as reverse chronological order.
976 function enable_order_by_date($enable = true)
978 $this->order_by_date = (bool) $enable;
982 * Allows you to override the character encoding reported by the feed.
985 * @param string $encoding Character encoding.
987 function set_input_encoding($encoding = false)
991 $this->input_encoding = (string) $encoding;
995 $this->input_encoding = false;
1000 * Set how much feed autodiscovery to do
1003 * @see SIMPLEPIE_LOCATOR_NONE
1004 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1005 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1006 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1007 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1008 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1009 * @see SIMPLEPIE_LOCATOR_ALL
1010 * @param int $level Feed Autodiscovery Level (level can be a
1011 * combination of the above constants, see bitwise OR operator)
1013 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1015 $this->autodiscovery = (int) $level;
1019 * Allows you to change which class SimplePie uses for caching.
1020 * Useful when you are overloading or extending SimplePie's default classes.
1023 * @param string $class Name of custom class.
1024 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1025 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1027 function set_cache_class($class = 'SimplePie_Cache')
1029 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1031 $this->cache_class = $class;
1038 * Allows you to change which class SimplePie uses for auto-discovery.
1039 * Useful when you are overloading or extending SimplePie's default classes.
1042 * @param string $class Name of custom class.
1043 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1044 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1046 function set_locator_class($class = 'SimplePie_Locator')
1048 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1050 $this->locator_class = $class;
1057 * Allows you to change which class SimplePie uses for XML parsing.
1058 * Useful when you are overloading or extending SimplePie's default classes.
1061 * @param string $class Name of custom class.
1062 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1063 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1065 function set_parser_class($class = 'SimplePie_Parser')
1067 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1069 $this->parser_class = $class;
1076 * Allows you to change which class SimplePie uses for remote file fetching.
1077 * Useful when you are overloading or extending SimplePie's default classes.
1080 * @param string $class Name of custom class.
1081 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1082 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1084 function set_file_class($class = 'SimplePie_File')
1086 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1088 $this->file_class = $class;
1095 * Allows you to change which class SimplePie uses for data sanitization.
1096 * Useful when you are overloading or extending SimplePie's default classes.
1099 * @param string $class Name of custom class.
1100 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1101 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1103 function set_sanitize_class($class = 'SimplePie_Sanitize')
1105 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1107 $this->sanitize =& new $class;
1114 * Allows you to change which class SimplePie uses for handling feed items.
1115 * Useful when you are overloading or extending SimplePie's default classes.
1118 * @param string $class Name of custom class.
1119 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1120 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1122 function set_item_class($class = 'SimplePie_Item')
1124 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1126 $this->item_class = $class;
1133 * Allows you to change which class SimplePie uses for handling author data.
1134 * Useful when you are overloading or extending SimplePie's default classes.
1137 * @param string $class Name of custom class.
1138 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1139 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1141 function set_author_class($class = 'SimplePie_Author')
1143 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1145 $this->author_class = $class;
1152 * Allows you to change which class SimplePie uses for handling category data.
1153 * Useful when you are overloading or extending SimplePie's default classes.
1156 * @param string $class Name of custom class.
1157 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1158 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1160 function set_category_class($class = 'SimplePie_Category')
1162 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1164 $this->category_class = $class;
1171 * Allows you to change which class SimplePie uses for feed enclosures.
1172 * Useful when you are overloading or extending SimplePie's default classes.
1175 * @param string $class Name of custom class.
1176 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1177 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1179 function set_enclosure_class($class = 'SimplePie_Enclosure')
1181 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1183 $this->enclosure_class = $class;
1190 * Allows you to change which class SimplePie uses for <media:text> captions
1191 * Useful when you are overloading or extending SimplePie's default classes.
1194 * @param string $class Name of custom class.
1195 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1196 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1198 function set_caption_class($class = 'SimplePie_Caption')
1200 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1202 $this->caption_class = $class;
1209 * Allows you to change which class SimplePie uses for <media:copyright>
1210 * Useful when you are overloading or extending SimplePie's default classes.
1213 * @param string $class Name of custom class.
1214 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1215 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1217 function set_copyright_class($class = 'SimplePie_Copyright')
1219 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1221 $this->copyright_class = $class;
1228 * Allows you to change which class SimplePie uses for <media:credit>
1229 * Useful when you are overloading or extending SimplePie's default classes.
1232 * @param string $class Name of custom class.
1233 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1234 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1236 function set_credit_class($class = 'SimplePie_Credit')
1238 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1240 $this->credit_class = $class;
1247 * Allows you to change which class SimplePie uses for <media:rating>
1248 * Useful when you are overloading or extending SimplePie's default classes.
1251 * @param string $class Name of custom class.
1252 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1253 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1255 function set_rating_class($class = 'SimplePie_Rating')
1257 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1259 $this->rating_class = $class;
1266 * Allows you to change which class SimplePie uses for <media:restriction>
1267 * Useful when you are overloading or extending SimplePie's default classes.
1270 * @param string $class Name of custom class.
1271 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1272 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1274 function set_restriction_class($class = 'SimplePie_Restriction')
1276 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1278 $this->restriction_class = $class;
1285 * Allows you to change which class SimplePie uses for content-type sniffing.
1286 * Useful when you are overloading or extending SimplePie's default classes.
1289 * @param string $class Name of custom class.
1290 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1291 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1293 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1295 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1297 $this->content_type_sniffer_class = $class;
1304 * Allows you to change which class SimplePie uses item sources.
1305 * Useful when you are overloading or extending SimplePie's default classes.
1308 * @param string $class Name of custom class.
1309 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1310 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1312 function set_source_class($class = 'SimplePie_Source')
1314 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1316 $this->source_class = $class;
1323 * Allows you to override the default user agent string.
1326 * @param string $ua New user agent string.
1328 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1330 $this->useragent = (string) $ua;
1334 * Set callback function to create cache filename with
1337 * @param mixed $function Callback function
1339 function set_cache_name_function($function = 'md5')
1341 if (is_callable($function))
1343 $this->cache_name_function = $function;
1348 * Set javascript query string parameter
1351 * @param mixed $get Javascript query string parameter
1353 function set_javascript($get = 'js')
1357 $this->javascript = (string) $get;
1361 $this->javascript = false;
1366 * Set options to make SP as fast as possible. Forgoes a
1367 * substantial amount of data sanitization in favor of speed.
1370 * @param bool $set Whether to set them or not
1372 function set_stupidly_fast($set = false)
1376 $this->enable_order_by_date(false);
1377 $this->remove_div(false);
1378 $this->strip_comments(false);
1379 $this->strip_htmltags(false);
1380 $this->strip_attributes(false);
1381 $this->set_image_handler(false);
1386 * Set maximum number of feeds to check with autodiscovery
1389 * @param int $max Maximum number of feeds to check
1391 function set_max_checked_feeds($max = 10)
1393 $this->max_checked_feeds = (int) $max;
1396 function remove_div($enable = true)
1398 $this->sanitize->remove_div($enable);
1401 function strip_htmltags($tags = '', $encode = null)
1405 $tags = $this->strip_htmltags;
1407 $this->sanitize->strip_htmltags($tags);
1408 if ($encode !== null)
1410 $this->sanitize->encode_instead_of_strip($tags);
1414 function encode_instead_of_strip($enable = true)
1416 $this->sanitize->encode_instead_of_strip($enable);
1419 function strip_attributes($attribs = '')
1421 if ($attribs === '')
1423 $attribs = $this->strip_attributes;
1425 $this->sanitize->strip_attributes($attribs);
1428 function set_output_encoding($encoding = 'UTF-8')
1430 $this->sanitize->set_output_encoding($encoding);
1433 function strip_comments($strip = false)
1435 $this->sanitize->strip_comments($strip);
1439 * Set element/attribute key/value pairs of HTML attributes
1440 * containing URLs that need to be resolved relative to the feed
1444 * @param array $element_attribute Element/attribute key/value pairs
1446 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1448 $this->sanitize->set_url_replacements($element_attribute);
1452 * Set the handler to enable the display of cached favicons.
1455 * @param str $page Web-accessible path to the handler_favicon.php file.
1456 * @param str $qs The query string that the value should be passed to.
1458 function set_favicon_handler($page = false, $qs = 'i')
1460 if ($page !== false)
1462 $this->favicon_handler = $page . '?' . $qs . '=';
1466 $this->favicon_handler = '';
1471 * Set the handler to enable the display of cached images.
1474 * @param str $page Web-accessible path to the handler_image.php file.
1475 * @param str $qs The query string that the value should be passed to.
1477 function set_image_handler($page = false, $qs = 'i')
1479 if ($page !== false)
1481 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1485 $this->image_handler = '';
1490 * Set the limit for items returned per-feed with multifeeds.
1493 * @param integer $limit The maximum number of items to return.
1495 function set_item_limit($limit = 0)
1497 $this->item_limit = (int) $limit;
1502 // Check absolute bare minimum requirements.
1503 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1507 // 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.
1508 elseif (!extension_loaded('xmlreader'))
1510 static $xml_is_sane = null;
1511 if ($xml_is_sane === null)
1513 $parser_check = xml_parser_create();
1514 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1515 xml_parser_free($parser_check);
1516 $xml_is_sane = isset($values[0]['value']);
1524 if (isset($_GET[$this->javascript]))
1526 SimplePie_Misc::output_javascript();
1530 // Pass whatever was set with config options over to the sanitizer.
1531 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1532 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1534 if ($this->feed_url !== null || $this->raw_data !== null)
1536 $this->data = array();
1537 $this->multifeed_objects = array();
1540 if ($this->feed_url !== null)
1542 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1543 // Decide whether to enable caching
1544 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1546 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1548 // If it's enabled and we don't want an XML dump, use the cache
1549 if ($cache && !$this->xml_dump)
1552 $this->data = $cache->load();
1553 if (!empty($this->data))
1555 // If the cache is for an outdated build of SimplePie
1556 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1559 $this->data = array();
1561 // If we've hit a collision just rerun it with caching disabled
1562 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1565 $this->data = array();
1567 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1568 elseif (isset($this->data['feed_url']))
1570 // If the autodiscovery cache is still valid use it.
1571 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1573 // Do not need to do feed autodiscovery yet.
1574 if ($this->data['feed_url'] === $this->data['url'])
1577 $this->data = array();
1581 $this->set_feed_url($this->data['feed_url']);
1582 return $this->init();
1586 // Check if the cache has been updated
1587 elseif ($cache->mtime() + $this->cache_duration < time())
1589 // If we have last-modified and/or etag set
1590 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1593 if (isset($this->data['headers']['last-modified']))
1595 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1597 if (isset($this->data['headers']['etag']))
1599 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1601 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1604 if ($file->status_code === 304)
1611 $headers = $file->headers;
1620 // If the cache is still valid, just return true
1626 // If the cache is empty, delete it
1630 $this->data = array();
1633 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1636 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1638 $file =& $this->file;
1642 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1645 // If the file connection has an error, set SimplePie::error to that and quit
1646 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1648 $this->error = $file->error;
1649 if (!empty($this->data))
1659 if (!$this->force_feed)
1661 // Check if the supplied URL is a feed, if it isn't, look for it.
1662 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1663 if (!$locate->is_feed($file))
1665 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1667 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1671 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1672 if (!$cache->save($this))
1674 trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
1676 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1678 $this->feed_url = $file->url;
1682 $this->error = "A feed could not be found at $this->feed_url";
1683 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1690 $headers = $file->headers;
1691 $data = $file->body;
1692 $sniffer =& new $this->content_type_sniffer_class($file);
1693 $sniffed = $sniffer->get_type();
1697 $data = $this->raw_data;
1700 // Set up array of possible encodings
1701 $encodings = array();
1703 // First check to see if input has been overridden.
1704 if ($this->input_encoding !== false)
1706 $encodings[] = $this->input_encoding;
1709 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1710 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1712 // RFC 3023 (only applies to sniffed content)
1713 if (isset($sniffed))
1715 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1717 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1719 $encodings[] = strtoupper($charset[1]);
1721 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1722 $encodings[] = 'UTF-8';
1724 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1726 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1728 $encodings[] = $charset[1];
1730 $encodings[] = 'US-ASCII';
1732 // Text MIME-type default
1733 elseif (substr($sniffed, 0, 5) === 'text/')
1735 $encodings[] = 'US-ASCII';
1739 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1740 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1741 $encodings[] = 'UTF-8';
1742 $encodings[] = 'ISO-8859-1';
1744 // There's no point in trying an encoding twice
1745 $encodings = array_unique($encodings);
1747 // If we want the XML, just output that with the most likely encoding and quit
1748 if ($this->xml_dump)
1750 header('Content-type: text/xml; charset=' . $encodings[0]);
1755 // Loop through each possible encoding, till we return something, or run out of possibilities
1756 foreach ($encodings as $encoding)
1758 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1759 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1761 // Create new parser
1762 $parser =& new $this->parser_class();
1764 // If it's parsed fine
1765 if ($parser->parse($utf8_data, 'UTF-8'))
1767 $this->data = $parser->get_data();
1768 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1770 if (isset($headers))
1772 $this->data['headers'] = $headers;
1774 $this->data['build'] = SIMPLEPIE_BUILD;
1776 // Cache the file if caching is enabled
1777 if ($cache && !$cache->save($this))
1779 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1785 $this->error = "A feed could not be found at $this->feed_url";
1786 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1794 // We have an error, just set SimplePie_Misc::error to it and quit
1795 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1799 $this->error = 'The data could not be converted to UTF-8';
1801 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1804 elseif (!empty($this->multifeed_url))
1808 $this->multifeed_objects = array();
1809 foreach ($this->multifeed_url as $url)
1813 // This keyword needs to defy coding standards for PHP4 compatibility
1814 $this->multifeed_objects[$i] = clone($this);
1818 $this->multifeed_objects[$i] = $this;
1820 $this->multifeed_objects[$i]->set_feed_url($url);
1821 $success |= $this->multifeed_objects[$i]->init();
1824 return (bool) $success;
1833 * Return the error message for the occured error
1836 * @return string Error message
1840 return $this->error;
1843 function get_encoding()
1845 return $this->sanitize->output_encoding;
1848 function handle_content_type($mime = 'text/html')
1850 if (!headers_sent())
1852 $header = "Content-type: $mime;";
1853 if ($this->get_encoding())
1855 $header .= ' charset=' . $this->get_encoding();
1859 $header .= ' charset=UTF-8';
1867 if (!isset($this->data['type']))
1869 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1870 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1872 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1874 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1876 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1878 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1880 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1881 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1882 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1885 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1887 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1888 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1889 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1892 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1895 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1897 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1898 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1900 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1904 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1906 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1909 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1913 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1920 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1924 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1928 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1932 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1939 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1942 return $this->data['type'];
1946 * Returns the URL for the favicon of the feed's website.
1948 * @todo Cache atom:icon
1952 function get_favicon()
1954 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1956 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1958 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1960 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1962 if ($this->cache && $this->favicon_handler)
1964 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1965 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1969 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1973 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1975 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1977 $sniffer =& new $this->content_type_sniffer_class($file);
1978 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1980 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1982 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1986 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1987 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2000 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2007 * @todo If we have a perm redirect we should return the new URL
2008 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2009 * @todo Also, |atom:link|@rel=self
2011 function subscribe_url()
2013 if ($this->feed_url !== null)
2015 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2023 function subscribe_feed()
2025 if ($this->feed_url !== null)
2027 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2035 function subscribe_outlook()
2037 if ($this->feed_url !== null)
2039 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2047 function subscribe_podcast()
2049 if ($this->feed_url !== null)
2051 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2059 function subscribe_itunes()
2061 if ($this->feed_url !== null)
2063 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2072 * Creates the subscribe_* methods' return data
2075 * @param string $feed_url String to prefix to the feed URL
2076 * @param string $site_url String to prefix to the site URL (and
2077 * suffix to the feed URL)
2078 * @return mixed URL if feed exists, false otherwise
2080 function subscribe_service($feed_url, $site_url = null)
2082 if ($this->subscribe_url())
2084 $return = $feed_url . rawurlencode($this->feed_url);
2085 if ($site_url !== null && $this->get_link() !== null)
2087 $return .= $site_url . rawurlencode($this->get_link());
2089 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2097 function subscribe_aol()
2099 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2102 function subscribe_bloglines()
2104 return $this->subscribe_service('http://www.bloglines.com/sub/');
2107 function subscribe_eskobo()
2109 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2112 function subscribe_feedfeeds()
2114 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2117 function subscribe_feedster()
2119 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2122 function subscribe_google()
2124 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2127 function subscribe_gritwire()
2129 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2132 function subscribe_msn()
2134 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2137 function subscribe_netvibes()
2139 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2142 function subscribe_newsburst()
2144 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2147 function subscribe_newsgator()
2149 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2152 function subscribe_odeo()
2154 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2157 function subscribe_podnova()
2159 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2162 function subscribe_rojo()
2164 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2167 function subscribe_yahoo()
2169 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2172 function get_feed_tags($namespace, $tag)
2174 $type = $this->get_type();
2175 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2177 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2179 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2182 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2184 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2186 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2189 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2191 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2193 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2196 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2198 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2200 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2206 function get_channel_tags($namespace, $tag)
2208 $type = $this->get_type();
2209 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2211 if ($return = $this->get_feed_tags($namespace, $tag))
2216 if ($type & SIMPLEPIE_TYPE_RSS_10)
2218 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2220 if (isset($channel[0]['child'][$namespace][$tag]))
2222 return $channel[0]['child'][$namespace][$tag];
2226 if ($type & SIMPLEPIE_TYPE_RSS_090)
2228 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2230 if (isset($channel[0]['child'][$namespace][$tag]))
2232 return $channel[0]['child'][$namespace][$tag];
2236 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2238 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2240 if (isset($channel[0]['child'][$namespace][$tag]))
2242 return $channel[0]['child'][$namespace][$tag];
2249 function get_image_tags($namespace, $tag)
2251 $type = $this->get_type();
2252 if ($type & SIMPLEPIE_TYPE_RSS_10)
2254 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2256 if (isset($image[0]['child'][$namespace][$tag]))
2258 return $image[0]['child'][$namespace][$tag];
2262 if ($type & SIMPLEPIE_TYPE_RSS_090)
2264 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2266 if (isset($image[0]['child'][$namespace][$tag]))
2268 return $image[0]['child'][$namespace][$tag];
2272 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2274 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2276 if (isset($image[0]['child'][$namespace][$tag]))
2278 return $image[0]['child'][$namespace][$tag];
2285 function get_base($element = array())
2287 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2289 return $element['xml_base'];
2291 elseif ($this->get_link() !== null)
2293 return $this->get_link();
2297 return $this->subscribe_url();
2301 function sanitize($data, $type, $base = '')
2303 return $this->sanitize->sanitize($data, $type, $base);
2306 function get_title()
2308 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2310 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2312 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2314 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2316 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2318 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2320 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2322 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2324 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2326 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2328 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2330 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2332 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2334 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2342 function get_category($key = 0)
2344 $categories = $this->get_categories();
2345 if (isset($categories[$key]))
2347 return $categories[$key];
2355 function get_categories()
2357 $categories = array();
2359 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2364 if (isset($category['attribs']['']['term']))
2366 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2368 if (isset($category['attribs']['']['scheme']))
2370 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2372 if (isset($category['attribs']['']['label']))
2374 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2376 $categories[] =& new $this->category_class($term, $scheme, $label);
2378 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2380 // This is really the label, but keep this as the term also for BC.
2381 // Label will also work on retrieving because that falls back to term.
2382 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2383 if (isset($category['attribs']['']['domain']))
2385 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2391 $categories[] =& new $this->category_class($term, $scheme, null);
2393 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2395 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2397 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2399 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2402 if (!empty($categories))
2404 return SimplePie_Misc::array_unique($categories);
2412 function get_author($key = 0)
2414 $authors = $this->get_authors();
2415 if (isset($authors[$key]))
2417 return $authors[$key];
2425 function get_authors()
2428 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2433 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2435 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2437 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2439 $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]));
2441 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2443 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2445 if ($name !== null || $email !== null || $uri !== null)
2447 $authors[] =& new $this->author_class($name, $uri, $email);
2450 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2455 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2457 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2459 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2461 $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]));
2463 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2465 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2467 if ($name !== null || $email !== null || $url !== null)
2469 $authors[] =& new $this->author_class($name, $url, $email);
2472 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2474 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2476 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2478 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2480 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2482 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2485 if (!empty($authors))
2487 return SimplePie_Misc::array_unique($authors);
2495 function get_contributor($key = 0)
2497 $contributors = $this->get_contributors();
2498 if (isset($contributors[$key]))
2500 return $contributors[$key];
2508 function get_contributors()
2510 $contributors = array();
2511 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2516 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2518 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2520 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2522 $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]));
2524 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2526 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2528 if ($name !== null || $email !== null || $uri !== null)
2530 $contributors[] =& new $this->author_class($name, $uri, $email);
2533 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2538 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2540 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2542 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2544 $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]));
2546 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2548 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2550 if ($name !== null || $email !== null || $url !== null)
2552 $contributors[] =& new $this->author_class($name, $url, $email);
2556 if (!empty($contributors))
2558 return SimplePie_Misc::array_unique($contributors);
2566 function get_link($key = 0, $rel = 'alternate')
2568 $links = $this->get_links($rel);
2569 if (isset($links[$key]))
2571 return $links[$key];
2580 * Added for parity between the parent-level and the item/entry-level.
2582 function get_permalink()
2584 return $this->get_link(0);
2587 function get_links($rel = 'alternate')
2589 if (!isset($this->data['links']))
2591 $this->data['links'] = array();
2592 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2594 foreach ($links as $link)
2596 if (isset($link['attribs']['']['href']))
2598 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2599 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2603 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2605 foreach ($links as $link)
2607 if (isset($link['attribs']['']['href']))
2609 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2610 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2615 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2617 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2619 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2621 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2623 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2625 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2628 $keys = array_keys($this->data['links']);
2629 foreach ($keys as $key)
2631 if (SimplePie_Misc::is_isegment_nz_nc($key))
2633 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2635 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2636 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2640 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2643 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2645 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2647 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2651 if (isset($this->data['links'][$rel]))
2653 return $this->data['links'][$rel];
2661 function get_all_discovered_feeds()
2663 return $this->all_discovered_feeds;
2666 function get_description()
2668 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2670 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2672 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2674 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2676 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2678 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2680 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2682 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2684 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2688 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2692 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2696 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2700 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2710 function get_copyright()
2712 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2714 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2716 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2718 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2720 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2722 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2724 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2726 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2728 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2730 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2738 function get_language()
2740 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2742 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2744 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2746 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2748 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2750 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2754 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2756 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2758 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2760 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2762 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2764 elseif (isset($this->data['headers']['content-language']))
2766 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2774 function get_latitude()
2776 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2778 return (float) $return[0]['data'];
2780 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2782 return (float) $match[1];
2790 function get_longitude()
2792 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2794 return (float) $return[0]['data'];
2796 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2798 return (float) $return[0]['data'];
2800 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2802 return (float) $match[2];
2810 function get_image_title()
2812 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2814 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2816 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2818 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2820 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2822 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2824 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2826 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2828 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2830 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2838 function get_image_url()
2840 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2842 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2844 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2846 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2848 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2850 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2852 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2854 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2856 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2858 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2860 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2862 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2870 function get_image_link()
2872 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2874 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2876 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2878 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2880 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2882 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2890 function get_image_width()
2892 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2894 return round($return[0]['data']);
2896 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2906 function get_image_height()
2908 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2910 return round($return[0]['data']);
2912 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2922 function get_item_quantity($max = 0)
2925 $qty = count($this->get_items());
2932 return ($qty > $max) ? $max : $qty;
2936 function get_item($key = 0)
2938 $items = $this->get_items();
2939 if (isset($items[$key]))
2941 return $items[$key];
2949 function get_items($start = 0, $end = 0)
2951 if (!isset($this->data['items']))
2953 if (!empty($this->multifeed_objects))
2955 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2959 $this->data['items'] = array();
2960 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2962 $keys = array_keys($items);
2963 foreach ($keys as $key)
2965 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2968 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2970 $keys = array_keys($items);
2971 foreach ($keys as $key)
2973 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2976 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2978 $keys = array_keys($items);
2979 foreach ($keys as $key)
2981 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2984 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2986 $keys = array_keys($items);
2987 foreach ($keys as $key)
2989 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2992 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2994 $keys = array_keys($items);
2995 foreach ($keys as $key)
2997 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
3003 if (!empty($this->data['items']))
3005 // If we want to order it by date, check if all items have a date, and then sort it
3006 if ($this->order_by_date && empty($this->multifeed_objects))
3008 if (!isset($this->data['ordered_items']))
3011 foreach ($this->data['items'] as $item)
3013 if (!$item->get_date('U'))
3020 $this->data['ordered_items'] = $this->data['items'];
3023 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3026 $items = $this->data['ordered_items'];
3030 $items = $this->data['items'];
3033 // Slice the data as desired
3036 return array_slice($items, $start);
3040 return array_slice($items, $start, $end);
3052 function sort_items($a, $b)
3054 return $a->get_date('U') <= $b->get_date('U');
3060 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3062 if (is_array($urls) && sizeof($urls) > 0)
3065 foreach ($urls as $arg)
3067 if (is_a($arg, 'SimplePie'))
3069 $items = array_merge($items, $arg->get_items(0, $limit));
3073 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3078 foreach ($items as $item)
3080 if (!$item->get_date('U'))
3089 usort($items, array('SimplePie', 'sort_items'));
3094 return array_slice($items, $start);
3098 return array_slice($items, $start, $end);
3103 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3109 class SimplePie_Item
3112 var $data = array();
3114 function SimplePie_Item($feed, $data)
3116 $this->feed = $feed;
3117 $this->data = $data;
3120 function __toString()
3122 return md5(serialize($this->data));
3126 * Remove items that link back to this before destroying this object
3128 function __destruct()
3130 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3136 function get_item_tags($namespace, $tag)
3138 if (isset($this->data['child'][$namespace][$tag]))
3140 return $this->data['child'][$namespace][$tag];
3148 function get_base($element = array())
3150 return $this->feed->get_base($element);
3153 function sanitize($data, $type, $base = '')
3155 return $this->feed->sanitize($data, $type, $base);
3163 function get_id($hash = false)
3167 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3169 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3171 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3173 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3175 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3177 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3179 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3181 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3183 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3185 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3187 elseif (($return = $this->get_permalink()) !== null)
3191 elseif (($return = $this->get_title()) !== null)
3196 if ($this->get_permalink() !== null || $this->get_title() !== null)
3198 return md5($this->get_permalink() . $this->get_title());
3202 return md5(serialize($this->data));
3206 function get_title()
3208 if (!isset($this->data['title']))
3210 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3212 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3214 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3216 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3218 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3220 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3222 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3224 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3226 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3228 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3232 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3236 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3240 $this->data['title'] = null;
3243 return $this->data['title'];
3246 function get_description($description_only = false)
3248 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3250 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3252 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3254 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3256 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3258 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3260 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
3262 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3264 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))