2 if ( ! class_exists( 'SimplePie' ) ) :
6 * A PHP-Based RSS and Atom Feed Framework.
7 * Takes the hard work out of managing a complete RSS/Atom solution.
9 * Copyright (c) 2004-2011, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without modification, are
13 * permitted provided that the following conditions are met:
15 * * Redistributions of source code must retain the above copyright notice, this list of
16 * conditions and the following disclaimer.
18 * * Redistributions in binary form must reproduce the above copyright notice, this list
19 * of conditions and the following disclaimer in the documentation and/or other materials
20 * provided with the distribution.
22 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
23 * to endorse or promote products derived from this software without specific prior
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
29 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
38 * @copyright 2004-2011 Ryan Parman, Geoffrey Sneddon, Ryan McCue
40 * @author Geoffrey Sneddon
42 * @link http://simplepie.org/ SimplePie
43 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
44 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
45 * @todo phpDoc comments
51 define('SIMPLEPIE_NAME', 'SimplePie');
56 define('SIMPLEPIE_VERSION', '1.2.1');
61 define('SIMPLEPIE_BUILD', '20111015034325');
64 * SimplePie Website URL
66 define('SIMPLEPIE_URL', 'http://simplepie.org');
70 * @see SimplePie::set_useragent()
72 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
77 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
81 * @see SimplePie::set_autodiscovery_level()
83 define('SIMPLEPIE_LOCATOR_NONE', 0);
86 * Feed Link Element Autodiscovery
87 * @see SimplePie::set_autodiscovery_level()
89 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
92 * Local Feed Extension Autodiscovery
93 * @see SimplePie::set_autodiscovery_level()
95 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
98 * Local Feed Body Autodiscovery
99 * @see SimplePie::set_autodiscovery_level()
101 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
104 * Remote Feed Extension Autodiscovery
105 * @see SimplePie::set_autodiscovery_level()
107 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
110 * Remote Feed Body Autodiscovery
111 * @see SimplePie::set_autodiscovery_level()
113 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
116 * All Feed Autodiscovery
117 * @see SimplePie::set_autodiscovery_level()
119 define('SIMPLEPIE_LOCATOR_ALL', 31);
124 define('SIMPLEPIE_TYPE_NONE', 0);
129 define('SIMPLEPIE_TYPE_RSS_090', 1);
132 * RSS 0.91 (Netscape)
134 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
137 * RSS 0.91 (Userland)
139 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
142 * RSS 0.91 (both Netscape and Userland)
144 define('SIMPLEPIE_TYPE_RSS_091', 6);
149 define('SIMPLEPIE_TYPE_RSS_092', 8);
154 define('SIMPLEPIE_TYPE_RSS_093', 16);
159 define('SIMPLEPIE_TYPE_RSS_094', 32);
164 define('SIMPLEPIE_TYPE_RSS_10', 64);
169 define('SIMPLEPIE_TYPE_RSS_20', 128);
174 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
177 * Non-RDF-based RSS (truly intended as syndication format)
179 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
184 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
189 define('SIMPLEPIE_TYPE_ATOM_03', 256);
194 define('SIMPLEPIE_TYPE_ATOM_10', 512);
199 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
204 define('SIMPLEPIE_TYPE_ALL', 1023);
209 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
214 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
219 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
224 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
227 * base64-encoded construct
229 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
234 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
237 * A construct that might be HTML
239 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
244 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
249 define('SIMPLEPIE_SAME_CASE', 1);
252 * Change to lowercase
254 define('SIMPLEPIE_LOWERCASE', 2);
257 * Change to uppercase
259 define('SIMPLEPIE_UPPERCASE', 4);
262 * PCRE for HTML attributes
264 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]*');
267 * PCRE for XML attributes
269 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
274 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
279 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
284 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
289 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
294 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
299 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
302 * RSS 1.0 Content Module Namespace
304 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
308 * (Stupid, I know, but I'm certain it will confuse people less with support.)
310 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
315 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
320 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
323 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
325 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
330 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
333 * Media RSS Namespace
335 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
338 * Wrong Media RSS Namespace
340 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
343 * iTunes RSS Namespace
345 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
350 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
353 * IANA Link Relations Registry
355 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
358 * Whether we're running on PHP5
360 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
365 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
370 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
375 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
378 * fsockopen() file source
380 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
385 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
388 * file_get_contents() file source
390 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
400 * @var array Raw data
406 * @var mixed Error string
412 * @var object Instance of SimplePie_Sanitize (or other class)
413 * @see SimplePie::set_sanitize_class()
419 * @var string SimplePie Useragent
420 * @see SimplePie::set_useragent()
423 var $useragent = SIMPLEPIE_USERAGENT;
426 * @var string Feed URL
427 * @see SimplePie::set_feed_url()
433 * @var object Instance of SimplePie_File to use as a feed
434 * @see SimplePie::set_file()
440 * @var string Raw feed data
441 * @see SimplePie::set_raw_data()
447 * @var int Timeout for fetching remote files
448 * @see SimplePie::set_timeout()
454 * @var bool Forces fsockopen() to be used for remote files instead
455 * of cURL, even if a new enough version is installed
456 * @see SimplePie::force_fsockopen()
459 var $force_fsockopen = false;
462 * @var bool Force the given data/URL to be treated as a feed no matter what
464 * @see SimplePie::force_feed()
467 var $force_feed = false;
470 * @var bool Enable/Disable XML dump
471 * @see SimplePie::enable_xml_dump()
474 var $xml_dump = false;
477 * @var bool Enable/Disable Caching
478 * @see SimplePie::enable_cache()
484 * @var int Cache duration (in seconds)
485 * @see SimplePie::set_cache_duration()
488 var $cache_duration = 3600;
491 * @var int Auto-discovery cache duration (in seconds)
492 * @see SimplePie::set_autodiscovery_cache_duration()
495 var $autodiscovery_cache_duration = 604800; // 7 Days.
498 * @var string Cache location (relative to executing script)
499 * @see SimplePie::set_cache_location()
502 var $cache_location = './cache';
505 * @var string Function that creates the cache filename
506 * @see SimplePie::set_cache_name_function()
509 var $cache_name_function = 'md5';
512 * @var bool Reorder feed by date descending
513 * @see SimplePie::enable_order_by_date()
516 var $order_by_date = true;
519 * @var mixed Force input encoding to be set to the follow value
520 * (false, or anything type-cast to false, disables this feature)
521 * @see SimplePie::set_input_encoding()
524 var $input_encoding = false;
527 * @var int Feed Autodiscovery Level
528 * @see SimplePie::set_autodiscovery_level()
531 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
534 * @var string Class used for caching feeds
535 * @see SimplePie::set_cache_class()
538 var $cache_class = 'SimplePie_Cache';
541 * @var string Class used for locating feeds
542 * @see SimplePie::set_locator_class()
545 var $locator_class = 'SimplePie_Locator';
548 * @var string Class used for parsing feeds
549 * @see SimplePie::set_parser_class()
552 var $parser_class = 'SimplePie_Parser';
555 * @var string Class used for fetching feeds
556 * @see SimplePie::set_file_class()
559 var $file_class = 'SimplePie_File';
562 * @var string Class used for items
563 * @see SimplePie::set_item_class()
566 var $item_class = 'SimplePie_Item';
569 * @var string Class used for authors
570 * @see SimplePie::set_author_class()
573 var $author_class = 'SimplePie_Author';
576 * @var string Class used for categories
577 * @see SimplePie::set_category_class()
580 var $category_class = 'SimplePie_Category';
583 * @var string Class used for enclosures
584 * @see SimplePie::set_enclosures_class()
587 var $enclosure_class = 'SimplePie_Enclosure';
590 * @var string Class used for Media RSS <media:text> captions
591 * @see SimplePie::set_caption_class()
594 var $caption_class = 'SimplePie_Caption';
597 * @var string Class used for Media RSS <media:copyright>
598 * @see SimplePie::set_copyright_class()
601 var $copyright_class = 'SimplePie_Copyright';
604 * @var string Class used for Media RSS <media:credit>
605 * @see SimplePie::set_credit_class()
608 var $credit_class = 'SimplePie_Credit';
611 * @var string Class used for Media RSS <media:rating>
612 * @see SimplePie::set_rating_class()
615 var $rating_class = 'SimplePie_Rating';
618 * @var string Class used for Media RSS <media:restriction>
619 * @see SimplePie::set_restriction_class()
622 var $restriction_class = 'SimplePie_Restriction';
625 * @var string Class used for content-type sniffing
626 * @see SimplePie::set_content_type_sniffer_class()
629 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
632 * @var string Class used for item sources.
633 * @see SimplePie::set_source_class()
636 var $source_class = 'SimplePie_Source';
639 * @var mixed Set javascript query string parameter (false, or
640 * anything type-cast to false, disables this feature)
641 * @see SimplePie::set_javascript()
644 var $javascript = 'js';
647 * @var int Maximum number of feeds to check with autodiscovery
648 * @see SimplePie::set_max_checked_feeds()
651 var $max_checked_feeds = 10;
654 * @var array All the feeds found during the autodiscovery process
655 * @see SimplePie::get_all_discovered_feeds()
658 var $all_discovered_feeds = array();
661 * @var string Web-accessible path to the handler_favicon.php file.
662 * @see SimplePie::set_favicon_handler()
665 var $favicon_handler = '';
668 * @var string Web-accessible path to the handler_image.php file.
669 * @see SimplePie::set_image_handler()
672 var $image_handler = '';
675 * @var array Stores the URLs when multiple feeds are being initialized.
676 * @see SimplePie::set_feed_url()
679 var $multifeed_url = array();
682 * @var array Stores SimplePie objects when multiple feeds initialized.
685 var $multifeed_objects = array();
688 * @var array Stores the get_object_vars() array for use with multifeeds.
689 * @see SimplePie::set_feed_url()
692 var $config_settings = null;
695 * @var integer Stores the number of items to return per-feed with multifeeds.
696 * @see SimplePie::set_item_limit()
702 * @var array Stores the default attributes to be stripped by strip_attributes().
703 * @see SimplePie::strip_attributes()
706 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
709 * @var array Stores the default tags to be stripped by strip_htmltags().
710 * @see SimplePie::strip_htmltags()
713 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
716 * The SimplePie class contains feed level data and options
718 * There are two ways that you can create a new SimplePie object. The first
719 * is by passing a feed URL as a parameter to the SimplePie constructor
720 * (as well as optionally setting the cache location and cache expiry). This
721 * will initialise the whole feed with all of the default settings, and you
722 * can begin accessing methods and properties immediately.
724 * The second way is to create the SimplePie object with no parameters
725 * at all. This will enable you to set configuration options. After setting
726 * them, you must initialise the feed using $feed->init(). At that point the
727 * object's methods and properties will be available to you. This format is
728 * what is used throughout this documentation.
731 * @since 1.0 Preview Release
732 * @param string $feed_url This is the URL you want to parse.
733 * @param string $cache_location This is where you want the cache to be stored.
734 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
736 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
738 // Other objects, instances created here so we can set options on them
739 $this->sanitize =& new SimplePie_Sanitize;
741 // Set options if they're passed to the constructor
742 if ($cache_location !== null)
744 $this->set_cache_location($cache_location);
747 if ($cache_duration !== null)
749 $this->set_cache_duration($cache_duration);
752 // Only init the script if we're passed a feed URL
753 if ($feed_url !== null)
755 $this->set_feed_url($feed_url);
761 * Used for converting object to a string
763 function __toString()
765 return md5(serialize($this->data));
769 * Remove items that link back to this before destroying this object
771 function __destruct()
773 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
775 if (!empty($this->data['items']))
777 foreach ($this->data['items'] as $item)
781 unset($item, $this->data['items']);
783 if (!empty($this->data['ordered_items']))
785 foreach ($this->data['ordered_items'] as $item)
789 unset($item, $this->data['ordered_items']);
795 * Force the given data/URL to be treated as a feed no matter what it
800 * @param bool $enable Force the given data/URL to be treated as a feed
802 function force_feed($enable = false)
804 $this->force_feed = (bool) $enable;
808 * This is the URL of the feed you want to parse.
810 * This allows you to enter the URL of the feed you want to parse, or the
811 * website you want to try to use auto-discovery on. This takes priority
812 * over any set raw data.
814 * You can set multiple feeds to mash together by passing an array instead
815 * of a string for the $url. Remember that with each additional feed comes
816 * additional processing and resources.
819 * @since 1.0 Preview Release
820 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
821 * @see SimplePie::set_raw_data()
823 function set_feed_url($url)
827 $this->multifeed_url = array();
828 foreach ($url as $value)
830 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
835 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
840 * Provides an instance of SimplePie_File to use as a feed
843 * @param object &$file Instance of SimplePie_File (or subclass)
844 * @return bool True on success, false on failure
846 function set_file(&$file)
848 if (is_a($file, 'SimplePie_File'))
850 $this->feed_url = $file->url;
851 $this->file =& $file;
858 * Allows you to use a string of RSS/Atom data instead of a remote feed.
860 * If you have a feed available as a string in PHP, you can tell SimplePie
861 * to parse that data string instead of a remote feed. Any set feed URL
866 * @param string $data RSS or Atom data as a string.
867 * @see SimplePie::set_feed_url()
869 function set_raw_data($data)
871 $this->raw_data = $data;
875 * Allows you to override the default timeout for fetching remote feeds.
877 * This allows you to change the maximum time the feed's server to respond
878 * and send the feed back.
882 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
884 function set_timeout($timeout = 10)
886 $this->timeout = (int) $timeout;
890 * Forces SimplePie to use fsockopen() instead of the preferred cURL
895 * @param bool $enable Force fsockopen() to be used
897 function force_fsockopen($enable = false)
899 $this->force_fsockopen = (bool) $enable;
903 * Outputs the raw XML content of the feed, after it has gone through
904 * SimplePie's filters.
906 * Used only for debugging, this function will output the XML content as
907 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
908 * before trying to parse it. Many parts of the feed are re-written in
909 * memory, and in the end, you have a parsable feed. XML dump shows you the
910 * actual XML that SimplePie tries to parse, which may or may not be very
911 * different from the original feed.
914 * @since 1.0 Preview Release
915 * @param bool $enable Enable XML dump
917 function enable_xml_dump($enable = false)
919 $this->xml_dump = (bool) $enable;
923 * Enables/disables caching in SimplePie.
925 * This option allows you to disable caching all-together in SimplePie.
926 * However, disabling the cache can lead to longer load times.
929 * @since 1.0 Preview Release
930 * @param bool $enable Enable caching
932 function enable_cache($enable = true)
934 $this->cache = (bool) $enable;
938 * Set the length of time (in seconds) that the contents of a feed
942 * @param int $seconds The feed content cache duration.
944 function set_cache_duration($seconds = 3600)
946 $this->cache_duration = (int) $seconds;
950 * Set the length of time (in seconds) that the autodiscovered feed
951 * URL will be cached.
954 * @param int $seconds The autodiscovered feed URL cache duration.
956 function set_autodiscovery_cache_duration($seconds = 604800)
958 $this->autodiscovery_cache_duration = (int) $seconds;
962 * Set the file system location where the cached files should be stored.
965 * @param string $location The file system location.
967 function set_cache_location($location = './cache')
969 $this->cache_location = (string) $location;
973 * Determines whether feed items should be sorted into reverse chronological order.
976 * @param bool $enable Sort as reverse chronological order.
978 function enable_order_by_date($enable = true)
980 $this->order_by_date = (bool) $enable;
984 * Allows you to override the character encoding reported by the feed.
987 * @param string $encoding Character encoding.
989 function set_input_encoding($encoding = false)
993 $this->input_encoding = (string) $encoding;
997 $this->input_encoding = false;
1002 * Set how much feed autodiscovery to do
1005 * @see SIMPLEPIE_LOCATOR_NONE
1006 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1007 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1008 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1009 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1010 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1011 * @see SIMPLEPIE_LOCATOR_ALL
1012 * @param int $level Feed Autodiscovery Level (level can be a
1013 * combination of the above constants, see bitwise OR operator)
1015 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1017 $this->autodiscovery = (int) $level;
1021 * Allows you to change which class SimplePie uses for caching.
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_cache_class($class = 'SimplePie_Cache')
1031 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1033 $this->cache_class = $class;
1040 * Allows you to change which class SimplePie uses for auto-discovery.
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_locator_class($class = 'SimplePie_Locator')
1050 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1052 $this->locator_class = $class;
1059 * Allows you to change which class SimplePie uses for XML parsing.
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_parser_class($class = 'SimplePie_Parser')
1069 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1071 $this->parser_class = $class;
1078 * Allows you to change which class SimplePie uses for remote file fetching.
1079 * Useful when you are overloading or extending SimplePie's default classes.
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_file_class($class = 'SimplePie_File')
1088 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1090 $this->file_class = $class;
1097 * Allows you to change which class SimplePie uses for data sanitization.
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_sanitize_class($class = 'SimplePie_Sanitize')
1107 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1109 $this->sanitize =& new $class;
1116 * Allows you to change which class SimplePie uses for handling feed items.
1117 * Useful when you are overloading or extending SimplePie's default classes.
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_item_class($class = 'SimplePie_Item')
1126 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1128 $this->item_class = $class;
1135 * Allows you to change which class SimplePie uses for handling author data.
1136 * Useful when you are overloading or extending SimplePie's default classes.
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_author_class($class = 'SimplePie_Author')
1145 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1147 $this->author_class = $class;
1154 * Allows you to change which class SimplePie uses for handling category data.
1155 * Useful when you are overloading or extending SimplePie's default classes.
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_category_class($class = 'SimplePie_Category')
1164 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1166 $this->category_class = $class;
1173 * Allows you to change which class SimplePie uses for feed enclosures.
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_enclosure_class($class = 'SimplePie_Enclosure')
1183 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1185 $this->enclosure_class = $class;
1192 * Allows you to change which class SimplePie uses for <media:text> captions
1193 * Useful when you are overloading or extending SimplePie's default classes.
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_caption_class($class = 'SimplePie_Caption')
1202 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1204 $this->caption_class = $class;
1211 * Allows you to change which class SimplePie uses for <media:copyright>
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_copyright_class($class = 'SimplePie_Copyright')
1221 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1223 $this->copyright_class = $class;
1230 * Allows you to change which class SimplePie uses for <media:credit>
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_credit_class($class = 'SimplePie_Credit')
1240 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1242 $this->credit_class = $class;
1249 * Allows you to change which class SimplePie uses for <media:rating>
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_rating_class($class = 'SimplePie_Rating')
1259 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1261 $this->rating_class = $class;
1268 * Allows you to change which class SimplePie uses for <media:restriction>
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_restriction_class($class = 'SimplePie_Restriction')
1278 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1280 $this->restriction_class = $class;
1287 * Allows you to change which class SimplePie uses for content-type sniffing.
1288 * Useful when you are overloading or extending SimplePie's default classes.
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_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1297 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1299 $this->content_type_sniffer_class = $class;
1306 * Allows you to change which class SimplePie uses item sources.
1307 * Useful when you are overloading or extending SimplePie's default classes.
1310 * @param string $class Name of custom class.
1311 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1312 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1314 function set_source_class($class = 'SimplePie_Source')
1316 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1318 $this->source_class = $class;
1325 * Allows you to override the default user agent string.
1328 * @param string $ua New user agent string.
1330 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1332 $this->useragent = (string) $ua;
1336 * Set callback function to create cache filename with
1339 * @param mixed $function Callback function
1341 function set_cache_name_function($function = 'md5')
1343 if (is_callable($function))
1345 $this->cache_name_function = $function;
1350 * Set javascript query string parameter
1353 * @param mixed $get Javascript query string parameter
1355 function set_javascript($get = 'js')
1359 $this->javascript = (string) $get;
1363 $this->javascript = false;
1368 * Set options to make SP as fast as possible. Forgoes a
1369 * substantial amount of data sanitization in favor of speed.
1372 * @param bool $set Whether to set them or not
1374 function set_stupidly_fast($set = false)
1378 $this->enable_order_by_date(false);
1379 $this->remove_div(false);
1380 $this->strip_comments(false);
1381 $this->strip_htmltags(false);
1382 $this->strip_attributes(false);
1383 $this->set_image_handler(false);
1388 * Set maximum number of feeds to check with autodiscovery
1391 * @param int $max Maximum number of feeds to check
1393 function set_max_checked_feeds($max = 10)
1395 $this->max_checked_feeds = (int) $max;
1398 function remove_div($enable = true)
1400 $this->sanitize->remove_div($enable);
1403 function strip_htmltags($tags = '', $encode = null)
1407 $tags = $this->strip_htmltags;
1409 $this->sanitize->strip_htmltags($tags);
1410 if ($encode !== null)
1412 $this->sanitize->encode_instead_of_strip($tags);
1416 function encode_instead_of_strip($enable = true)
1418 $this->sanitize->encode_instead_of_strip($enable);
1421 function strip_attributes($attribs = '')
1423 if ($attribs === '')
1425 $attribs = $this->strip_attributes;
1427 $this->sanitize->strip_attributes($attribs);
1430 function set_output_encoding($encoding = 'UTF-8')
1432 $this->sanitize->set_output_encoding($encoding);
1435 function strip_comments($strip = false)
1437 $this->sanitize->strip_comments($strip);
1441 * Set element/attribute key/value pairs of HTML attributes
1442 * containing URLs that need to be resolved relative to the feed
1446 * @param array $element_attribute Element/attribute key/value pairs
1448 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1450 $this->sanitize->set_url_replacements($element_attribute);
1454 * Set the handler to enable the display of cached favicons.
1457 * @param str $page Web-accessible path to the handler_favicon.php file.
1458 * @param str $qs The query string that the value should be passed to.
1460 function set_favicon_handler($page = false, $qs = 'i')
1462 if ($page !== false)
1464 $this->favicon_handler = $page . '?' . $qs . '=';
1468 $this->favicon_handler = '';
1473 * Set the handler to enable the display of cached images.
1476 * @param str $page Web-accessible path to the handler_image.php file.
1477 * @param str $qs The query string that the value should be passed to.
1479 function set_image_handler($page = false, $qs = 'i')
1481 if ($page !== false)
1483 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1487 $this->image_handler = '';
1492 * Set the limit for items returned per-feed with multifeeds.
1495 * @param integer $limit The maximum number of items to return.
1497 function set_item_limit($limit = 0)
1499 $this->item_limit = (int) $limit;
1504 // Check absolute bare minimum requirements.
1505 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1509 // 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.
1510 elseif (!extension_loaded('xmlreader'))
1512 static $xml_is_sane = null;
1513 if ($xml_is_sane === null)
1515 $parser_check = xml_parser_create();
1516 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1517 xml_parser_free($parser_check);
1518 $xml_is_sane = isset($values[0]['value']);
1526 if (isset($_GET[$this->javascript]))
1528 SimplePie_Misc::output_javascript();
1532 // Pass whatever was set with config options over to the sanitizer.
1533 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1534 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1536 if ($this->feed_url !== null || $this->raw_data !== null)
1538 $this->data = array();
1539 $this->multifeed_objects = array();
1542 if ($this->feed_url !== null)
1544 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1545 // Decide whether to enable caching
1546 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1548 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1550 // If it's enabled and we don't want an XML dump, use the cache
1551 if ($cache && !$this->xml_dump)
1554 $this->data = $cache->load();
1555 if (!empty($this->data))
1557 // If the cache is for an outdated build of SimplePie
1558 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1561 $this->data = array();
1563 // If we've hit a collision just rerun it with caching disabled
1564 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1567 $this->data = array();
1569 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1570 elseif (isset($this->data['feed_url']))
1572 // If the autodiscovery cache is still valid use it.
1573 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1575 // Do not need to do feed autodiscovery yet.
1576 if ($this->data['feed_url'] === $this->data['url'])
1579 $this->data = array();
1583 $this->set_feed_url($this->data['feed_url']);
1584 return $this->init();
1588 // Check if the cache has been updated
1589 elseif ($cache->mtime() + $this->cache_duration < time())
1591 // If we have last-modified and/or etag set
1592 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1595 if (isset($this->data['headers']['last-modified']))
1597 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1599 if (isset($this->data['headers']['etag']))
1601 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1603 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1606 if ($file->status_code === 304)
1613 $headers = $file->headers;
1622 // If the cache is still valid, just return true
1628 // If the cache is empty, delete it
1632 $this->data = array();
1635 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1638 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1640 $file =& $this->file;
1644 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1647 // If the file connection has an error, set SimplePie::error to that and quit
1648 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1650 $this->error = $file->error;
1651 if (!empty($this->data))
1661 if (!$this->force_feed)
1663 // Check if the supplied URL is a feed, if it isn't, look for it.
1664 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1665 if (!$locate->is_feed($file))
1667 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1669 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1673 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1674 if (!$cache->save($this))
1676 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1678 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1680 $this->feed_url = $file->url;
1684 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
1685 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1692 $headers = $file->headers;
1693 $data = $file->body;
1694 $sniffer =& new $this->content_type_sniffer_class($file);
1695 $sniffed = $sniffer->get_type();
1699 $data = $this->raw_data;
1702 // Set up array of possible encodings
1703 $encodings = array();
1705 // First check to see if input has been overridden.
1706 if ($this->input_encoding !== false)
1708 $encodings[] = $this->input_encoding;
1711 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1712 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1714 // RFC 3023 (only applies to sniffed content)
1715 if (isset($sniffed))
1717 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1719 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1721 $encodings[] = strtoupper($charset[1]);
1723 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1724 $encodings[] = 'UTF-8';
1726 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1728 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1730 $encodings[] = $charset[1];
1732 $encodings[] = 'US-ASCII';
1734 // Text MIME-type default
1735 elseif (substr($sniffed, 0, 5) === 'text/')
1737 $encodings[] = 'US-ASCII';
1741 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1742 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1743 $encodings[] = 'UTF-8';
1744 $encodings[] = 'ISO-8859-1';
1746 // There's no point in trying an encoding twice
1747 $encodings = array_unique($encodings);
1749 // If we want the XML, just output that with the most likely encoding and quit
1750 if ($this->xml_dump)
1752 header('Content-type: text/xml; charset=' . $encodings[0]);
1757 // Loop through each possible encoding, till we return something, or run out of possibilities
1758 foreach ($encodings as $encoding)
1760 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1761 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1763 // Create new parser
1764 $parser =& new $this->parser_class();
1766 // If it's parsed fine
1767 if ($parser->parse($utf8_data, 'UTF-8'))
1769 $this->data = $parser->get_data();
1770 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1772 if (isset($headers))
1774 $this->data['headers'] = $headers;
1776 $this->data['build'] = SIMPLEPIE_BUILD;
1778 // Cache the file if caching is enabled
1779 if ($cache && !$cache->save($this))
1781 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1787 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1788 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1796 // We have an error, just set SimplePie_Misc::error to it and quit
1797 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1801 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
1803 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1806 elseif (!empty($this->multifeed_url))
1810 $this->multifeed_objects = array();
1811 foreach ($this->multifeed_url as $url)
1815 // This keyword needs to defy coding standards for PHP4 compatibility
1816 $this->multifeed_objects[$i] = clone($this);
1820 $this->multifeed_objects[$i] = $this;
1822 $this->multifeed_objects[$i]->set_feed_url($url);
1823 $success |= $this->multifeed_objects[$i]->init();
1826 return (bool) $success;
1835 * Return the error message for the occured error
1838 * @return string Error message
1842 return $this->error;
1845 function get_encoding()
1847 return $this->sanitize->output_encoding;
1850 function handle_content_type($mime = 'text/html')
1852 if (!headers_sent())
1854 $header = "Content-type: $mime;";
1855 if ($this->get_encoding())
1857 $header .= ' charset=' . $this->get_encoding();
1861 $header .= ' charset=UTF-8';
1869 if (!isset($this->data['type']))
1871 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1872 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1874 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1876 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1878 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1880 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1882 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1884 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1885 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1887 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1889 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1891 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1892 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1894 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1897 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1899 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1900 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1902 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1905 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1906 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1908 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1911 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1915 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1922 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1926 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1930 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1934 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1941 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1944 return $this->data['type'];
1948 * Returns the URL for the favicon of the feed's website.
1950 * @todo Cache atom:icon
1954 function get_favicon()
1956 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1958 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1960 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1962 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1964 if ($this->cache && $this->favicon_handler)
1966 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1967 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1971 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1975 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1977 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1979 $sniffer =& new $this->content_type_sniffer_class($file);
1980 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1982 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1984 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1988 trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1989 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2002 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2009 * @todo If we have a perm redirect we should return the new URL
2010 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2011 * @todo Also, |atom:link|@rel=self
2013 function subscribe_url()
2015 if ($this->feed_url !== null)
2017 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2025 function subscribe_feed()
2027 if ($this->feed_url !== null)
2029 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2037 function subscribe_outlook()
2039 if ($this->feed_url !== null)
2041 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2049 function subscribe_podcast()
2051 if ($this->feed_url !== null)
2053 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2061 function subscribe_itunes()
2063 if ($this->feed_url !== null)
2065 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2074 * Creates the subscribe_* methods' return data
2077 * @param string $feed_url String to prefix to the feed URL
2078 * @param string $site_url String to prefix to the site URL (and
2079 * suffix to the feed URL)
2080 * @return mixed URL if feed exists, false otherwise
2082 function subscribe_service($feed_url, $site_url = null)
2084 if ($this->subscribe_url())
2086 $return = $feed_url . rawurlencode($this->feed_url);
2087 if ($site_url !== null && $this->get_link() !== null)
2089 $return .= $site_url . rawurlencode($this->get_link());
2091 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2099 function subscribe_aol()
2101 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2104 function subscribe_bloglines()
2106 return $this->subscribe_service('http://www.bloglines.com/sub/');
2109 function subscribe_eskobo()
2111 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2114 function subscribe_feedfeeds()
2116 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2119 function subscribe_feedster()
2121 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2124 function subscribe_google()
2126 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2129 function subscribe_gritwire()
2131 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2134 function subscribe_msn()
2136 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2139 function subscribe_netvibes()
2141 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2144 function subscribe_newsburst()
2146 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2149 function subscribe_newsgator()
2151 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2154 function subscribe_odeo()
2156 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2159 function subscribe_podnova()
2161 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2164 function subscribe_rojo()
2166 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2169 function subscribe_yahoo()
2171 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2174 function get_feed_tags($namespace, $tag)
2176 $type = $this->get_type();
2177 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2179 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2181 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2184 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2186 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2188 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2191 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2193 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2195 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2198 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2200 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2202 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2208 function get_channel_tags($namespace, $tag)
2210 $type = $this->get_type();
2211 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2213 if ($return = $this->get_feed_tags($namespace, $tag))
2218 if ($type & SIMPLEPIE_TYPE_RSS_10)
2220 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2222 if (isset($channel[0]['child'][$namespace][$tag]))
2224 return $channel[0]['child'][$namespace][$tag];
2228 if ($type & SIMPLEPIE_TYPE_RSS_090)
2230 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2232 if (isset($channel[0]['child'][$namespace][$tag]))
2234 return $channel[0]['child'][$namespace][$tag];
2238 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2240 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2242 if (isset($channel[0]['child'][$namespace][$tag]))
2244 return $channel[0]['child'][$namespace][$tag];
2251 function get_image_tags($namespace, $tag)
2253 $type = $this->get_type();
2254 if ($type & SIMPLEPIE_TYPE_RSS_10)
2256 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2258 if (isset($image[0]['child'][$namespace][$tag]))
2260 return $image[0]['child'][$namespace][$tag];
2264 if ($type & SIMPLEPIE_TYPE_RSS_090)
2266 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2268 if (isset($image[0]['child'][$namespace][$tag]))
2270 return $image[0]['child'][$namespace][$tag];
2274 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2276 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2278 if (isset($image[0]['child'][$namespace][$tag]))
2280 return $image[0]['child'][$namespace][$tag];
2287 function get_base($element = array())
2289 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2291 return $element['xml_base'];
2293 elseif ($this->get_link() !== null)
2295 return $this->get_link();
2299 return $this->subscribe_url();
2303 function sanitize($data, $type, $base = '')
2305 return $this->sanitize->sanitize($data, $type, $base);
2308 function get_title()
2310 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2312 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2314 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2316 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2318 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2320 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2322 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2324 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2326 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2328 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2330 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2332 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2334 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2336 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2344 function get_category($key = 0)
2346 $categories = $this->get_categories();
2347 if (isset($categories[$key]))
2349 return $categories[$key];
2357 function get_categories()
2359 $categories = array();
2361 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2366 if (isset($category['attribs']['']['term']))
2368 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2370 if (isset($category['attribs']['']['scheme']))
2372 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2374 if (isset($category['attribs']['']['label']))
2376 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2378 $categories[] =& new $this->category_class($term, $scheme, $label);
2380 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2382 // This is really the label, but keep this as the term also for BC.
2383 // Label will also work on retrieving because that falls back to term.
2384 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2385 if (isset($category['attribs']['']['domain']))
2387 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2393 $categories[] =& new $this->category_class($term, $scheme, null);
2395 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2397 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2399 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2401 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2404 if (!empty($categories))
2406 return SimplePie_Misc::array_unique($categories);
2414 function get_author($key = 0)
2416 $authors = $this->get_authors();
2417 if (isset($authors[$key]))
2419 return $authors[$key];
2427 function get_authors()
2430 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2435 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2437 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2439 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2441 $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]));
2443 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2445 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2447 if ($name !== null || $email !== null || $uri !== null)
2449 $authors[] =& new $this->author_class($name, $uri, $email);
2452 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2457 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2459 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2461 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2463 $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]));
2465 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2467 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2469 if ($name !== null || $email !== null || $url !== null)
2471 $authors[] =& new $this->author_class($name, $url, $email);
2474 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2476 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2478 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2480 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2482 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2484 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2487 if (!empty($authors))
2489 return SimplePie_Misc::array_unique($authors);
2497 function get_contributor($key = 0)
2499 $contributors = $this->get_contributors();
2500 if (isset($contributors[$key]))
2502 return $contributors[$key];
2510 function get_contributors()
2512 $contributors = array();
2513 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2518 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2520 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2522 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2524 $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]));
2526 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2528 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2530 if ($name !== null || $email !== null || $uri !== null)
2532 $contributors[] =& new $this->author_class($name, $uri, $email);
2535 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2540 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2542 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2544 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2546 $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]));
2548 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2550 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2552 if ($name !== null || $email !== null || $url !== null)
2554 $contributors[] =& new $this->author_class($name, $url, $email);
2558 if (!empty($contributors))
2560 return SimplePie_Misc::array_unique($contributors);
2568 function get_link($key = 0, $rel = 'alternate')
2570 $links = $this->get_links($rel);
2571 if (isset($links[$key]))
2573 return $links[$key];
2582 * Added for parity between the parent-level and the item/entry-level.
2584 function get_permalink()
2586 return $this->get_link(0);
2589 function get_links($rel = 'alternate')
2591 if (!isset($this->data['links']))
2593 $this->data['links'] = array();
2594 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2596 foreach ($links as $link)
2598 if (isset($link['attribs']['']['href']))
2600 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2601 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2605 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2607 foreach ($links as $link)
2609 if (isset($link['attribs']['']['href']))
2611 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2612 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2617 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2619 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2621 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2623 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2625 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2627 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2630 $keys = array_keys($this->data['links']);
2631 foreach ($keys as $key)
2633 if (SimplePie_Misc::is_isegment_nz_nc($key))
2635 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2637 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2638 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2642 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2645 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2647 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2649 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2653 if (isset($this->data['links'][$rel]))
2655 return $this->data['links'][$rel];
2663 function get_all_discovered_feeds()
2665 return $this->all_discovered_feeds;
2668 function get_description()
2670 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2672 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2674 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2676 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2678 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2680 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2684 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2686 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2688 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2690 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2692 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2694 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2698 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2700 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2702 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2704 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2712 function get_copyright()
2714 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2716 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2718 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2720 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2722 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2724 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2726 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2728 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2730 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2732 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2740 function get_language()
2742 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2744 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2746 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2748 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2750 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2752 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2754 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2756 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2758 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2760 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2762 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2764 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2766 elseif (isset($this->data['headers']['content-language']))
2768 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2776 function get_latitude()
2779 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2781 return (float) $return[0]['data'];
2783 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2785 return (float) $match[1];
2793 function get_longitude()
2795 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2797 return (float) $return[0]['data'];
2799 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2801 return (float) $return[0]['data'];
2803 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2805 return (float) $match[2];
2813 function get_image_title()
2815 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2817 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2819 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2821 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2823 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2825 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2827 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2829 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2831 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2833 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2841 function get_image_url()
2843 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2845 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2847 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2849 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2851 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2853 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2855 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2857 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2861 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2863 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2865 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2873 function get_image_link()
2875 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2877 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2879 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2881 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2883 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2885 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2893 function get_image_width()
2895 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2897 return round($return[0]['data']);
2899 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2909 function get_image_height()
2911 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2913 return round($return[0]['data']);
2915 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2925 function get_item_quantity($max = 0)
2928 $qty = count($this->get_items());
2935 return ($qty > $max) ? $max : $qty;
2939 function get_item($key = 0)
2941 $items = $this->get_items();
2942 if (isset($items[$key]))
2944 return $items[$key];
2952 function get_items($start = 0, $end = 0)
2954 if (!isset($this->data['items']))
2956 if (!empty($this->multifeed_objects))
2958 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2962 $this->data['items'] = array();
2963 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2965 $keys = array_keys($items);
2966 foreach ($keys as $key)
2968 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2971 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2973 $keys = array_keys($items);
2974 foreach ($keys as $key)
2976 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2979 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2981 $keys = array_keys($items);
2982 foreach ($keys as $key)
2984 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2987 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2989 $keys = array_keys($items);
2990 foreach ($keys as $key)
2992 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2995 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2997 $keys = array_keys($items);
2998 foreach ($keys as $key)
3000 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
3006 if (!empty($this->data['items']))
3008 // If we want to order it by date, check if all items have a date, and then sort it
3009 if ($this->order_by_date && empty($this->multifeed_objects))
3011 if (!isset($this->data['ordered_items']))
3014 foreach ($this->data['items'] as $item)
3016 if (!$item->get_date('U'))
3023 $this->data['ordered_items'] = $this->data['items'];
3026 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3029 $items = $this->data['ordered_items'];
3033 $items = $this->data['items'];
3036 // Slice the data as desired
3039 return array_slice($items, $start);
3043 return array_slice($items, $start, $end);
3055 function sort_items($a, $b)
3057 return $a->get_date('U') <= $b->get_date('U');
3063 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3065 if (is_array($urls) && sizeof($urls) > 0)
3068 foreach ($urls as $arg)
3070 if (is_a($arg, 'SimplePie'))
3072 $items = array_merge($items, $arg->get_items(0, $limit));
3076 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3081 foreach ($items as $item)
3083 if (!$item->get_date('U'))
3092 usort($items, array('SimplePie', 'sort_items'));
3097 return array_slice($items, $start);
3101 return array_slice($items, $start, $end);
3106 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3112 class SimplePie_Item
3115 var $data = array();
3117 function SimplePie_Item($feed, $data)
3119 $this->feed = $feed;
3120 $this->data = $data;
3123 function __toString()
3125 return md5(serialize($this->data));
3129 * Remove items that link back to this before destroying this object
3131 function __destruct()
3133 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3139 function get_item_tags($namespace, $tag)
3141 if (isset($this->data['child'][$namespace][$tag]))
3143 return $this->data['child'][$namespace][$tag];
3151 function get_base($element = array())
3153 return $this->feed->get_base($element);
3156 function sanitize($data, $type, $base = '')
3158 return $this->feed->sanitize($data, $type, $base);
3166 function get_id($hash = false)
3170 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3172 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3176 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3178 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3182 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3184 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3186 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3188 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3190 elseif (($return = $this->get_permalink()) !== null)
3194 elseif (($return = $this->get_title()) !== null)
3199 if ($this->get_permalink() !== null || $this->get_title() !== null)
3201 return md5($this->get_permalink() . $this->get_title());
3205 return md5(serialize($this->data));
3209 function get_title()
3211 if (!isset($this->data['title']))
3213 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3215 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3217 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3219 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3221 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3223 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3225 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3227 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3229 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3231 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3233 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3235 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3237 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3239 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3243 $this->data['title'] = null;
3246 return $this->data['title'];
3249 function get_description($description_only = false)
3251 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3253 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3255 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3257 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3259 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3261 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));