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-2008, 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-2008 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.1.3');
59 define('SIMPLEPIE_BUILD', 20081219);
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);
245 * PCRE for HTML attributes
247 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]*');
250 * PCRE for XML attributes
252 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
257 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
262 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
267 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
272 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
277 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
282 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
285 * RSS 1.0 Content Module Namespace
287 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
291 * (Stupid, I know, but I'm certain it will confuse people less with support.)
293 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
298 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
303 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
306 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
308 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
313 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
316 * Media RSS Namespace
318 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
321 * Wrong Media RSS Namespace
323 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
326 * iTunes RSS Namespace
328 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
333 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
336 * IANA Link Relations Registry
338 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
341 * Whether we're running on PHP5
343 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
348 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
353 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
358 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
361 * fsockopen() file source
363 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
368 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
371 * file_get_contents() file source
373 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
379 * @version "Razzleberry"
380 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
381 * @author Ryan Parman
382 * @author Geoffrey Sneddon
383 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
388 * @var array Raw data
394 * @var mixed Error string
400 * @var object Instance of SimplePie_Sanitize (or other class)
401 * @see SimplePie::set_sanitize_class()
407 * @var string SimplePie Useragent
408 * @see SimplePie::set_useragent()
411 var $useragent = SIMPLEPIE_USERAGENT;
414 * @var string Feed URL
415 * @see SimplePie::set_feed_url()
421 * @var object Instance of SimplePie_File to use as a feed
422 * @see SimplePie::set_file()
428 * @var string Raw feed data
429 * @see SimplePie::set_raw_data()
435 * @var int Timeout for fetching remote files
436 * @see SimplePie::set_timeout()
442 * @var bool Forces fsockopen() to be used for remote files instead
443 * of cURL, even if a new enough version is installed
444 * @see SimplePie::force_fsockopen()
447 var $force_fsockopen = false;
450 * @var bool Force the given data/URL to be treated as a feed no matter what
452 * @see SimplePie::force_feed()
455 var $force_feed = false;
458 * @var bool Enable/Disable XML dump
459 * @see SimplePie::enable_xml_dump()
462 var $xml_dump = false;
465 * @var bool Enable/Disable Caching
466 * @see SimplePie::enable_cache()
472 * @var int Cache duration (in seconds)
473 * @see SimplePie::set_cache_duration()
476 var $cache_duration = 3600;
479 * @var int Auto-discovery cache duration (in seconds)
480 * @see SimplePie::set_autodiscovery_cache_duration()
483 var $autodiscovery_cache_duration = 604800; // 7 Days.
486 * @var string Cache location (relative to executing script)
487 * @see SimplePie::set_cache_location()
490 var $cache_location = './cache';
493 * @var string Function that creates the cache filename
494 * @see SimplePie::set_cache_name_function()
497 var $cache_name_function = 'md5';
500 * @var bool Reorder feed by date descending
501 * @see SimplePie::enable_order_by_date()
504 var $order_by_date = true;
507 * @var mixed Force input encoding to be set to the follow value
508 * (false, or anything type-cast to false, disables this feature)
509 * @see SimplePie::set_input_encoding()
512 var $input_encoding = false;
515 * @var int Feed Autodiscovery Level
516 * @see SimplePie::set_autodiscovery_level()
519 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
522 * @var string Class used for caching feeds
523 * @see SimplePie::set_cache_class()
526 var $cache_class = 'SimplePie_Cache';
529 * @var string Class used for locating feeds
530 * @see SimplePie::set_locator_class()
533 var $locator_class = 'SimplePie_Locator';
536 * @var string Class used for parsing feeds
537 * @see SimplePie::set_parser_class()
540 var $parser_class = 'SimplePie_Parser';
543 * @var string Class used for fetching feeds
544 * @see SimplePie::set_file_class()
547 var $file_class = 'SimplePie_File';
550 * @var string Class used for items
551 * @see SimplePie::set_item_class()
554 var $item_class = 'SimplePie_Item';
557 * @var string Class used for authors
558 * @see SimplePie::set_author_class()
561 var $author_class = 'SimplePie_Author';
564 * @var string Class used for categories
565 * @see SimplePie::set_category_class()
568 var $category_class = 'SimplePie_Category';
571 * @var string Class used for enclosures
572 * @see SimplePie::set_enclosures_class()
575 var $enclosure_class = 'SimplePie_Enclosure';
578 * @var string Class used for Media RSS <media:text> captions
579 * @see SimplePie::set_caption_class()
582 var $caption_class = 'SimplePie_Caption';
585 * @var string Class used for Media RSS <media:copyright>
586 * @see SimplePie::set_copyright_class()
589 var $copyright_class = 'SimplePie_Copyright';
592 * @var string Class used for Media RSS <media:credit>
593 * @see SimplePie::set_credit_class()
596 var $credit_class = 'SimplePie_Credit';
599 * @var string Class used for Media RSS <media:rating>
600 * @see SimplePie::set_rating_class()
603 var $rating_class = 'SimplePie_Rating';
606 * @var string Class used for Media RSS <media:restriction>
607 * @see SimplePie::set_restriction_class()
610 var $restriction_class = 'SimplePie_Restriction';
613 * @var string Class used for content-type sniffing
614 * @see SimplePie::set_content_type_sniffer_class()
617 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
620 * @var string Class used for item sources.
621 * @see SimplePie::set_source_class()
624 var $source_class = 'SimplePie_Source';
627 * @var mixed Set javascript query string parameter (false, or
628 * anything type-cast to false, disables this feature)
629 * @see SimplePie::set_javascript()
632 var $javascript = 'js';
635 * @var int Maximum number of feeds to check with autodiscovery
636 * @see SimplePie::set_max_checked_feeds()
639 var $max_checked_feeds = 10;
642 * @var string Web-accessible path to the handler_favicon.php file.
643 * @see SimplePie::set_favicon_handler()
646 var $favicon_handler = '';
649 * @var string Web-accessible path to the handler_image.php file.
650 * @see SimplePie::set_image_handler()
653 var $image_handler = '';
656 * @var array Stores the URLs when multiple feeds are being initialized.
657 * @see SimplePie::set_feed_url()
660 var $multifeed_url = array();
663 * @var array Stores SimplePie objects when multiple feeds initialized.
666 var $multifeed_objects = array();
669 * @var array Stores the get_object_vars() array for use with multifeeds.
670 * @see SimplePie::set_feed_url()
673 var $config_settings = null;
676 * @var integer Stores the number of items to return per-feed with multifeeds.
677 * @see SimplePie::set_item_limit()
683 * @var array Stores the default attributes to be stripped by strip_attributes().
684 * @see SimplePie::strip_attributes()
687 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
690 * @var array Stores the default tags to be stripped by strip_htmltags().
691 * @see SimplePie::strip_htmltags()
694 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
697 * The SimplePie class contains feed level data and options
699 * There are two ways that you can create a new SimplePie object. The first
700 * is by passing a feed URL as a parameter to the SimplePie constructor
701 * (as well as optionally setting the cache location and cache expiry). This
702 * will initialise the whole feed with all of the default settings, and you
703 * can begin accessing methods and properties immediately.
705 * The second way is to create the SimplePie object with no parameters
706 * at all. This will enable you to set configuration options. After setting
707 * them, you must initialise the feed using $feed->init(). At that point the
708 * object's methods and properties will be available to you. This format is
709 * what is used throughout this documentation.
712 * @since 1.0 Preview Release
713 * @param string $feed_url This is the URL you want to parse.
714 * @param string $cache_location This is where you want the cache to be stored.
715 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
717 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
719 // Other objects, instances created here so we can set options on them
720 $this->sanitize =& new SimplePie_Sanitize;
722 // Set options if they're passed to the constructor
723 if ($cache_location !== null)
725 $this->set_cache_location($cache_location);
728 if ($cache_duration !== null)
730 $this->set_cache_duration($cache_duration);
733 // Only init the script if we're passed a feed URL
734 if ($feed_url !== null)
736 $this->set_feed_url($feed_url);
742 * Used for converting object to a string
744 function __toString()
746 return md5(serialize($this->data));
750 * Remove items that link back to this before destroying this object
752 function __destruct()
754 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
756 if (!empty($this->data['items']))
758 foreach ($this->data['items'] as $item)
762 unset($item, $this->data['items']);
764 if (!empty($this->data['ordered_items']))
766 foreach ($this->data['ordered_items'] as $item)
770 unset($item, $this->data['ordered_items']);
776 * Force the given data/URL to be treated as a feed no matter what it
781 * @param bool $enable Force the given data/URL to be treated as a feed
783 function force_feed($enable = false)
785 $this->force_feed = (bool) $enable;
789 * This is the URL of the feed you want to parse.
791 * This allows you to enter the URL of the feed you want to parse, or the
792 * website you want to try to use auto-discovery on. This takes priority
793 * over any set raw data.
795 * You can set multiple feeds to mash together by passing an array instead
796 * of a string for the $url. Remember that with each additional feed comes
797 * additional processing and resources.
800 * @since 1.0 Preview Release
801 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
802 * @see SimplePie::set_raw_data()
804 function set_feed_url($url)
808 $this->multifeed_url = array();
809 foreach ($url as $value)
811 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
816 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
821 * Provides an instance of SimplePie_File to use as a feed
824 * @param object &$file Instance of SimplePie_File (or subclass)
825 * @return bool True on success, false on failure
827 function set_file(&$file)
829 if (is_a($file, 'SimplePie_File'))
831 $this->feed_url = $file->url;
832 $this->file =& $file;
839 * Allows you to use a string of RSS/Atom data instead of a remote feed.
841 * If you have a feed available as a string in PHP, you can tell SimplePie
842 * to parse that data string instead of a remote feed. Any set feed URL
847 * @param string $data RSS or Atom data as a string.
848 * @see SimplePie::set_feed_url()
850 function set_raw_data($data)
852 $this->raw_data = $data;
856 * Allows you to override the default timeout for fetching remote feeds.
858 * This allows you to change the maximum time the feed's server to respond
859 * and send the feed back.
863 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
865 function set_timeout($timeout = 10)
867 $this->timeout = (int) $timeout;
871 * Forces SimplePie to use fsockopen() instead of the preferred cURL
876 * @param bool $enable Force fsockopen() to be used
878 function force_fsockopen($enable = false)
880 $this->force_fsockopen = (bool) $enable;
884 * Outputs the raw XML content of the feed, after it has gone through
885 * SimplePie's filters.
887 * Used only for debugging, this function will output the XML content as
888 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
889 * before trying to parse it. Many parts of the feed are re-written in
890 * memory, and in the end, you have a parsable feed. XML dump shows you the
891 * actual XML that SimplePie tries to parse, which may or may not be very
892 * different from the original feed.
895 * @since 1.0 Preview Release
896 * @param bool $enable Enable XML dump
898 function enable_xml_dump($enable = false)
900 $this->xml_dump = (bool) $enable;
904 * Enables/disables caching in SimplePie.
906 * This option allows you to disable caching all-together in SimplePie.
907 * However, disabling the cache can lead to longer load times.
910 * @since 1.0 Preview Release
911 * @param bool $enable Enable caching
913 function enable_cache($enable = true)
915 $this->cache = (bool) $enable;
919 * Set the length of time (in seconds) that the contents of a feed
923 * @param int $seconds The feed content cache duration.
925 function set_cache_duration($seconds = 3600)
927 $this->cache_duration = (int) $seconds;
931 * Set the length of time (in seconds) that the autodiscovered feed
932 * URL will be cached.
935 * @param int $seconds The autodiscovered feed URL cache duration.
937 function set_autodiscovery_cache_duration($seconds = 604800)
939 $this->autodiscovery_cache_duration = (int) $seconds;
943 * Set the file system location where the cached files should be stored.
946 * @param string $location The file system location.
948 function set_cache_location($location = './cache')
950 $this->cache_location = (string) $location;
954 * Determines whether feed items should be sorted into reverse chronological order.
957 * @param bool $enable Sort as reverse chronological order.
959 function enable_order_by_date($enable = true)
961 $this->order_by_date = (bool) $enable;
965 * Allows you to override the character encoding reported by the feed.
968 * @param string $encoding Character encoding.
970 function set_input_encoding($encoding = false)
974 $this->input_encoding = (string) $encoding;
978 $this->input_encoding = false;
983 * Set how much feed autodiscovery to do
986 * @see SIMPLEPIE_LOCATOR_NONE
987 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
988 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
989 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
990 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
991 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
992 * @see SIMPLEPIE_LOCATOR_ALL
993 * @param int $level Feed Autodiscovery Level (level can be a
994 * combination of the above constants, see bitwise OR operator)
996 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
998 $this->autodiscovery = (int) $level;
1002 * Allows you to change which class SimplePie uses for caching.
1003 * Useful when you are overloading or extending SimplePie's default classes.
1006 * @param string $class Name of custom class.
1007 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1008 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1010 function set_cache_class($class = 'SimplePie_Cache')
1012 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1014 $this->cache_class = $class;
1021 * Allows you to change which class SimplePie uses for auto-discovery.
1022 * Useful when you are overloading or extending SimplePie's default classes.
1025 * @param string $class Name of custom class.
1026 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1027 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1029 function set_locator_class($class = 'SimplePie_Locator')
1031 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1033 $this->locator_class = $class;
1040 * Allows you to change which class SimplePie uses for XML parsing.
1041 * Useful when you are overloading or extending SimplePie's default classes.
1044 * @param string $class Name of custom class.
1045 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1046 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1048 function set_parser_class($class = 'SimplePie_Parser')
1050 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1052 $this->parser_class = $class;
1059 * Allows you to change which class SimplePie uses for remote file fetching.
1060 * Useful when you are overloading or extending SimplePie's default classes.
1063 * @param string $class Name of custom class.
1064 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1065 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1067 function set_file_class($class = 'SimplePie_File')
1069 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1071 $this->file_class = $class;
1078 * Allows you to change which class SimplePie uses for data sanitization.
1079 * Useful when you are overloading or extending SimplePie's default classes.
1082 * @param string $class Name of custom class.
1083 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1084 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1086 function set_sanitize_class($class = 'SimplePie_Sanitize')
1088 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1090 $this->sanitize =& new $class;
1097 * Allows you to change which class SimplePie uses for handling feed items.
1098 * Useful when you are overloading or extending SimplePie's default classes.
1101 * @param string $class Name of custom class.
1102 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1103 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1105 function set_item_class($class = 'SimplePie_Item')
1107 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1109 $this->item_class = $class;
1116 * Allows you to change which class SimplePie uses for handling author data.
1117 * Useful when you are overloading or extending SimplePie's default classes.
1120 * @param string $class Name of custom class.
1121 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1122 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1124 function set_author_class($class = 'SimplePie_Author')
1126 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1128 $this->author_class = $class;
1135 * Allows you to change which class SimplePie uses for handling category data.
1136 * Useful when you are overloading or extending SimplePie's default classes.
1139 * @param string $class Name of custom class.
1140 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1141 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1143 function set_category_class($class = 'SimplePie_Category')
1145 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1147 $this->category_class = $class;
1154 * Allows you to change which class SimplePie uses for feed enclosures.
1155 * Useful when you are overloading or extending SimplePie's default classes.
1158 * @param string $class Name of custom class.
1159 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1160 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1162 function set_enclosure_class($class = 'SimplePie_Enclosure')
1164 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1166 $this->enclosure_class = $class;
1173 * Allows you to change which class SimplePie uses for <media:text> captions
1174 * Useful when you are overloading or extending SimplePie's default classes.
1177 * @param string $class Name of custom class.
1178 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1179 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1181 function set_caption_class($class = 'SimplePie_Caption')
1183 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1185 $this->caption_class = $class;
1192 * Allows you to change which class SimplePie uses for <media:copyright>
1193 * Useful when you are overloading or extending SimplePie's default classes.
1196 * @param string $class Name of custom class.
1197 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1198 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1200 function set_copyright_class($class = 'SimplePie_Copyright')
1202 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1204 $this->copyright_class = $class;
1211 * Allows you to change which class SimplePie uses for <media:credit>
1212 * Useful when you are overloading or extending SimplePie's default classes.
1215 * @param string $class Name of custom class.
1216 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1217 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1219 function set_credit_class($class = 'SimplePie_Credit')
1221 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1223 $this->credit_class = $class;
1230 * Allows you to change which class SimplePie uses for <media:rating>
1231 * Useful when you are overloading or extending SimplePie's default classes.
1234 * @param string $class Name of custom class.
1235 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1236 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1238 function set_rating_class($class = 'SimplePie_Rating')
1240 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1242 $this->rating_class = $class;
1249 * Allows you to change which class SimplePie uses for <media:restriction>
1250 * Useful when you are overloading or extending SimplePie's default classes.
1253 * @param string $class Name of custom class.
1254 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1255 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1257 function set_restriction_class($class = 'SimplePie_Restriction')
1259 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1261 $this->restriction_class = $class;
1268 * Allows you to change which class SimplePie uses for content-type sniffing.
1269 * Useful when you are overloading or extending SimplePie's default classes.
1272 * @param string $class Name of custom class.
1273 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1274 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1276 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1278 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1280 $this->content_type_sniffer_class = $class;
1287 * Allows you to change which class SimplePie uses item sources.
1288 * Useful when you are overloading or extending SimplePie's default classes.
1291 * @param string $class Name of custom class.
1292 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1293 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1295 function set_source_class($class = 'SimplePie_Source')
1297 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1299 $this->source_class = $class;
1306 * Allows you to override the default user agent string.
1309 * @param string $ua New user agent string.
1311 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1313 $this->useragent = (string) $ua;
1317 * Set callback function to create cache filename with
1320 * @param mixed $function Callback function
1322 function set_cache_name_function($function = 'md5')
1324 if (is_callable($function))
1326 $this->cache_name_function = $function;
1331 * Set javascript query string parameter
1334 * @param mixed $get Javascript query string parameter
1336 function set_javascript($get = 'js')
1340 $this->javascript = (string) $get;
1344 $this->javascript = false;
1349 * Set options to make SP as fast as possible. Forgoes a
1350 * substantial amount of data sanitization in favor of speed.
1353 * @param bool $set Whether to set them or not
1355 function set_stupidly_fast($set = false)
1359 $this->enable_order_by_date(false);
1360 $this->remove_div(false);
1361 $this->strip_comments(false);
1362 $this->strip_htmltags(false);
1363 $this->strip_attributes(false);
1364 $this->set_image_handler(false);
1369 * Set maximum number of feeds to check with autodiscovery
1372 * @param int $max Maximum number of feeds to check
1374 function set_max_checked_feeds($max = 10)
1376 $this->max_checked_feeds = (int) $max;
1379 function remove_div($enable = true)
1381 $this->sanitize->remove_div($enable);
1384 function strip_htmltags($tags = '', $encode = null)
1388 $tags = $this->strip_htmltags;
1390 $this->sanitize->strip_htmltags($tags);
1391 if ($encode !== null)
1393 $this->sanitize->encode_instead_of_strip($tags);
1397 function encode_instead_of_strip($enable = true)
1399 $this->sanitize->encode_instead_of_strip($enable);
1402 function strip_attributes($attribs = '')
1404 if ($attribs === '')
1406 $attribs = $this->strip_attributes;
1408 $this->sanitize->strip_attributes($attribs);
1411 function set_output_encoding($encoding = 'UTF-8')
1413 $this->sanitize->set_output_encoding($encoding);
1416 function strip_comments($strip = false)
1418 $this->sanitize->strip_comments($strip);
1422 * Set element/attribute key/value pairs of HTML attributes
1423 * containing URLs that need to be resolved relative to the feed
1427 * @param array $element_attribute Element/attribute key/value pairs
1429 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'))
1431 $this->sanitize->set_url_replacements($element_attribute);
1435 * Set the handler to enable the display of cached favicons.
1438 * @param str $page Web-accessible path to the handler_favicon.php file.
1439 * @param str $qs The query string that the value should be passed to.
1441 function set_favicon_handler($page = false, $qs = 'i')
1445 $this->favicon_handler = $page . '?' . $qs . '=';
1449 $this->favicon_handler = '';
1454 * Set the handler to enable the display of cached images.
1457 * @param str $page Web-accessible path to the handler_image.php file.
1458 * @param str $qs The query string that the value should be passed to.
1460 function set_image_handler($page = false, $qs = 'i')
1464 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1468 $this->image_handler = '';
1473 * Set the limit for items returned per-feed with multifeeds.
1476 * @param integer $limit The maximum number of items to return.
1478 function set_item_limit($limit = 0)
1480 $this->item_limit = (int) $limit;
1485 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1489 if (isset($_GET[$this->javascript]))
1491 if (function_exists('ob_gzhandler'))
1493 ob_start('ob_gzhandler');
1495 header('Content-type: text/javascript; charset: UTF-8');
1496 header('Cache-Control: must-revalidate');
1497 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1499 function embed_odeo(link) {
1500 document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
1503 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1504 if (placeholder != '') {
1505 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1508 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1512 function embed_flash(bgcolor, width, height, link, loop, type) {
1513 document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
1516 function embed_flv(width, height, link, placeholder, loop, player) {
1517 document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
1520 function embed_wmedia(width, height, link) {
1521 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1527 // Pass whatever was set with config options over to the sanitizer.
1528 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1529 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1531 if ($this->feed_url !== null || $this->raw_data !== null)
1533 $this->data = array();
1534 $this->multifeed_objects = array();
1537 if ($this->feed_url !== null)
1539 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1540 // Decide whether to enable caching
1541 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1543 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1545 // If it's enabled and we don't want an XML dump, use the cache
1546 if ($cache && !$this->xml_dump)
1549 $this->data = $cache->load();
1550 if (!empty($this->data))
1552 // If the cache is for an outdated build of SimplePie
1553 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1556 $this->data = array();
1558 // If we've hit a collision just rerun it with caching disabled
1559 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1562 $this->data = array();
1564 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1565 elseif (isset($this->data['feed_url']))
1567 // If the autodiscovery cache is still valid use it.
1568 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1570 // Do not need to do feed autodiscovery yet.
1571 if ($this->data['feed_url'] == $this->data['url'])
1574 $this->data = array();
1578 $this->set_feed_url($this->data['feed_url']);
1579 return $this->init();
1583 // Check if the cache has been updated
1584 elseif ($cache->mtime() + $this->cache_duration < time())
1586 // If we have last-modified and/or etag set
1587 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1590 if (isset($this->data['headers']['last-modified']))
1592 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1594 if (isset($this->data['headers']['etag']))
1596 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1598 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1601 if ($file->status_code == 304)
1608 $headers = $file->headers;
1617 // If the cache is still valid, just return true
1623 // If the cache is empty, delete it
1627 $this->data = array();
1630 // 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.
1633 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1635 $file =& $this->file;
1639 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1642 // If the file connection has an error, set SimplePie::error to that and quit
1643 if (!$file->success)
1645 $this->error = $file->error;
1646 if (!empty($this->data))
1656 if (!$this->force_feed)
1658 // Check if the supplied URL is a feed, if it isn't, look for it.
1659 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1660 if (!$locate->is_feed($file))
1662 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1664 if ($file = $locate->find($this->autodiscovery))
1668 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1669 if (!$cache->save($this))
1671 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1673 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1675 $this->feed_url = $file->url;
1679 $this->error = "A feed could not be found at $this->feed_url";
1680 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1687 $headers = $file->headers;
1688 $data = $file->body;
1689 $sniffer =& new $this->content_type_sniffer_class($file);
1690 $sniffed = $sniffer->get_type();
1694 $data = $this->raw_data;
1697 // Set up array of possible encodings
1698 $encodings = array();
1700 // First check to see if input has been overridden.
1701 if ($this->input_encoding !== false)
1703 $encodings[] = $this->input_encoding;
1706 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1707 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1709 // RFC 3023 (only applies to sniffed content)
1710 if (isset($sniffed))
1712 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1714 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1716 $encodings[] = strtoupper($charset[1]);
1718 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1719 $encodings[] = 'UTF-8';
1721 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1723 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1725 $encodings[] = $charset[1];
1727 $encodings[] = 'US-ASCII';
1729 // Text MIME-type default
1730 elseif (substr($sniffed, 0, 5) === 'text/')
1732 $encodings[] = 'US-ASCII';
1736 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1737 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1738 $encodings[] = 'UTF-8';
1739 $encodings[] = 'ISO-8859-1';
1741 // There's no point in trying an encoding twice
1742 $encodings = array_unique($encodings);
1744 // If we want the XML, just output that with the most likely encoding and quit
1745 if ($this->xml_dump)
1747 header('Content-type: text/xml; charset=' . $encodings[0]);
1752 // Loop through each possible encoding, till we return something, or run out of possibilities
1753 foreach ($encodings as $encoding)
1755 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1756 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1758 // Create new parser
1759 $parser =& new $this->parser_class();
1761 // If it's parsed fine
1762 if ($parser->parse($utf8_data, 'UTF-8'))
1764 $this->data = $parser->get_data();
1765 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1767 if (isset($headers))
1769 $this->data['headers'] = $headers;
1771 $this->data['build'] = SIMPLEPIE_BUILD;
1773 // Cache the file if caching is enabled
1774 if ($cache && !$cache->save($this))
1776 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1782 $this->error = "A feed could not be found at $this->feed_url";
1783 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1789 // We have an error, just set SimplePie::error to it and quit
1790 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1791 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1794 elseif (!empty($this->multifeed_url))
1798 $this->multifeed_objects = array();
1799 foreach ($this->multifeed_url as $url)
1803 // This keyword needs to defy coding standards for PHP4 compatibility
1804 $this->multifeed_objects[$i] = clone($this);
1808 $this->multifeed_objects[$i] = $this;
1810 $this->multifeed_objects[$i]->set_feed_url($url);
1811 $success |= $this->multifeed_objects[$i]->init();
1814 return (bool) $success;
1823 * Return the error message for the occured error
1826 * @return string Error message
1830 return $this->error;
1833 function get_encoding()
1835 return $this->sanitize->output_encoding;
1838 function handle_content_type($mime = 'text/html')
1840 if (!headers_sent())
1842 $header = "Content-type: $mime;";
1843 if ($this->get_encoding())
1845 $header .= ' charset=' . $this->get_encoding();
1849 $header .= ' charset=UTF-8';
1857 if (!isset($this->data['type']))
1859 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1860 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1862 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1864 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1866 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1868 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1870 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1871 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1872 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1873 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1875 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1877 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1878 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1879 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1880 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1882 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1885 elseif (isset($this->data['child']['']['rss']))
1887 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1888 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1890 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1893 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1894 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1896 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1899 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1918 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1922 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1929 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1932 return $this->data['type'];
1936 * Returns the URL for the favicon of the feed's website.
1938 * @todo Cache atom:icon
1942 function get_favicon()
1944 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1946 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1948 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1950 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1952 if ($this->cache && $this->favicon_handler)
1954 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1955 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1959 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1963 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1965 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1967 $sniffer =& new $this->content_type_sniffer_class($file);
1968 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1970 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1972 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1976 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1977 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1985 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1992 * @todo If we have a perm redirect we should return the new URL
1993 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1994 * @todo Also, |atom:link|@rel=self
1996 function subscribe_url()
1998 if ($this->feed_url !== null)
2000 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2008 function subscribe_feed()
2010 if ($this->feed_url !== null)
2012 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2020 function subscribe_outlook()
2022 if ($this->feed_url !== null)
2024 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2032 function subscribe_podcast()
2034 if ($this->feed_url !== null)
2036 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2044 function subscribe_itunes()
2046 if ($this->feed_url !== null)
2048 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2057 * Creates the subscribe_* methods' return data
2060 * @param string $feed_url String to prefix to the feed URL
2061 * @param string $site_url String to prefix to the site URL (and
2062 * suffix to the feed URL)
2063 * @return mixed URL if feed exists, false otherwise
2065 function subscribe_service($feed_url, $site_url = null)
2067 if ($this->subscribe_url())
2069 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2070 if ($site_url !== null && $this->get_link() !== null)
2072 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2082 function subscribe_aol()
2084 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2087 function subscribe_bloglines()
2089 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2092 function subscribe_eskobo()
2094 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2097 function subscribe_feedfeeds()
2099 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2102 function subscribe_feedster()
2104 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2107 function subscribe_google()
2109 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2112 function subscribe_gritwire()
2114 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2117 function subscribe_msn()
2119 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2122 function subscribe_netvibes()
2124 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2127 function subscribe_newsburst()
2129 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2132 function subscribe_newsgator()
2134 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2137 function subscribe_odeo()
2139 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2142 function subscribe_podnova()
2144 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2147 function subscribe_rojo()
2149 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2152 function subscribe_yahoo()
2154 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2157 function get_feed_tags($namespace, $tag)
2159 $type = $this->get_type();
2160 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2162 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2164 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2167 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2169 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2171 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2174 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2176 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2178 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2181 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2183 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2185 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2191 function get_channel_tags($namespace, $tag)
2193 $type = $this->get_type();
2194 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2196 if ($return = $this->get_feed_tags($namespace, $tag))
2201 if ($type & SIMPLEPIE_TYPE_RSS_10)
2203 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2205 if (isset($channel[0]['child'][$namespace][$tag]))
2207 return $channel[0]['child'][$namespace][$tag];
2211 if ($type & SIMPLEPIE_TYPE_RSS_090)
2213 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2215 if (isset($channel[0]['child'][$namespace][$tag]))
2217 return $channel[0]['child'][$namespace][$tag];
2221 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2223 if ($channel = $this->get_feed_tags('', 'channel'))
2225 if (isset($channel[0]['child'][$namespace][$tag]))
2227 return $channel[0]['child'][$namespace][$tag];
2234 function get_image_tags($namespace, $tag)
2236 $type = $this->get_type();
2237 if ($type & SIMPLEPIE_TYPE_RSS_10)
2239 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2241 if (isset($image[0]['child'][$namespace][$tag]))
2243 return $image[0]['child'][$namespace][$tag];
2247 if ($type & SIMPLEPIE_TYPE_RSS_090)
2249 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2251 if (isset($image[0]['child'][$namespace][$tag]))
2253 return $image[0]['child'][$namespace][$tag];
2257 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2259 if ($image = $this->get_channel_tags('', 'image'))
2261 if (isset($image[0]['child'][$namespace][$tag]))
2263 return $image[0]['child'][$namespace][$tag];
2270 function get_base($element = array())
2272 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2274 return $element['xml_base'];
2276 elseif ($this->get_link() !== null)
2278 return $this->get_link();
2282 return $this->subscribe_url();
2286 function sanitize($data, $type, $base = '')
2288 return $this->sanitize->sanitize($data, $type, $base);
2291 function get_title()
2293 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2295 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2297 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2299 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2301 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2303 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2307 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2309 elseif ($return = $this->get_channel_tags('', 'title'))
2311 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2313 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2315 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2317 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2319 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2327 function get_category($key = 0)
2329 $categories = $this->get_categories();
2330 if (isset($categories[$key]))
2332 return $categories[$key];
2340 function get_categories()
2342 $categories = array();
2344 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2349 if (isset($category['attribs']['']['term']))
2351 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2353 if (isset($category['attribs']['']['scheme']))
2355 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2357 if (isset($category['attribs']['']['label']))
2359 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2361 $categories[] =& new $this->category_class($term, $scheme, $label);
2363 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2365 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2369 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2373 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2376 if (!empty($categories))
2378 return SimplePie_Misc::array_unique($categories);
2386 function get_author($key = 0)
2388 $authors = $this->get_authors();
2389 if (isset($authors[$key]))
2391 return $authors[$key];
2399 function get_authors()
2402 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2407 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2409 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2411 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2413 $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]));
2415 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2417 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2419 if ($name !== null || $email !== null || $uri !== null)
2421 $authors[] =& new $this->author_class($name, $uri, $email);
2424 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2429 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2431 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2433 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2435 $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]));
2437 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2439 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2441 if ($name !== null || $email !== null || $url !== null)
2443 $authors[] =& new $this->author_class($name, $url, $email);
2446 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2448 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2452 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2456 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2459 if (!empty($authors))
2461 return SimplePie_Misc::array_unique($authors);
2469 function get_contributor($key = 0)
2471 $contributors = $this->get_contributors();
2472 if (isset($contributors[$key]))
2474 return $contributors[$key];
2482 function get_contributors()
2484 $contributors = array();
2485 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2490 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2492 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2494 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2496 $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]));
2498 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2500 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2502 if ($name !== null || $email !== null || $uri !== null)
2504 $contributors[] =& new $this->author_class($name, $uri, $email);
2507 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2512 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2514 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2516 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2518 $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]));
2520 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2522 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2524 if ($name !== null || $email !== null || $url !== null)
2526 $contributors[] =& new $this->author_class($name, $url, $email);
2530 if (!empty($contributors))
2532 return SimplePie_Misc::array_unique($contributors);
2540 function get_link($key = 0, $rel = 'alternate')
2542 $links = $this->get_links($rel);
2543 if (isset($links[$key]))
2545 return $links[$key];
2554 * Added for parity between the parent-level and the item/entry-level.
2556 function get_permalink()
2558 return $this->get_link(0);
2561 function get_links($rel = 'alternate')
2563 if (!isset($this->data['links']))
2565 $this->data['links'] = array();
2566 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2568 foreach ($links as $link)
2570 if (isset($link['attribs']['']['href']))
2572 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2573 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2577 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2579 foreach ($links as $link)
2581 if (isset($link['attribs']['']['href']))
2583 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2584 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2589 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2591 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2593 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2595 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2597 if ($links = $this->get_channel_tags('', 'link'))
2599 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2602 $keys = array_keys($this->data['links']);
2603 foreach ($keys as $key)
2605 if (SimplePie_Misc::is_isegment_nz_nc($key))
2607 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2609 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2610 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2614 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2617 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2619 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2621 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2625 if (isset($this->data['links'][$rel]))
2627 return $this->data['links'][$rel];
2635 function get_description()
2637 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2639 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2641 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2643 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2645 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2647 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2651 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2653 elseif ($return = $this->get_channel_tags('', 'description'))
2655 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2657 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2659 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2661 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2663 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2665 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2667 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2669 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2671 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2679 function get_copyright()
2681 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2683 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2685 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2687 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2689 elseif ($return = $this->get_channel_tags('', 'copyright'))
2691 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2693 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2695 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2699 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2707 function get_language()
2709 if ($return = $this->get_channel_tags('', 'language'))
2711 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2715 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2719 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2721 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2723 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2727 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2729 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2731 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2733 elseif (isset($this->data['headers']['content-language']))
2735 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2743 function get_latitude()
2745 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2747 return (float) $return[0]['data'];
2749 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2751 return (float) $match[1];
2759 function get_longitude()
2761 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2763 return (float) $return[0]['data'];
2765 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2767 return (float) $return[0]['data'];
2769 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2771 return (float) $match[2];
2779 function get_image_title()
2781 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2783 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2787 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789 elseif ($return = $this->get_image_tags('', 'title'))
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2793 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2795 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2797 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2799 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2807 function get_image_url()
2809 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2811 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2813 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2815 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2819 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2823 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2825 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2827 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829 elseif ($return = $this->get_image_tags('', 'url'))
2831 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2839 function get_image_link()
2841 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2845 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2847 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2849 elseif ($return = $this->get_image_tags('', 'link'))
2851 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859 function get_image_width()
2861 if ($return = $this->get_image_tags('', 'width'))
2863 return round($return[0]['data']);
2865 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2875 function get_image_height()
2877 if ($return = $this->get_image_tags('', 'height'))
2879 return round($return[0]['data']);
2881 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2891 function get_item_quantity($max = 0)
2893 $qty = count($this->get_items());
2900 return ($qty > $max) ? $max : $qty;
2904 function get_item($key = 0)
2906 $items = $this->get_items();
2907 if (isset($items[$key]))
2909 return $items[$key];
2917 function get_items($start = 0, $end = 0)
2919 if (!empty($this->multifeed_objects))
2921 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2923 elseif (!isset($this->data['items']))
2925 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2927 $keys = array_keys($items);
2928 foreach ($keys as $key)
2930 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2933 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2935 $keys = array_keys($items);
2936 foreach ($keys as $key)
2938 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2941 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2943 $keys = array_keys($items);
2944 foreach ($keys as $key)
2946 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2949 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2951 $keys = array_keys($items);
2952 foreach ($keys as $key)
2954 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2957 if ($items = $this->get_channel_tags('', 'item'))
2959 $keys = array_keys($items);
2960 foreach ($keys as $key)
2962 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2967 if (!empty($this->data['items']))
2969 // If we want to order it by date, check if all items have a date, and then sort it
2970 if ($this->order_by_date)
2972 if (!isset($this->data['ordered_items']))
2975 foreach ($this->data['items'] as $item)
2977 if (!$item->get_date('U'))
2984 $this->data['ordered_items'] = $this->data['items'];
2987 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2990 $items = $this->data['ordered_items'];
2994 $items = $this->data['items'];
2997 // Slice the data as desired
3000 return array_slice($items, $start);
3004 return array_slice($items, $start, $end);
3013 function sort_items($a, $b)
3015 return $a->get_date('U') <= $b->get_date('U');
3018 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3020 if (is_array($urls) && sizeof($urls) > 0)
3023 foreach ($urls as $arg)
3025 if (is_a($arg, 'SimplePie'))
3027 $items = array_merge($items, $arg->get_items(0, $limit));
3031 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3036 foreach ($items as $item)
3038 if (!$item->get_date('U'))
3047 usort($items, array('SimplePie', 'sort_items'));
3052 return array_slice($items, $start);
3056 return array_slice($items, $start, $end);
3061 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3067 class SimplePie_Item
3070 var $data = array();
3072 function SimplePie_Item($feed, $data)
3074 $this->feed = $feed;
3075 $this->data = $data;
3078 function __toString()
3080 return md5(serialize($this->data));
3084 * Remove items that link back to this before destroying this object
3086 function __destruct()
3088 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3094 function get_item_tags($namespace, $tag)
3096 if (isset($this->data['child'][$namespace][$tag]))
3098 return $this->data['child'][$namespace][$tag];
3106 function get_base($element = array())
3108 return $this->feed->get_base($element);
3111 function sanitize($data, $type, $base = '')
3113 return $this->feed->sanitize($data, $type, $base);
3121 function get_id($hash = false)
3125 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3127 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3129 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3131 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3133 elseif ($return = $this->get_item_tags('', 'guid'))
3135 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3137 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3139 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3141 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3143 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3145 elseif (($return = $this->get_permalink()) !== null)
3149 elseif (($return = $this->get_title()) !== null)
3154 if ($this->get_permalink() !== null || $this->get_title() !== null)
3156 return md5($this->get_permalink() . $this->get_title());
3160 return md5(serialize($this->data));
3164 function get_title()
3166 if (!isset($this->data['title']))
3168 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3170 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3172 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3174 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3176 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3178 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3180 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3182 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3184 elseif ($return = $this->get_item_tags('', 'title'))
3186 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3188 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3190 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3192 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3194 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3198 $this->data['title'] = null;
3201 return $this->data['title'];
3204 function get_description($description_only = false)
3206 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3208 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3210 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3212 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3214 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3216 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3218 elseif ($return = $this->get_item_tags('', 'description'))
3220 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3222 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3224 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3226 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3228 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3232 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3236 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3238 elseif (!$description_only)
3240 return $this->get_content(true);
3248 function get_content($content_only = false)
3250 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3252 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3254 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3256 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3258 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3260 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3262 elseif (!$content_only)
3264 return $this->get_description(true);
3272 function get_category($key = 0)