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 * @var string proxy used to fetch feeds
698 * @see SimplePie::set_proxy()
704 * The SimplePie class contains feed level data and options
706 * There are two ways that you can create a new SimplePie object. The first
707 * is by passing a feed URL as a parameter to the SimplePie constructor
708 * (as well as optionally setting the cache location and cache expiry). This
709 * will initialise the whole feed with all of the default settings, and you
710 * can begin accessing methods and properties immediately.
712 * The second way is to create the SimplePie object with no parameters
713 * at all. This will enable you to set configuration options. After setting
714 * them, you must initialise the feed using $feed->init(). At that point the
715 * object's methods and properties will be available to you. This format is
716 * what is used throughout this documentation.
719 * @since 1.0 Preview Release
720 * @param string $feed_url This is the URL you want to parse.
721 * @param string $cache_location This is where you want the cache to be stored.
722 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
723 * @param string $proxy This is the proxy "host:port" used to fetch feeds
725 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null, $proxy = null)
727 // Other objects, instances created here so we can set options on them
728 $this->sanitize = new SimplePie_Sanitize;
730 // Set options if they're passed to the constructor
731 if ($cache_location !== null)
733 $this->set_cache_location($cache_location);
736 if ($cache_duration !== null)
738 $this->set_cache_duration($cache_duration);
743 $this->set_proxy($proxy);
746 // Only init the script if we're passed a feed URL
747 if ($feed_url !== null)
749 $this->set_feed_url($feed_url);
755 * Used for converting object to a string
757 function __toString()
759 return md5(serialize($this->data));
763 * Remove items that link back to this before destroying this object
765 function __destruct()
767 if (!empty($this->data['items']))
769 foreach ($this->data['items'] as $item)
773 unset($this->data['items']);
775 if (!empty($this->data['ordered_items']))
777 foreach ($this->data['ordered_items'] as $item)
781 unset($this->data['ordered_items']);
786 * Force the given data/URL to be treated as a feed no matter what it
791 * @param bool $enable Force the given data/URL to be treated as a feed
793 function force_feed($enable = false)
795 $this->force_feed = (bool) $enable;
799 * This is the URL of the feed you want to parse.
801 * This allows you to enter the URL of the feed you want to parse, or the
802 * website you want to try to use auto-discovery on. This takes priority
803 * over any set raw data.
805 * You can set multiple feeds to mash together by passing an array instead
806 * of a string for the $url. Remember that with each additional feed comes
807 * additional processing and resources.
810 * @since 1.0 Preview Release
811 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
812 * @see SimplePie::set_raw_data()
814 function set_feed_url($url)
818 $this->multifeed_url = array();
819 foreach ($url as $value)
821 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
826 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
831 * This is the proxy used to fetch feeds
834 * @param string $proxy This is the URL of the proxy "host:port"
836 function set_proxy($proxy)
838 $this->proxy = $proxy;
839 $this->sanitize->proxy = $proxy;
843 * Provides an instance of SimplePie_File to use as a feed
846 * @param object &$file Instance of SimplePie_File (or subclass)
847 * @return bool True on success, false on failure
849 function set_file(&$file)
851 if (is_a($file, 'SimplePie_File'))
853 $this->feed_url = $file->url;
854 $this->file =& $file;
861 * Allows you to use a string of RSS/Atom data instead of a remote feed.
863 * If you have a feed available as a string in PHP, you can tell SimplePie
864 * to parse that data string instead of a remote feed. Any set feed URL
869 * @param string $data RSS or Atom data as a string.
870 * @see SimplePie::set_feed_url()
872 function set_raw_data($data)
874 $this->raw_data = $data;
878 * Allows you to override the default timeout for fetching remote feeds.
880 * This allows you to change the maximum time the feed's server to respond
881 * and send the feed back.
885 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
887 function set_timeout($timeout = 10)
889 $this->timeout = (int) $timeout;
893 * Forces SimplePie to use fsockopen() instead of the preferred cURL
898 * @param bool $enable Force fsockopen() to be used
900 function force_fsockopen($enable = false)
902 $this->force_fsockopen = (bool) $enable;
906 * Outputs the raw XML content of the feed, after it has gone through
907 * SimplePie's filters.
909 * Used only for debugging, this function will output the XML content as
910 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
911 * before trying to parse it. Many parts of the feed are re-written in
912 * memory, and in the end, you have a parsable feed. XML dump shows you the
913 * actual XML that SimplePie tries to parse, which may or may not be very
914 * different from the original feed.
917 * @since 1.0 Preview Release
918 * @param bool $enable Enable XML dump
920 function enable_xml_dump($enable = false)
922 $this->xml_dump = (bool) $enable;
926 * Enables/disables caching in SimplePie.
928 * This option allows you to disable caching all-together in SimplePie.
929 * However, disabling the cache can lead to longer load times.
932 * @since 1.0 Preview Release
933 * @param bool $enable Enable caching
935 function enable_cache($enable = true)
937 $this->cache = (bool) $enable;
941 * Set the length of time (in seconds) that the contents of a feed
945 * @param int $seconds The feed content cache duration.
947 function set_cache_duration($seconds = 3600)
949 $this->cache_duration = (int) $seconds;
953 * Set the length of time (in seconds) that the autodiscovered feed
954 * URL will be cached.
957 * @param int $seconds The autodiscovered feed URL cache duration.
959 function set_autodiscovery_cache_duration($seconds = 604800)
961 $this->autodiscovery_cache_duration = (int) $seconds;
965 * Set the file system location where the cached files should be stored.
968 * @param string $location The file system location.
970 function set_cache_location($location = './cache')
972 $this->cache_location = (string) $location;
976 * Determines whether feed items should be sorted into reverse chronological order.
979 * @param bool $enable Sort as reverse chronological order.
981 function enable_order_by_date($enable = true)
983 $this->order_by_date = (bool) $enable;
987 * Allows you to override the character encoding reported by the feed.
990 * @param string $encoding Character encoding.
992 function set_input_encoding($encoding = false)
996 $this->input_encoding = (string) $encoding;
1000 $this->input_encoding = false;
1005 * Set how much feed autodiscovery to do
1008 * @see SIMPLEPIE_LOCATOR_NONE
1009 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1010 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1011 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1012 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1013 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1014 * @see SIMPLEPIE_LOCATOR_ALL
1015 * @param int $level Feed Autodiscovery Level (level can be a
1016 * combination of the above constants, see bitwise OR operator)
1018 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1020 $this->autodiscovery = (int) $level;
1024 * Allows you to change which class SimplePie uses for caching.
1025 * Useful when you are overloading or extending SimplePie's default classes.
1028 * @param string $class Name of custom class.
1029 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1030 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1032 function set_cache_class($class = 'SimplePie_Cache')
1034 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1036 $this->cache_class = $class;
1043 * Allows you to change which class SimplePie uses for auto-discovery.
1044 * Useful when you are overloading or extending SimplePie's default classes.
1047 * @param string $class Name of custom class.
1048 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1049 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1051 function set_locator_class($class = 'SimplePie_Locator')
1053 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1055 $this->locator_class = $class;
1062 * Allows you to change which class SimplePie uses for XML parsing.
1063 * Useful when you are overloading or extending SimplePie's default classes.
1066 * @param string $class Name of custom class.
1067 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1068 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1070 function set_parser_class($class = 'SimplePie_Parser')
1072 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1074 $this->parser_class = $class;
1081 * Allows you to change which class SimplePie uses for remote file fetching.
1082 * Useful when you are overloading or extending SimplePie's default classes.
1085 * @param string $class Name of custom class.
1086 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1087 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1089 function set_file_class($class = 'SimplePie_File')
1091 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1093 $this->file_class = $class;
1100 * Allows you to change which class SimplePie uses for data sanitization.
1101 * Useful when you are overloading or extending SimplePie's default classes.
1104 * @param string $class Name of custom class.
1105 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1106 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1108 function set_sanitize_class($class = 'SimplePie_Sanitize')
1110 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1112 $this->sanitize = new $class;
1113 $this->sanitize->proxy = $this->proxy;
1120 * Allows you to change which class SimplePie uses for handling feed items.
1121 * Useful when you are overloading or extending SimplePie's default classes.
1124 * @param string $class Name of custom class.
1125 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1126 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1128 function set_item_class($class = 'SimplePie_Item')
1130 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1132 $this->item_class = $class;
1139 * Allows you to change which class SimplePie uses for handling author data.
1140 * Useful when you are overloading or extending SimplePie's default classes.
1143 * @param string $class Name of custom class.
1144 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1145 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1147 function set_author_class($class = 'SimplePie_Author')
1149 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1151 $this->author_class = $class;
1158 * Allows you to change which class SimplePie uses for handling category data.
1159 * Useful when you are overloading or extending SimplePie's default classes.
1162 * @param string $class Name of custom class.
1163 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1164 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1166 function set_category_class($class = 'SimplePie_Category')
1168 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1170 $this->category_class = $class;
1177 * Allows you to change which class SimplePie uses for feed enclosures.
1178 * Useful when you are overloading or extending SimplePie's default classes.
1181 * @param string $class Name of custom class.
1182 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1183 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1185 function set_enclosure_class($class = 'SimplePie_Enclosure')
1187 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1189 $this->enclosure_class = $class;
1196 * Allows you to change which class SimplePie uses for <media:text> captions
1197 * Useful when you are overloading or extending SimplePie's default classes.
1200 * @param string $class Name of custom class.
1201 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1202 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1204 function set_caption_class($class = 'SimplePie_Caption')
1206 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1208 $this->caption_class = $class;
1215 * Allows you to change which class SimplePie uses for <media:copyright>
1216 * Useful when you are overloading or extending SimplePie's default classes.
1219 * @param string $class Name of custom class.
1220 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1221 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1223 function set_copyright_class($class = 'SimplePie_Copyright')
1225 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1227 $this->copyright_class = $class;
1234 * Allows you to change which class SimplePie uses for <media:credit>
1235 * Useful when you are overloading or extending SimplePie's default classes.
1238 * @param string $class Name of custom class.
1239 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1240 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1242 function set_credit_class($class = 'SimplePie_Credit')
1244 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1246 $this->credit_class = $class;
1253 * Allows you to change which class SimplePie uses for <media:rating>
1254 * Useful when you are overloading or extending SimplePie's default classes.
1257 * @param string $class Name of custom class.
1258 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1259 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1261 function set_rating_class($class = 'SimplePie_Rating')
1263 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1265 $this->rating_class = $class;
1272 * Allows you to change which class SimplePie uses for <media:restriction>
1273 * Useful when you are overloading or extending SimplePie's default classes.
1276 * @param string $class Name of custom class.
1277 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1278 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1280 function set_restriction_class($class = 'SimplePie_Restriction')
1282 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1284 $this->restriction_class = $class;
1291 * Allows you to change which class SimplePie uses for content-type sniffing.
1292 * Useful when you are overloading or extending SimplePie's default classes.
1295 * @param string $class Name of custom class.
1296 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1297 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1299 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1301 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1303 $this->content_type_sniffer_class = $class;
1310 * Allows you to change which class SimplePie uses item sources.
1311 * Useful when you are overloading or extending SimplePie's default classes.
1314 * @param string $class Name of custom class.
1315 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1316 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1318 function set_source_class($class = 'SimplePie_Source')
1320 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1322 $this->source_class = $class;
1329 * Allows you to override the default user agent string.
1332 * @param string $ua New user agent string.
1334 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1336 $this->useragent = (string) $ua;
1340 * Set callback function to create cache filename with
1343 * @param mixed $function Callback function
1345 function set_cache_name_function($function = 'md5')
1347 if (is_callable($function))
1349 $this->cache_name_function = $function;
1354 * Set javascript query string parameter
1357 * @param mixed $get Javascript query string parameter
1359 function set_javascript($get = 'js')
1363 $this->javascript = (string) $get;
1367 $this->javascript = false;
1372 * Set options to make SP as fast as possible. Forgoes a
1373 * substantial amount of data sanitization in favor of speed.
1376 * @param bool $set Whether to set them or not
1378 function set_stupidly_fast($set = false)
1382 $this->enable_order_by_date(false);
1383 $this->remove_div(false);
1384 $this->strip_comments(false);
1385 $this->strip_htmltags(false);
1386 $this->strip_attributes(false);
1387 $this->set_image_handler(false);
1392 * Set maximum number of feeds to check with autodiscovery
1395 * @param int $max Maximum number of feeds to check
1397 function set_max_checked_feeds($max = 10)
1399 $this->max_checked_feeds = (int) $max;
1402 function remove_div($enable = true)
1404 $this->sanitize->remove_div($enable);
1407 function strip_htmltags($tags = '', $encode = null)
1411 $tags = $this->strip_htmltags;
1413 $this->sanitize->strip_htmltags($tags);
1414 if ($encode !== null)
1416 $this->sanitize->encode_instead_of_strip($tags);
1420 function encode_instead_of_strip($enable = true)
1422 $this->sanitize->encode_instead_of_strip($enable);
1425 function strip_attributes($attribs = '')
1427 if ($attribs === '')
1429 $attribs = $this->strip_attributes;
1431 $this->sanitize->strip_attributes($attribs);
1434 function set_output_encoding($encoding = 'UTF-8')
1436 $this->sanitize->set_output_encoding($encoding);
1439 function strip_comments($strip = false)
1441 $this->sanitize->strip_comments($strip);
1445 * Set element/attribute key/value pairs of HTML attributes
1446 * containing URLs that need to be resolved relative to the feed
1450 * @param array $element_attribute Element/attribute key/value pairs
1452 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'))
1454 $this->sanitize->set_url_replacements($element_attribute);
1458 * Set the handler to enable the display of cached favicons.
1461 * @param str $page Web-accessible path to the handler_favicon.php file.
1462 * @param str $qs The query string that the value should be passed to.
1464 function set_favicon_handler($page = false, $qs = 'i')
1468 $this->favicon_handler = $page . '?' . $qs . '=';
1472 $this->favicon_handler = '';
1477 * Set the handler to enable the display of cached images.
1480 * @param str $page Web-accessible path to the handler_image.php file.
1481 * @param str $qs The query string that the value should be passed to.
1483 function set_image_handler($page = false, $qs = 'i')
1487 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1491 $this->image_handler = '';
1496 * Set the limit for items returned per-feed with multifeeds.
1499 * @param integer $limit The maximum number of items to return.
1501 function set_item_limit($limit = 0)
1503 $this->item_limit = (int) $limit;
1508 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1512 if (isset($_GET[$this->javascript]))
1514 if (function_exists('ob_gzhandler'))
1516 ob_start('ob_gzhandler');
1518 header('Content-type: text/javascript; charset: UTF-8');
1519 header('Cache-Control: must-revalidate');
1520 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1522 function embed_odeo(link) {
1523 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>');
1526 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1527 if (placeholder != '') {
1528 document.writeln('<embed type="'+type+'" style="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>');
1531 document.writeln('<embed type="'+type+'" style="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>');
1535 function embed_flash(bgcolor, width, height, link, loop, type) {
1536 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>');
1539 function embed_flv(width, height, link, placeholder, loop, player) {
1540 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>');
1543 function embed_wmedia(width, height, link) {
1544 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1550 // Pass whatever was set with config options over to the sanitizer.
1551 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1552 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1554 if ($this->feed_url !== null || $this->raw_data !== null)
1556 $this->data = array();
1557 $this->multifeed_objects = array();
1560 if ($this->feed_url !== null)
1562 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1563 // Decide whether to enable caching
1564 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1566 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1568 // If it's enabled and we don't want an XML dump, use the cache
1569 if ($cache && !$this->xml_dump)
1572 $this->data = $cache->load();
1573 if (!empty($this->data))
1575 // If the cache is for an outdated build of SimplePie
1576 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1579 $this->data = array();
1581 // If we've hit a collision just rerun it with caching disabled
1582 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1585 $this->data = array();
1587 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1588 elseif (isset($this->data['feed_url']))
1590 // If the autodiscovery cache is still valid use it.
1591 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1593 // Do not need to do feed autodiscovery yet.
1594 if ($this->data['feed_url'] == $this->data['url'])
1597 $this->data = array();
1601 $this->set_feed_url($this->data['feed_url']);
1602 return $this->init();
1606 // Check if the cache has been updated
1607 elseif ($cache->mtime() + $this->cache_duration < time())
1609 // If we have last-modified and/or etag set
1610 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1613 if (isset($this->data['headers']['last-modified']))
1615 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1617 if (isset($this->data['headers']['etag']))
1619 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1621 $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->proxy);
1624 if ($file->status_code == 304)
1631 $headers = $file->headers;
1640 // If the cache is still valid, just return true
1646 // If the cache is empty, delete it
1650 $this->data = array();
1653 // 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.
1656 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1658 $file =& $this->file;
1662 $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->proxy);
1665 // If the file connection has an error, set SimplePie::error to that and quit
1666 if (!$file->success)
1668 $this->error = $file->error;
1669 if (!empty($this->data))
1679 if (!$this->force_feed)
1681 // Check if the supplied URL is a feed, if it isn't, look for it.
1682 $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1683 if (!$locate->is_feed($file))
1685 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1687 if ($file = $locate->find($this->autodiscovery))
1691 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1692 if (!$cache->save($this))
1694 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1696 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1698 $this->feed_url = $file->url;
1702 $this->error = "A feed could not be found at $this->feed_url";
1703 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1710 $headers = $file->headers;
1711 $data = $file->body;
1712 $sniffer = new $this->content_type_sniffer_class($file);
1713 $sniffed = $sniffer->get_type();
1717 $data = $this->raw_data;
1720 // Set up array of possible encodings
1721 $encodings = array();
1723 // First check to see if input has been overridden.
1724 if ($this->input_encoding !== false)
1726 $encodings[] = $this->input_encoding;
1729 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1730 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1732 // RFC 3023 (only applies to sniffed content)
1733 if (isset($sniffed))
1735 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1737 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1739 $encodings[] = strtoupper($charset[1]);
1741 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1742 $encodings[] = 'UTF-8';
1744 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1746 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1748 $encodings[] = $charset[1];
1750 $encodings[] = 'US-ASCII';
1752 // Text MIME-type default
1753 elseif (substr($sniffed, 0, 5) === 'text/')
1755 $encodings[] = 'US-ASCII';
1759 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1760 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1761 $encodings[] = 'UTF-8';
1762 $encodings[] = 'ISO-8859-1';
1764 // There's no point in trying an encoding twice
1765 $encodings = array_unique($encodings);
1767 // If we want the XML, just output that with the most likely encoding and quit
1768 if ($this->xml_dump)
1770 header('Content-type: text/xml; charset=' . $encodings[0]);
1775 // Loop through each possible encoding, till we return something, or run out of possibilities
1776 foreach ($encodings as $encoding)
1778 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1779 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1781 // Create new parser
1782 $parser = new $this->parser_class();
1784 // If it's parsed fine
1785 if ($parser->parse($utf8_data, 'UTF-8'))
1787 $this->data = $parser->get_data();
1788 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1790 if (isset($headers))
1792 $this->data['headers'] = $headers;
1794 $this->data['build'] = SIMPLEPIE_BUILD;
1796 // Cache the file if caching is enabled
1797 if ($cache && !$cache->save($this))
1799 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1805 $this->error = "A feed could not be found at $this->feed_url";
1806 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1812 // We have an error, just set SimplePie::error to it and quit
1813 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1814 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1817 elseif (!empty($this->multifeed_url))
1821 $this->multifeed_objects = array();
1822 foreach ($this->multifeed_url as $url)
1826 // This keyword needs to defy coding standards for PHP4 compatibility
1827 $this->multifeed_objects[$i] = clone($this);
1831 $this->multifeed_objects[$i] = $this;
1833 $this->multifeed_objects[$i]->set_feed_url($url);
1834 $success |= $this->multifeed_objects[$i]->init();
1837 return (bool) $success;
1846 * Return the error message for the occured error
1849 * @return string Error message
1853 return $this->error;
1856 function get_encoding()
1858 return $this->sanitize->output_encoding;
1861 function handle_content_type($mime = 'text/html')
1863 if (!headers_sent())
1865 $header = "Content-type: $mime;";
1866 if ($this->get_encoding())
1868 $header .= ' charset=' . $this->get_encoding();
1872 $header .= ' charset=UTF-8';
1880 if (!isset($this->data['type']))
1882 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1883 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1885 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1887 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1889 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1891 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1893 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1894 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1895 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1896 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1898 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1900 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1901 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1902 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1903 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1905 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1908 elseif (isset($this->data['child']['']['rss']))
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1911 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1913 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1916 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1917 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1919 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1922 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1926 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1933 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1937 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1941 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1945 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1952 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1955 return $this->data['type'];
1959 * Returns the URL for the favicon of the feed's website.
1961 * @todo Cache atom:icon
1965 function get_favicon()
1967 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1969 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1971 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1973 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1975 if ($this->cache && $this->favicon_handler)
1977 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1978 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1982 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1986 $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen, $this->proxy);
1988 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1990 $sniffer = new $this->content_type_sniffer_class($file);
1991 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1993 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1995 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1999 trigger_error("$cache->name is not writeable", E_USER_WARNING);
2000 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2008 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2015 * @todo If we have a perm redirect we should return the new URL
2016 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2017 * @todo Also, |atom:link|@rel=self
2019 function subscribe_url()
2021 if ($this->feed_url !== null)
2023 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2031 function subscribe_feed()
2033 if ($this->feed_url !== null)
2035 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2043 function subscribe_outlook()
2045 if ($this->feed_url !== null)
2047 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2055 function subscribe_podcast()
2057 if ($this->feed_url !== null)
2059 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2067 function subscribe_itunes()
2069 if ($this->feed_url !== null)
2071 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2080 * Creates the subscribe_* methods' return data
2083 * @param string $feed_url String to prefix to the feed URL
2084 * @param string $site_url String to prefix to the site URL (and
2085 * suffix to the feed URL)
2086 * @return mixed URL if feed exists, false otherwise
2088 function subscribe_service($feed_url, $site_url = null)
2090 if ($this->subscribe_url())
2092 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2093 if ($site_url !== null && $this->get_link() !== null)
2095 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2105 function subscribe_aol()
2107 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2110 function subscribe_bloglines()
2112 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2115 function subscribe_eskobo()
2117 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2120 function subscribe_feedfeeds()
2122 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2125 function subscribe_feedster()
2127 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2130 function subscribe_google()
2132 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2135 function subscribe_gritwire()
2137 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2140 function subscribe_msn()
2142 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2145 function subscribe_netvibes()
2147 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2150 function subscribe_newsburst()
2152 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2155 function subscribe_newsgator()
2157 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2160 function subscribe_odeo()
2162 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2165 function subscribe_podnova()
2167 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2170 function subscribe_rojo()
2172 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2175 function subscribe_yahoo()
2177 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2180 function get_feed_tags($namespace, $tag)
2182 $type = $this->get_type();
2183 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2185 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2187 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2190 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2192 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2194 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2197 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2199 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2201 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2204 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2206 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2208 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2214 function get_channel_tags($namespace, $tag)
2216 $type = $this->get_type();
2217 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2219 if ($return = $this->get_feed_tags($namespace, $tag))
2224 if ($type & SIMPLEPIE_TYPE_RSS_10)
2226 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2228 if (isset($channel[0]['child'][$namespace][$tag]))
2230 return $channel[0]['child'][$namespace][$tag];
2234 if ($type & SIMPLEPIE_TYPE_RSS_090)
2236 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2238 if (isset($channel[0]['child'][$namespace][$tag]))
2240 return $channel[0]['child'][$namespace][$tag];
2244 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2246 if ($channel = $this->get_feed_tags('', 'channel'))
2248 if (isset($channel[0]['child'][$namespace][$tag]))
2250 return $channel[0]['child'][$namespace][$tag];
2257 function get_image_tags($namespace, $tag)
2259 $type = $this->get_type();
2260 if ($type & SIMPLEPIE_TYPE_RSS_10)
2262 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2264 if (isset($image[0]['child'][$namespace][$tag]))
2266 return $image[0]['child'][$namespace][$tag];
2270 if ($type & SIMPLEPIE_TYPE_RSS_090)
2272 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2274 if (isset($image[0]['child'][$namespace][$tag]))
2276 return $image[0]['child'][$namespace][$tag];
2280 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2282 if ($image = $this->get_channel_tags('', 'image'))
2284 if (isset($image[0]['child'][$namespace][$tag]))
2286 return $image[0]['child'][$namespace][$tag];
2293 function get_base($element = array())
2295 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2297 return $element['xml_base'];
2299 elseif ($this->get_link() !== null)
2301 return $this->get_link();
2305 return $this->subscribe_url();
2309 function sanitize($data, $type, $base = '')
2311 return $this->sanitize->sanitize($data, $type, $base);
2314 function get_title()
2316 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2318 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2320 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2322 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2324 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2326 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2328 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2330 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2332 elseif ($return = $this->get_channel_tags('', 'title'))
2334 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2336 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2338 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2340 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2342 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2350 function get_category($key = 0)
2352 $categories = $this->get_categories();
2353 if (isset($categories[$key]))
2355 return $categories[$key];
2363 function get_categories()
2365 $categories = array();
2367 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2372 if (isset($category['attribs']['']['term']))
2374 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2376 if (isset($category['attribs']['']['scheme']))
2378 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2380 if (isset($category['attribs']['']['label']))
2382 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2384 $categories[] = new $this->category_class($term, $scheme, $label);
2386 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2388 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2390 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2392 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2394 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2396 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2399 if (!empty($categories))
2401 return SimplePie_Misc::array_unique($categories);
2409 function get_author($key = 0)
2411 $authors = $this->get_authors();
2412 if (isset($authors[$key]))
2414 return $authors[$key];
2422 function get_authors()
2425 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2430 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2432 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2434 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2436 $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]));
2438 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2440 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2442 if ($name !== null || $email !== null || $uri !== null)
2444 $authors[] = new $this->author_class($name, $uri, $email);
2447 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2452 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2454 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2456 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2458 $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]));
2460 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2462 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2464 if ($name !== null || $email !== null || $url !== null)
2466 $authors[] = new $this->author_class($name, $url, $email);
2469 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2471 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2473 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2475 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2477 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2479 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2482 if (!empty($authors))
2484 return SimplePie_Misc::array_unique($authors);
2492 function get_contributor($key = 0)
2494 $contributors = $this->get_contributors();
2495 if (isset($contributors[$key]))
2497 return $contributors[$key];
2505 function get_contributors()
2507 $contributors = array();
2508 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2513 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2515 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2517 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2519 $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]));
2521 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2523 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2525 if ($name !== null || $email !== null || $uri !== null)
2527 $contributors[] = new $this->author_class($name, $uri, $email);
2530 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2535 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2537 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2539 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2541 $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]));
2543 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2545 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2547 if ($name !== null || $email !== null || $url !== null)
2549 $contributors[] = new $this->author_class($name, $url, $email);
2553 if (!empty($contributors))
2555 return SimplePie_Misc::array_unique($contributors);
2563 function get_link($key = 0, $rel = 'alternate')
2565 $links = $this->get_links($rel);
2566 if (isset($links[$key]))
2568 return $links[$key];
2577 * Added for parity between the parent-level and the item/entry-level.
2579 function get_permalink()
2581 return $this->get_link(0);
2584 function get_links($rel = 'alternate')
2586 if (!isset($this->data['links']))
2588 $this->data['links'] = array();
2589 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2591 foreach ($links as $link)
2593 if (isset($link['attribs']['']['href']))
2595 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2596 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2600 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2602 foreach ($links as $link)
2604 if (isset($link['attribs']['']['href']))
2606 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2607 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2612 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2614 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2616 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2618 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2620 if ($links = $this->get_channel_tags('', 'link'))
2622 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2625 $keys = array_keys($this->data['links']);
2626 foreach ($keys as $key)
2628 if (SimplePie_Misc::is_isegment_nz_nc($key))
2630 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2632 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2633 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2637 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2640 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2642 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2644 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2648 if (isset($this->data['links'][$rel]))
2650 return $this->data['links'][$rel];
2658 function get_description()
2660 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2662 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2664 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2666 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2668 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2670 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2672 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2674 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2676 elseif ($return = $this->get_channel_tags('', 'description'))
2678 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2680 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2682 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2684 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2688 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2692 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2702 function get_copyright()
2704 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2706 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2708 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2710 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2712 elseif ($return = $this->get_channel_tags('', 'copyright'))
2714 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2716 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2718 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2720 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2722 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2730 function get_language()
2732 if ($return = $this->get_channel_tags('', 'language'))
2734 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2736 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2738 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2740 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2742 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2744 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2746 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2748 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2750 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2752 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2754 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2756 elseif (isset($this->data['headers']['content-language']))
2758 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2766 function get_latitude()
2768 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2770 return (float) $return[0]['data'];
2772 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2774 return (float) $match[1];
2782 function get_longitude()
2784 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2786 return (float) $return[0]['data'];
2788 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2790 return (float) $return[0]['data'];
2792 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2794 return (float) $match[2];
2802 function get_image_title()
2804 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2806 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2808 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2810 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2812 elseif ($return = $this->get_image_tags('', 'title'))
2814 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2816 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2818 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2820 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2822 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2830 function get_image_url()
2832 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2834 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2836 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2838 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2840 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2842 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2844 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2846 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2848 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2850 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2852 elseif ($return = $this->get_image_tags('', 'url'))
2854 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2862 function get_image_link()
2864 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2866 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2868 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2870 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2872 elseif ($return = $this->get_image_tags('', 'link'))
2874 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2882 function get_image_width()
2884 if ($return = $this->get_image_tags('', 'width'))
2886 return round($return[0]['data']);
2888 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2898 function get_image_height()
2900 if ($return = $this->get_image_tags('', 'height'))
2902 return round($return[0]['data']);
2904 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2914 function get_item_quantity($max = 0)
2916 $qty = count($this->get_items());
2923 return ($qty > $max) ? $max : $qty;
2927 function get_item($key = 0)
2929 $items = $this->get_items();
2930 if (isset($items[$key]))
2932 return $items[$key];
2940 function get_items($start = 0, $end = 0)
2942 if (!empty($this->multifeed_objects))
2944 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2946 elseif (!isset($this->data['items']))
2948 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2950 $keys = array_keys($items);
2951 foreach ($keys as $key)
2953 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2956 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2958 $keys = array_keys($items);
2959 foreach ($keys as $key)
2961 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2964 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2966 $keys = array_keys($items);
2967 foreach ($keys as $key)
2969 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2972 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2974 $keys = array_keys($items);
2975 foreach ($keys as $key)
2977 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2980 if ($items = $this->get_channel_tags('', 'item'))
2982 $keys = array_keys($items);
2983 foreach ($keys as $key)
2985 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2990 if (!empty($this->data['items']))
2992 // If we want to order it by date, check if all items have a date, and then sort it
2993 if ($this->order_by_date)
2995 if (!isset($this->data['ordered_items']))
2998 foreach ($this->data['items'] as $item)
3000 if (!$item->get_date('U'))
3007 $this->data['ordered_items'] = $this->data['items'];
3010 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3013 $items = $this->data['ordered_items'];
3017 $items = $this->data['items'];
3020 // Slice the data as desired
3023 return array_slice($items, $start);
3027 return array_slice($items, $start, $end);
3036 function sort_items($a, $b)
3038 return $a->get_date('U') <= $b->get_date('U');
3041 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3043 if (is_array($urls) && sizeof($urls) > 0)
3046 foreach ($urls as $arg)
3048 if (is_a($arg, 'SimplePie'))
3050 $items = array_merge($items, $arg->get_items(0, $limit));
3054 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3059 foreach ($items as $item)
3061 if (!$item->get_date('U'))
3070 usort($items, array('SimplePie', 'sort_items'));
3075 return array_slice($items, $start);
3079 return array_slice($items, $start, $end);
3084 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3090 class SimplePie_Item
3093 var $data = array();
3095 function SimplePie_Item($feed, $data)
3097 $this->feed = $feed;
3098 $this->data = $data;
3101 function __toString()
3103 return md5(serialize($this->data));
3107 * Remove items that link back to this before destroying this object
3109 function __destruct()
3114 function get_item_tags($namespace, $tag)
3116 if (isset($this->data['child'][$namespace][$tag]))
3118 return $this->data['child'][$namespace][$tag];
3126 function get_base($element = array())
3128 return $this->feed->get_base($element);
3131 function sanitize($data, $type, $base = '')
3133 return $this->feed->sanitize($data, $type, $base);
3141 function get_id($hash = false)
3145 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3147 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3149 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3151 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3153 elseif ($return = $this->get_item_tags('', 'guid'))
3155 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3157 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3159 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3161 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3163 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3165 elseif (($return = $this->get_permalink()) !== null)
3169 elseif (($return = $this->get_title()) !== null)
3174 if ($this->get_permalink() !== null || $this->get_title() !== null)
3176 return md5($this->get_permalink() . $this->get_title());
3180 return md5(serialize($this->data));
3184 function get_title()
3186 if (!isset($this->data['title']))
3188 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3190 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3192 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3194 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3196 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3198 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3200 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3202 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3204 elseif ($return = $this->get_item_tags('', 'title'))
3206 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3210 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3212 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3214 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3218 $this->data['title'] = null;
3221 return $this->data['title'];
3224 function get_description($description_only = false)
3226 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3228 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3232 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3236 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3238 elseif ($return = $this->get_item_tags('', 'description'))
3240 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3242 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3244 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3246 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3248 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3250 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3252 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3254 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3256 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3258 elseif (!$description_only)
3260 return $this->get_content(true);
3268 function get_content($content_only = false)
3270 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3272 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3274 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3276 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3278 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3280 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3282 elseif (!$content_only)
3284 return $this->get_description(true);
3292 function get_category($key = 0)
3294 $categories = $this->get_categories();
3295 if (isset($categories[$key]))
3297 return $categories[$key];
3305 function get_categories()
3307 $categories = array();
3309 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3314 if (isset($category['attribs']['']['term']))
3316 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3318 if (isset($category['attribs']['']['scheme']))
3320 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3322 if (isset($category['attribs']['']['label']))
3324 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3326 $categories[] = new $this->feed->category_class($term, $scheme, $label);
3328 foreach ((array) $this->get_item_tags('', 'category') as $category)
3330 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3332 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3334 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3336 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3338 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3341 if (!empty($categories))
3343 return SimplePie_Misc::array_unique($categories);
3351 function get_author($key = 0)
3353 $authors = $this->get_authors();
3354 if (isset($authors[$key]))
3356 return $authors[$key];
3364 function get_contributor($key = 0)
3366 $contributors = $this->get_contributors();
3367 if (isset($contributors[$key]))
3369 return $contributors[$key];
3377 function get_contributors()
3379 $contributors = array();
3380 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3385 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3387 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3389 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3391 $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]));
3393 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3395 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3397 if ($name !== null || $email !== null || $uri !== null)
3399 $contributors[] = new $this->feed->author_class($name, $uri, $email);
3402 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3407 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3409 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3411 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3413 $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]));
3415 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3417 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3419 if ($name !== null || $email !== null || $url !== null)
3421 $contributors[] = new $this->feed->author_class($name, $url, $email);
3425 if (!empty($contributors))
3427 return SimplePie_Misc::array_unique($contributors);
3436 * @todo Atom inheritance (item author, source author, feed author)
3438 function get_authors()
3441 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3446 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3448 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3450 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3452 $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]));
3454 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3456 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3458 if ($name !== null || $email !== null || $uri !== null)
3460 $authors[] = new $this->feed->author_class($name, $uri, $email);
3463 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3468 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3470 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3472 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3474 $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]));
3476 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3478 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3480 if ($name !== null || $email !== null || $url !== null)
3482 $authors[] = new $this->feed->author_class($name, $url, $email);
3485 if ($author = $this->get_item_tags('', 'author'))
3487 $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3489 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3491 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3493 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3495 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3497 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3499 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3502 if (!empty($authors))
3504 return SimplePie_Misc::array_unique($authors);
3506 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3510 elseif ($authors = $this->feed->get_authors())
3520 function get_copyright()
3522 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3524 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3526 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3528 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3530 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3532 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3540 function get_date($date_format = 'j F Y, g:i a')
3542 if (!isset($this->data['date']))
3544 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3546 $this->data['date']['raw'] = $return[0]['data'];
3548 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3550 $this->data['date']['raw'] = $return[0]['data'];
3552 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3554 $this->data['date']['raw'] = $return[0]['data'];
3556 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3558 $this->data['date']['raw'] = $return[0]['data'];
3560 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3562 $this->data['date']['raw'] = $return[0]['data'];
3564 elseif ($return = $this->get_item_tags('', 'pubDate'))
3566 $this->data['date']['raw'] = $return[0]['data'];
3568 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3570 $this->data['date']['raw'] = $return[0]['data'];
3572 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3574 $this->data['date']['raw'] = $return[0]['data'];
3577 if (!empty($this->data['date']['raw']))
3579 $parser = SimplePie_Parse_Date::get();
3580 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3584 $this->data['date'] = null;
3587 if ($this->data['date'])
3589 $date_format = (string) $date_format;
3590 switch ($date_format)
3593 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3596 return $this->data['date']['parsed'];
3599 return date($date_format, $this->data['date']['parsed']);
3608 function get_local_date($date_format = '%c')
3612 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3614 elseif (($date = $this->get_date('U')) !== null)
3616 return strftime($date_format, $date);
3624 function get_permalink()
3626 $link = $this->get_link();
3627 $enclosure = $this->get_enclosure(0);
3632 elseif ($enclosure !== null)
3634 return $enclosure->get_link();
3642 function get_link($key = 0, $rel = 'alternate')
3644 $links = $this->get_links($rel);
3645 if ($links[$key] !== null)
3647 return $links[$key];
3655 function get_links($rel = 'alternate')
3657 if (!isset($this->data['links']))
3659 $this->data['links'] = array();
3660 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3662 if (isset($link['attribs']['']['href']))
3664 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3665 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3669 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3671 if (isset($link['attribs']['']['href']))
3673 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3674 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3677 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3679 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3681 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3683 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3685 if ($links = $this->get_item_tags('', 'link'))
3687 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3689 if ($links = $this->get_item_tags('', 'guid'))
3691 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3693 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3697 $keys = array_keys($this->data['links']);
3698 foreach ($keys as $key)
3700 if (SimplePie_Misc::is_isegment_nz_nc($key))
3702 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3704 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3705 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3709 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3712 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3714 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3716 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3719 if (isset($this->data['links'][$rel]))
3721 return $this->data['links'][$rel];
3730 * @todo Add ability to prefer one type of content over another (in a media group).
3732 function get_enclosure($key = 0, $prefer = null)
3734 $enclosures = $this->get_enclosures();
3735 if (isset($enclosures[$key]))
3737 return $enclosures[$key];
3746 * Grabs all available enclosures (podcasts, etc.)
3748 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3750 * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support.
3752 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3753 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
3755 function get_enclosures()
3757 if (!isset($this->data['enclosures']))
3759 $this->data['enclosures'] = array();
3762 $captions_parent = null;
3763 $categories_parent = null;
3764 $copyrights_parent = null;
3765 $credits_parent = null;
3766 $description_parent = null;
3767 $duration_parent = null;
3768 $hashes_parent = null;
3769 $keywords_parent = null;
3770 $player_parent = null;
3771 $ratings_parent = null;
3772 $restrictions_parent = null;
3773 $thumbnails_parent = null;
3774 $title_parent = null;
3776 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3777 $parent = $this->get_feed();
3780 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3782 foreach ($captions as $caption)
3784 $caption_type = null;
3785 $caption_lang = null;
3786 $caption_startTime = null;
3787 $caption_endTime = null;
3788 $caption_text = null;
3789 if (isset($caption['attribs']['']['type']))
3791 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3793 if (isset($caption['attribs']['']['lang']))
3795 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3797 if (isset($caption['attribs']['']['start']))
3799 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3801 if (isset($caption['attribs']['']['end']))
3803 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3805 if (isset($caption['data']))
3807 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3809 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3812 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3814 foreach ($captions as $caption)
3816 $caption_type = null;
3817 $caption_lang = null;
3818 $caption_startTime = null;
3819 $caption_endTime = null;
3820 $caption_text = null;
3821 if (isset($caption['attribs']['']['type']))
3823 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3825 if (isset($caption['attribs']['']['lang']))
3827 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3829 if (isset($caption['attribs']['']['start']))
3831 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3833 if (isset($caption['attribs']['']['end']))
3835 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3837 if (isset($caption['data']))
3839 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3841 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3844 if (is_array($captions_parent))
3846 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3850 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3855 if (isset($category['data']))
3857 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3859 if (isset($category['attribs']['']['scheme']))
3861 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3865 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3867 if (isset($category['attribs']['']['label']))
3869 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3871 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3873 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3878 if (isset($category['data']))
3880 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3882 if (isset($category['attribs']['']['scheme']))
3884 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3888 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3890 if (isset($category['attribs']['']['label']))
3892 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3894 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3896 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3899 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3901 if (isset($category['attribs']['']['text']))
3903 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3905 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3907 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3909 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3911 if (isset($subcategory['attribs']['']['text']))
3913 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3915 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3919 if (is_array($categories_parent))
3921 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3925 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3927 $copyright_url = null;
3928 $copyright_label = null;
3929 if (isset($copyright[0]['attribs']['']['url']))
3931 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3933 if (isset($copyright[0]['data']))
3935 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3937 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3939 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3941 $copyright_url = null;
3942 $copyright_label = null;
3943 if (isset($copyright[0]['attribs']['']['url']))
3945 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3947 if (isset($copyright[0]['data']))
3949 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3951 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3955 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3957 foreach ($credits as $credit)
3959 $credit_role = null;
3960 $credit_scheme = null;
3961 $credit_name = null;
3962 if (isset($credit['attribs']['']['role']))
3964 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3966 if (isset($credit['attribs']['']['scheme']))
3968 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 $credit_scheme = 'urn:ebu';
3974 if (isset($credit['data']))
3976 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3978 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3981 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3983 foreach ($credits as $credit)
3985 $credit_role = null;
3986 $credit_scheme = null;
3987 $credit_name = null;
3988 if (isset($credit['attribs']['']['role']))
3990 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3992 if (isset($credit['attribs']['']['scheme']))
3994 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3998 $credit_scheme = 'urn:ebu';
4000 if (isset($credit['data']))
4002 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4004 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4007 if (is_array($credits_parent))
4009 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4013 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4015 if (isset($description_parent[0]['data']))
4017 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4020 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4022 if (isset($description_parent[0]['data']))
4024 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4029 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4034 if (isset($duration_parent[0]['data']))
4036 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4037 if (sizeof($temp) > 0)
4039 (int) $seconds = array_pop($temp);
4041 if (sizeof($temp) > 0)
4043 (int) $minutes = array_pop($temp);
4044 $seconds += $minutes * 60;
4046 if (sizeof($temp) > 0)
4048 (int) $hours = array_pop($temp);
4049 $seconds += $hours * 3600;
4052 $duration_parent = $seconds;
4057 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4059 foreach ($hashes_iterator as $hash)
4063 if (isset($hash['data']))
4065 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4067 if (isset($hash['attribs']['']['algo']))
4069 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4075 $hashes_parent[] = $algo.':'.$value;
4078 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4080 foreach ($hashes_iterator as $hash)
4084 if (isset($hash['data']))
4086 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4088 if (isset($hash['attribs']['']['algo']))
4090 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4096 $hashes_parent[] = $algo.':'.$value;
4099 if (is_array($hashes_parent))
4101 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4105 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4107 if (isset($keywords[0]['data']))
4109 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4110 foreach ($temp as $word)
4112 $keywords_parent[] = trim($word);
4117 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4119 if (isset($keywords[0]['data']))
4121 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4122 foreach ($temp as $word)
4124 $keywords_parent[] = trim($word);
4129 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4131 if (isset($keywords[0]['data']))
4133 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4134 foreach ($temp as $word)
4136 $keywords_parent[] = trim($word);
4141 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4143 if (isset($keywords[0]['data']))
4145 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4146 foreach ($temp as $word)
4148 $keywords_parent[] = trim($word);
4153 if (is_array($keywords_parent))
4155 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4159 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4161 if (isset($player_parent[0]['attribs']['']['url']))
4163 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4166 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4168 if (isset($player_parent[0]['attribs']['']['url']))
4170 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4175 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4177 foreach ($ratings as $rating)
4179 $rating_scheme = null;
4180 $rating_value = null;
4181 if (isset($rating['attribs']['']['scheme']))
4183 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4187 $rating_scheme = 'urn:simple';
4189 if (isset($rating['data']))
4191 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4193 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4196 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4198 foreach ($ratings as $rating)
4200 $rating_scheme = 'urn:itunes';
4201 $rating_value = null;
4202 if (isset($rating['data']))
4204 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4206 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4209 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4211 foreach ($ratings as $rating)
4213 $rating_scheme = null;
4214 $rating_value = null;
4215 if (isset($rating['attribs']['']['scheme']))
4217 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4221 $rating_scheme = 'urn:simple';
4223 if (isset($rating['data']))
4225 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4227 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4230 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4232 foreach ($ratings as $rating)
4234 $rating_scheme = 'urn:itunes';
4235 $rating_value = null;
4236 if (isset($rating['data']))
4238 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4240 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4243 if (is_array($ratings_parent))
4245 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4249 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4251 foreach ($restrictions as $restriction)
4253 $restriction_relationship = null;
4254 $restriction_type = null;
4255 $restriction_value = null;
4256 if (isset($restriction['attribs']['']['relationship']))
4258 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4260 if (isset($restriction['attribs']['']['type']))
4262 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4264 if (isset($restriction['data']))
4266 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4268 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4271 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4273 foreach ($restrictions as $restriction)
4275 $restriction_relationship = 'allow';
4276 $restriction_type = null;
4277 $restriction_value = 'itunes';
4278 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4280 $restriction_relationship = 'deny';
4282 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4285 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4287 foreach ($restrictions as $restriction)
4289 $restriction_relationship = null;
4290 $restriction_type = null;
4291 $restriction_value = null;
4292 if (isset($restriction['attribs']['']['relationship']))
4294 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4296 if (isset($restriction['attribs']['']['type']))
4298 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4300 if (isset($restriction['data']))
4302 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4304 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4307 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4309 foreach ($restrictions as $restriction)
4311 $restriction_relationship = 'allow';
4312 $restriction_type = null;
4313 $restriction_value = 'itunes';
4314 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4316 $restriction_relationship = 'deny';
4318 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4321 if (is_array($restrictions_parent))
4323 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4327 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4329 foreach ($thumbnails as $thumbnail)
4331 if (isset($thumbnail['attribs']['']['url']))
4333 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4337 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4339 foreach ($thumbnails as $thumbnail)
4341 if (isset($thumbnail['attribs']['']['url']))
4343 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4349 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4351 if (isset($title_parent[0]['data']))
4353 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4356 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4358 if (isset($title_parent[0]['data']))
4360 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4378 $samplingrate = null;
4388 $description = null;
4393 $restrictions = null;
4397 // If we have media:group tags, loop through them.
4398 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4400 // If we have media:content tags, loop through them.
4401 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4403 if (isset($content['attribs']['']['url']))
4416 $samplingrate = null;
4426 $description = null;
4431 $restrictions = null;
4435 // Start checking the attributes of media:content
4436 if (isset($content['attribs']['']['bitrate']))
4438 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4440 if (isset($content['attribs']['']['channels']))
4442 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4444 if (isset($content['attribs']['']['duration']))
4446 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4450 $duration = $duration_parent;
4452 if (isset($content['attribs']['']['expression']))
4454 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4456 if (isset($content['attribs']['']['framerate']))
4458 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4460 if (isset($content['attribs']['']['height']))
4462 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4464 if (isset($content['attribs']['']['lang']))
4466 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4468 if (isset($content['attribs']['']['fileSize']))
4470 $length = ceil($content['attribs']['']['fileSize']);
4472 if (isset($content['attribs']['']['medium']))
4474 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4476 if (isset($content['attribs']['']['samplingrate']))
4478 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4480 if (isset($content['attribs']['']['type']))
4482 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4484 if (isset($content['attribs']['']['width']))
4486 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4488 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4490 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4493 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4495 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4497 $caption_type = null;
4498 $caption_lang = null;
4499 $caption_startTime = null;
4500 $caption_endTime = null;
4501 $caption_text = null;
4502 if (isset($caption['attribs']['']['type']))
4504 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4506 if (isset($caption['attribs']['']['lang']))
4508 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4510 if (isset($caption['attribs']['']['start']))
4512 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4514 if (isset($caption['attribs']['']['end']))
4516 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4518 if (isset($caption['data']))
4520 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4522 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4524 if (is_array($captions))
4526 $captions = array_values(SimplePie_Misc::array_unique($captions));
4529 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4531 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4533 $caption_type = null;
4534 $caption_lang = null;
4535 $caption_startTime = null;
4536 $caption_endTime = null;
4537 $caption_text = null;
4538 if (isset($caption['attribs']['']['type']))
4540 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4542 if (isset($caption['attribs']['']['lang']))
4544 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4546 if (isset($caption['attribs']['']['start']))
4548 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4550 if (isset($caption['attribs']['']['end']))
4552 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4554 if (isset($caption['data']))
4556 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4558 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4560 if (is_array($captions))
4562 $captions = array_values(SimplePie_Misc::array_unique($captions));
4567 $captions = $captions_parent;
4571 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4573 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4578 if (isset($category['data']))
4580 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4582 if (isset($category['attribs']['']['scheme']))
4584 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4588 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4590 if (isset($category['attribs']['']['label']))
4592 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4594 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4597 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4599 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4604 if (isset($category['data']))
4606 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4608 if (isset($category['attribs']['']['scheme']))
4610 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4614 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4616 if (isset($category['attribs']['']['label']))
4618 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4620 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4623 if (is_array($categories) && is_array($categories_parent))
4625 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4627 elseif (is_array($categories))
4629 $categories = array_values(SimplePie_Misc::array_unique($categories));
4631 elseif (is_array($categories_parent))
4633 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4637 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4639 $copyright_url = null;
4640 $copyright_label = null;
4641 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4643 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4645 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4647 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4649 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4651 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4653 $copyright_url = null;
4654 $copyright_label = null;
4655 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4657 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4659 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4661 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4663 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4667 $copyrights = $copyrights_parent;
4671 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4673 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4675 $credit_role = null;
4676 $credit_scheme = null;
4677 $credit_name = null;
4678 if (isset($credit['attribs']['']['role']))
4680 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4682 if (isset($credit['attribs']['']['scheme']))
4684 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4688 $credit_scheme = 'urn:ebu';
4690 if (isset($credit['data']))
4692 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4694 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4696 if (is_array($credits))
4698 $credits = array_values(SimplePie_Misc::array_unique($credits));
4701 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4703 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4705 $credit_role = null;
4706 $credit_scheme = null;
4707 $credit_name = null;
4708 if (isset($credit['attribs']['']['role']))
4710 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4712 if (isset($credit['attribs']['']['scheme']))
4714 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4718 $credit_scheme = 'urn:ebu';
4720 if (isset($credit['data']))
4722 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4724 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4726 if (is_array($credits))
4728 $credits = array_values(SimplePie_Misc::array_unique($credits));
4733 $credits = $credits_parent;
4737 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4739 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4741 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4743 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4747 $description = $description_parent;
4751 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4753 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4757 if (isset($hash['data']))
4759 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4761 if (isset($hash['attribs']['']['algo']))
4763 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4769 $hashes[] = $algo.':'.$value;
4771 if (is_array($hashes))
4773 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4776 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4778 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4782 if (isset($hash['data']))
4784 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4786 if (isset($hash['attribs']['']['algo']))
4788 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4794 $hashes[] = $algo.':'.$value;
4796 if (is_array($hashes))
4798 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4803 $hashes = $hashes_parent;
4807 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4809 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4811 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4812 foreach ($temp as $word)
4814 $keywords[] = trim($word);
4818 if (is_array($keywords))
4820 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4823 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4825 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4827 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4828 foreach ($temp as $word)
4830 $keywords[] = trim($word);
4834 if (is_array($keywords))
4836 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4841 $keywords = $keywords_parent;
4845 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4847 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4849 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4851 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4855 $player = $player_parent;
4859 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4861 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4863 $rating_scheme = null;
4864 $rating_value = null;
4865 if (isset($rating['attribs']['']['scheme']))
4867 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4871 $rating_scheme = 'urn:simple';
4873 if (isset($rating['data']))
4875 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4877 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4879 if (is_array($ratings))
4881 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4884 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4886 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4888 $rating_scheme = null;
4889 $rating_value = null;
4890 if (isset($rating['attribs']['']['scheme']))
4892 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4896 $rating_scheme = 'urn:simple';
4898 if (isset($rating['data']))
4900 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4902 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4904 if (is_array($ratings))
4906 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4911 $ratings = $ratings_parent;
4915 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4917 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4919 $restriction_relationship = null;
4920 $restriction_type = null;
4921 $restriction_value = null;
4922 if (isset($restriction['attribs']['']['relationship']))
4924 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4926 if (isset($restriction['attribs']['']['type']))
4928 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4930 if (isset($restriction['data']))
4932 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4934 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4936 if (is_array($restrictions))
4938 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4941 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4943 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4945 $restriction_relationship = null;
4946 $restriction_type = null;
4947 $restriction_value = null;
4948 if (isset($restriction['attribs']['']['relationship']))
4950 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4952 if (isset($restriction['attribs']['']['type']))
4954 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4956 if (isset($restriction['data']))
4958 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4960 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4962 if (is_array($restrictions))
4964 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4969 $restrictions = $restrictions_parent;
4973 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4975 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4977 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4979 if (is_array($thumbnails))
4981 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4984 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4986 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4988 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4990 if (is_array($thumbnails))
4992 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4997 $thumbnails = $thumbnails_parent;
5001 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5003 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5005 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5007 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5011 $title = $title_parent;
5014 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
5019 // If we have standalone media:content tags, loop through them.
5020 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5022 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5024 if (isset($content['attribs']['']['url']))
5037 $samplingrate = null;
5047 $description = null;
5052 $restrictions = null;
5056 // Start checking the attributes of media:content
5057 if (isset($content['attribs']['']['bitrate']))
5059 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5061 if (isset($content['attribs']['']['channels']))
5063 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5065 if (isset($content['attribs']['']['duration']))
5067 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5071 $duration = $duration_parent;
5073 if (isset($content['attribs']['']['expression']))
5075 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5077 if (isset($content['attribs']['']['framerate']))
5079 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5081 if (isset($content['attribs']['']['height']))
5083 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5085 if (isset($content['attribs']['']['lang']))
5087 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5089 if (isset($content['attribs']['']['fileSize']))
5091 $length = ceil($content['attribs']['']['fileSize']);
5093 if (isset($content['attribs']['']['medium']))
5095 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5097 if (isset($content['attribs']['']['samplingrate']))
5099 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5101 if (isset($content['attribs']['']['type']))
5103 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5105 if (isset($content['attribs']['']['width']))
5107 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5109 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5111 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5114 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5116 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5118 $caption_type = null;
5119 $caption_lang = null;
5120 $caption_startTime = null;
5121 $caption_endTime = null;
5122 $caption_text = null;
5123 if (isset($caption['attribs']['']['type']))
5125 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5127 if (isset($caption['attribs']['']['lang']))
5129 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5131 if (isset($caption['attribs']['']['start']))
5133 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5135 if (isset($caption['attribs']['']['end']))
5137 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5139 if (isset($caption['data']))
5141 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5143 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5145 if (is_array($captions))
5147 $captions = array_values(SimplePie_Misc::array_unique($captions));
5152 $captions = $captions_parent;
5156 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5158 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5163 if (isset($category['data']))
5165 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5167 if (isset($category['attribs']['']['scheme']))
5169 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5173 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5175 if (isset($category['attribs']['']['label']))
5177 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5179 $categories[] = new $this->feed->category_class($term, $scheme, $label);
5182 if (is_array($categories) && is_array($categories_parent))
5184 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5186 elseif (is_array($categories))
5188 $categories = array_values(SimplePie_Misc::array_unique($categories));
5190 elseif (is_array($categories_parent))
5192 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5200 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5202 $copyright_url = null;
5203 $copyright_label = null;
5204 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5206 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5208 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5210 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5212 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
5216 $copyrights = $copyrights_parent;
5220 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5222 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5224 $credit_role = null;
5225 $credit_scheme = null;
5226 $credit_name = null;
5227 if (isset($credit['attribs']['']['role']))
5229 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5231 if (isset($credit['attribs']['']['scheme']))
5233 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5237 $credit_scheme = 'urn:ebu';
5239 if (isset($credit['data']))
5241 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5243 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5245 if (is_array($credits))
5247 $credits = array_values(SimplePie_Misc::array_unique($credits));
5252 $credits = $credits_parent;
5256 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5258 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5262 $description = $description_parent;
5266 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5268 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5272 if (isset($hash['data']))
5274 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5276 if (isset($hash['attribs']['']['algo']))
5278 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5284 $hashes[] = $algo.':'.$value;
5286 if (is_array($hashes))
5288 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5293 $hashes = $hashes_parent;
5297 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5299 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5301 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5302 foreach ($temp as $word)
5304 $keywords[] = trim($word);
5308 if (is_array($keywords))
5310 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5315 $keywords = $keywords_parent;
5319 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5321 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5325 $player = $player_parent;
5329 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5331 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5333 $rating_scheme = null;
5334 $rating_value = null;
5335 if (isset($rating['attribs']['']['scheme']))
5337 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5341 $rating_scheme = 'urn:simple';
5343 if (isset($rating['data']))
5345 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5347 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
5349 if (is_array($ratings))
5351 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5356 $ratings = $ratings_parent;
5360 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5362 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5364 $restriction_relationship = null;
5365 $restriction_type = null;
5366 $restriction_value = null;
5367 if (isset($restriction['attribs']['']['relationship']))
5369 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5371 if (isset($restriction['attribs']['']['type']))
5373 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5375 if (isset($restriction['data']))
5377 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5379 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5381 if (is_array($restrictions))
5383 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5388 $restrictions = $restrictions_parent;
5392 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5394 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5396 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5398 if (is_array($thumbnails))
5400 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5405 $thumbnails = $thumbnails_parent;
5409 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5411 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5415 $title = $title_parent;
5418 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
5423 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5425 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5438 $samplingrate = null;
5443 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5444 if (isset($link['attribs']['']['type']))
5446 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5448 if (isset($link['attribs']['']['length']))
5450 $length = ceil($link['attribs']['']['length']);
5453 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5454 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5458 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5460 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5473 $samplingrate = null;
5478 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5479 if (isset($link['attribs']['']['type']))
5481 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5483 if (isset($link['attribs']['']['length']))
5485 $length = ceil($link['attribs']['']['length']);
5488 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5489 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5493 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5495 if (isset($enclosure[0]['attribs']['']['url']))
5508 $samplingrate = null;
5513 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5514 if (isset($enclosure[0]['attribs']['']['type']))
5516 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5518 if (isset($enclosure[0]['attribs']['']['length']))
5520 $length = ceil($enclosure[0]['attribs']['']['length']);
5523 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5524 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5528 if (sizeof($this->data['enclosures']) == 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
5530 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5531 $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5534 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5536 if (!empty($this->data['enclosures']))
5538 return $this->data['enclosures'];
5546 function get_latitude()
5548 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5550 return (float) $return[0]['data'];
5552 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5554 return (float) $match[1];
5562 function get_longitude()
5564 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5566 return (float) $return[0]['data'];
5568 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5570 return (float) $return[0]['data'];
5572 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5574 return (float) $match[2];
5582 function get_source()
5584 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5586 return new $this->feed->source_class($this, $return[0]);
5595 * Creates the add_to_* methods' return data
5598 * @param string $item_url String to prefix to the item permalink
5599 * @param string $title_url String to prefix to the item title
5600 * (and suffix to the item permalink)
5601 * @return mixed URL if feed exists, false otherwise
5603 function add_to_service($item_url, $title_url = null, $summary_url = null)
5605 if ($this->get_permalink() !== null)
5607 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5608 if ($title_url !== null && $this->get_title() !== null)
5610 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5612 if ($summary_url !== null && $this->get_description() !== null)
5614 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5624 function add_to_blinklist()
5626 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5629 function add_to_blogmarks()
5631 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5634 function add_to_delicious()
5636 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5639 function add_to_digg()
5641 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5644 function add_to_furl()
5646 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5649 function add_to_magnolia()
5651 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5654 function add_to_myweb20()
5656 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5659 function add_to_newsvine()
5661 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5664 function add_to_reddit()
5666 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5669 function add_to_segnalo()
5671 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5674 function add_to_simpy()
5676 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5679 function add_to_spurl()
5681 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5684 function add_to_wists()
5686 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5689 function search_technorati()
5691 return $this->add_to_service('http://www.technorati.com/search/');
5695 class SimplePie_Source
5698 var $data = array();
5700 function SimplePie_Source($item, $data)
5702 $this->item = $item;
5703 $this->data = $data;
5706 function __toString()
5708 return md5(serialize($this->data));
5712 * Remove items that link back to this before destroying this object
5714 function __destruct()
5719 function get_source_tags($namespace, $tag)
5721 if (isset($this->data['child'][$namespace][$tag]))
5723 return $this->data['child'][$namespace][$tag];
5731 function get_base($element = array())
5733 return $this->item->get_base($element);
5736 function sanitize($data, $type, $base = '')
5738 return $this->item->sanitize($data, $type, $base);
5746 function get_title()
5748 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5750 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5752 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5754 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5756 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5758 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5760 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5762 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5764 elseif ($return = $this->get_source_tags('', 'title'))
5766 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5768 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5770 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5772 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5774 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5782 function get_category($key = 0)
5784 $categories = $this->get_categories();
5785 if (isset($categories[$key]))
5787 return $categories[$key];
5795 function get_categories()
5797 $categories = array();
5799 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5804 if (isset($category['attribs']['']['term']))
5806 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5808 if (isset($category['attribs']['']['scheme']))
5810 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5812 if (isset($category['attribs']['']['label']))
5814 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5816 $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
5818 foreach ((array) $this->get_source_tags('', 'category') as $category)
5820 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5822 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5824 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5826 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5828 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5831 if (!empty($categories))
5833 return SimplePie_Misc::array_unique($categories);
5841 function get_author($key = 0)
5843 $authors = $this->get_authors();
5844 if (isset($authors[$key]))
5846 return $authors[$key];
5854 function get_authors()
5857 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5862 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5864 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5866 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5868 $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]));
5870 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5872 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5874 if ($name !== null || $email !== null || $uri !== null)
5876 $authors[] = new $this->item->feed->author_class($name, $uri, $email);
5879 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5884 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5886 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5888 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5890 $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]));
5892 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5894 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5896 if ($name !== null || $email !== null || $url !== null)
5898 $authors[] = new $this->item->feed->author_class($name, $url, $email);
5901 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5903 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5905 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5907 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5909 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5911 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5914 if (!empty($authors))
5916 return SimplePie_Misc::array_unique($authors);
5924 function get_contributor($key = 0)
5926 $contributors = $this->get_contributors();
5927 if (isset($contributors[$key]))
5929 return $contributors[$key];
5937 function get_contributors()
5939 $contributors = array();
5940 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5945 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5947 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5949 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5951 $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]));
5953 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5955 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5957 if ($name !== null || $email !== null || $uri !== null)
5959 $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
5962 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5967 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5969 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5971 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5973 $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]));
5975 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5977 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5979 if ($name !== null || $email !== null || $url !== null)
5981 $contributors[] = new $this->item->feed->author_class($name, $url, $email);
5985 if (!empty($contributors))
5987 return SimplePie_Misc::array_unique($contributors);
5995 function get_link($key = 0, $rel = 'alternate')
5997 $links = $this->get_links($rel);
5998 if (isset($links[$key]))
6000 return $links[$key];
6009 * Added for parity between the parent-level and the item/entry-level.
6011 function get_permalink()
6013 return $this->get_link(0);
6016 function get_links($rel = 'alternate')
6018 if (!isset($this->data['links']))
6020 $this->data['links'] = array();
6021 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6023 foreach ($links as $link)
6025 if (isset($link['attribs']['']['href']))
6027 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6028 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6032 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6034 foreach ($links as $link)
6036 if (isset($link['attribs']['']['href']))
6038 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6039 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6044 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6046 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6048 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6050 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6052 if ($links = $this->get_source_tags('', 'link'))
6054 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6057 $keys = array_keys($this->data['links']);
6058 foreach ($keys as $key)
6060 if (SimplePie_Misc::is_isegment_nz_nc($key))
6062 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6064 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6065 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6069 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6072 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6074 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6076 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6080 if (isset($this->data['links'][$rel]))
6082 return $this->data['links'][$rel];
6090 function get_description()
6092 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6094 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6096 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6098 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6100 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6102 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6104 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6106 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6108 elseif ($return = $this->get_source_tags('', 'description'))
6110 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6112 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6114 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6116 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6118 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6120 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6122 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6124 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6126 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6134 function get_copyright()
6136 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6138 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6140 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6142 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6144 elseif ($return = $this->get_source_tags('', 'copyright'))
6146 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6148 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6150 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6152 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6154 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6162 function get_language()
6164 if ($return = $this->get_source_tags('', 'language'))
6166 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6168 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6170 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6172 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6174 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6176 elseif (isset($this->data['xml_lang']))
6178 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6186 function get_latitude()
6188 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6190 return (float) $return[0]['data'];
6192 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6194 return (float) $match[1];
6202 function get_longitude()
6204 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6206 return (float) $return[0]['data'];
6208 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6210 return (float) $return[0]['data'];
6212 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6214 return (float) $match[2];
6222 function get_image_url()
6224 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6226 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6228 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6230 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6232 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6234 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6243 class SimplePie_Author
6249 // Constructor, used to input the data
6250 function SimplePie_Author($name = null, $link = null, $email = null)
6252 $this->name = $name;
6253 $this->link = $link;
6254 $this->email = $email;
6257 function __toString()
6259 // There is no $this->data here
6260 return md5(serialize($this));
6265 if ($this->name !== null)
6277 if ($this->link !== null)
6287 function get_email()
6289 if ($this->email !== null)
6291 return $this->email;
6300 class SimplePie_Category
6306 // Constructor, used to input the data
6307 function SimplePie_Category($term = null, $scheme = null, $label = null)
6309 $this->term = $term;
6310 $this->scheme = $scheme;
6311 $this->label = $label;
6314 function __toString()
6316 // There is no $this->data here
6317 return md5(serialize($this));
6322 if ($this->term !== null)
6332 function get_scheme()
6334 if ($this->scheme !== null)
6336 return $this->scheme;
6344 function get_label()
6346 if ($this->label !== null)
6348 return $this->label;
6352 return $this->get_term();
6357 class SimplePie_Enclosure
6387 // Constructor, used to input the data
6388 function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
6390 $this->bitrate = $bitrate;
6391 $this->captions = $captions;
6392 $this->categories = $categories;
6393 $this->channels = $channels;
6394 $this->copyright = $copyright;
6395 $this->credits = $credits;
6396 $this->description = $description;
6397 $this->duration = $duration;
6398 $this->expression = $expression;
6399 $this->framerate = $framerate;
6400 $this->hashes = $hashes;
6401 $this->height = $height;
6402 $this->javascript = $javascript;
6403 $this->keywords = $keywords;
6404 $this->lang = $lang;
6405 $this->length = $length;
6406 $this->link = $link;
6407 $this->medium = $medium;
6408 $this->player = $player;
6409 $this->ratings = $ratings;
6410 $this->restrictions = $restrictions;
6411 $this->samplingrate = $samplingrate;
6412 $this->thumbnails = $thumbnails;
6413 $this->title = $title;
6414 $this->type = $type;
6415 $this->width = $width;
6416 if (class_exists('idna_convert'))
6418 $idn = new idna_convert;
6419 $parsed = SimplePie_Misc::parse_url($link);
6420 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6422 $this->handler = $this->get_handler(); // Needs to load last
6425 function __toString()
6427 // There is no $this->data here
6428 return md5(serialize($this));
6431 function get_bitrate()
6433 if ($this->bitrate !== null)
6435 return $this->bitrate;
6443 function get_caption($key = 0)
6445 $captions = $this->get_captions();
6446 if (isset($captions[$key]))
6448 return $captions[$key];
6456 function get_captions()
6458 if ($this->captions !== null)
6460 return $this->captions;
6468 function get_category($key = 0)
6470 $categories = $this->get_categories();
6471 if (isset($categories[$key]))
6473 return $categories[$key];
6481 function get_categories()
6483 if ($this->categories !== null)
6485 return $this->categories;
6493 function get_channels()
6495 if ($this->channels !== null)
6497 return $this->channels;
6505 function get_copyright()
6507 if ($this->copyright !== null)
6509 return $this->copyright;
6517 function get_credit($key = 0)
6519 $credits = $this->get_credits();
6520 if (isset($credits[$key]))
6522 return $credits[$key];
6530 function get_credits()
6532 if ($this->credits !== null)
6534 return $this->credits;
6542 function get_description()
6544 if ($this->description !== null)
6546 return $this->description;
6554 function get_duration($convert = false)
6556 if ($this->duration !== null)
6560 $time = SimplePie_Misc::time_hms($this->duration);
6565 return $this->duration;
6574 function get_expression()
6576 if ($this->expression !== null)
6578 return $this->expression;
6586 function get_extension()
6588 if ($this->link !== null)
6590 $url = SimplePie_Misc::parse_url($this->link);
6591 if ($url['path'] !== '')
6593 return pathinfo($url['path'], PATHINFO_EXTENSION);
6599 function get_framerate()
6601 if ($this->framerate !== null)
6603 return $this->framerate;
6611 function get_handler()
6613 return $this->get_real_type(true);
6616 function get_hash($key = 0)
6618 $hashes = $this->get_hashes();
6619 if (isset($hashes[$key]))
6621 return $hashes[$key];
6629 function get_hashes()
6631 if ($this->hashes !== null)
6633 return $this->hashes;
6641 function get_height()
6643 if ($this->height !== null)
6645 return $this->height;
6653 function get_language()
6655 if ($this->lang !== null)
6665 function get_keyword($key = 0)
6667 $keywords = $this->get_keywords();
6668 if (isset($keywords[$key]))
6670 return $keywords[$key];
6678 function get_keywords()
6680 if ($this->keywords !== null)
6682 return $this->keywords;
6690 function get_length()
6692 if ($this->length !== null)
6694 return $this->length;
6704 if ($this->link !== null)
6706 return urldecode($this->link);
6714 function get_medium()
6716 if ($this->medium !== null)
6718 return $this->medium;
6726 function get_player()
6728 if ($this->player !== null)
6730 return $this->player;
6738 function get_rating($key = 0)
6740 $ratings = $this->get_ratings();
6741 if (isset($ratings[$key]))
6743 return $ratings[$key];
6751 function get_ratings()
6753 if ($this->ratings !== null)
6755 return $this->ratings;
6763 function get_restriction($key = 0)
6765 $restrictions = $this->get_restrictions();
6766 if (isset($restrictions[$key]))
6768 return $restrictions[$key];
6776 function get_restrictions()
6778 if ($this->restrictions !== null)
6780 return $this->restrictions;
6788 function get_sampling_rate()
6790 if ($this->samplingrate !== null)
6792 return $this->samplingrate;
6802 $length = $this->get_length();
6803 if ($length !== null)
6805 return round($length/1048576, 2);
6813 function get_thumbnail($key = 0)
6815 $thumbnails = $this->get_thumbnails();
6816 if (isset($thumbnails[$key]))
6818 return $thumbnails[$key];
6826 function get_thumbnails()
6828 if ($this->thumbnails !== null)
6830 return $this->thumbnails;
6838 function get_title()
6840 if ($this->title !== null)
6842 return $this->title;
6852 if ($this->type !== null)
6862 function get_width()
6864 if ($this->width !== null)
6866 return $this->width;
6874 function native_embed($options='')
6876 return $this->embed($options, true);
6880 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6882 function embed($options = '', $native = false)
6892 $bgcolor = '#ffffff';
6894 $widescreen = false;
6895 $handler = $this->get_handler();
6896 $type = $this->get_real_type();
6898 // Process options and reassign values as necessary
6899 if (is_array($options))
6905 $options = explode(',', $options);
6906 foreach($options as $option)
6908 $opt = explode(':', $option, 2);
6909 if (isset($opt[0], $opt[1]))
6911 $opt[0] = trim($opt[0]);
6912 $opt[1] = trim($opt[1]);
6928 $altclass = $opt[1];
6948 $mediaplayer = $opt[1];
6952 $widescreen = $opt[1];
6959 $mime = explode('/', $type, 2);
6962 // Process values for 'auto'
6963 if ($width == 'auto')
6965 if ($mime == 'video')
6967 if ($height == 'auto')
6971 elseif ($widescreen)
6973 $width = round((intval($height)/9)*16);
6977 $width = round((intval($height)/3)*4);
6986 if ($height == 'auto')
6988 if ($mime == 'audio')
6992 elseif ($mime == 'video')
6994 if ($width == 'auto')
7005 elseif ($widescreen)
7007 $height = round((intval($width)/16)*9);
7011 $height = round((intval($width)/4)*3);
7019 elseif ($mime == 'audio')
7024 // Set proper placeholder value
7025 if ($mime == 'audio')
7027 $placeholder = $audio;
7029 elseif ($mime == 'video')
7031 $placeholder = $video;
7036 // Make sure the JS library is included
7039 static $javascript_outputted = null;
7040 if (!$javascript_outputted && $this->javascript)
7042 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7043 $javascript_outputted = true;
7048 if ($handler == 'odeo')
7052 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.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=' . $this->get_link() . '"></embed>';
7056 $embed .= '<script type="text/javascript">/* <![CDATA[ */embed_odeo("' . $this->get_link() . '");/* ]]> */</script>';
7061 elseif ($handler == 'flash')
7065 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
7069 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7070 "embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');/* ]]> */</script>";
7074 // Flash Media Player file types.
7075 // Preferred handler for MP3 file types.
7076 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7081 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
7085 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7086 "embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');/* ]]> */</script>";
7090 // QuickTime 7 file types. Need to test with QuickTime 6.
7091 // Only handle MP3's if the Flash Media Player is not present.
7092 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7097 if ($placeholder != ""){
7098 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
7101 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
7106 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7107 "embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');/* ]]> */</script>";
7112 elseif ($handler == 'wmedia')
7117 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
7121 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7122 "embed_wmedia('$width', '$height', '" . $this->get_link() . "');/* ]]> */</script>";
7127 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7132 function get_real_type($find_handler = false)
7134 // If it's Odeo, let's get it out of the way.
7135 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7140 // Mime-types by handler.
7141 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7142 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7143 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
7144 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
7145 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7147 if ($this->get_type() !== null)
7149 $type = strtolower($this->type);
7156 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7157 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7159 switch (strtolower($this->get_extension()))
7164 $type = 'audio/acc';
7171 $type = 'audio/aiff';
7175 $type = 'audio/wav';
7182 $type = 'audio/midi';
7186 $type = 'audio/x-m4a';
7191 $type = 'audio/mp3';
7195 $type = 'audio/wav';
7199 $type = 'audio/x-ms-wax';
7203 $type = 'audio/x-ms-wma';
7209 $type = 'video/3gpp';
7214 $type = 'video/3gpp2';
7218 $type = 'video/x-ms-asf';
7222 $type = 'video/x-flv';
7236 $type = 'video/mpeg';
7240 $type = 'video/x-m4v';
7245 $type = 'video/quicktime';
7250 $type = 'video/mp4';
7254 $type = 'video/sd-video';
7258 $type = 'video/x-ms-wm';
7262 $type = 'video/x-ms-wmv';
7266 $type = 'video/x-ms-wvx';
7271 $type = 'application/futuresplash';
7275 $type = 'application/x-shockwave-flash';
7282 if (in_array($type, $types_flash))
7286 elseif (in_array($type, $types_fmedia))
7290 elseif (in_array($type, $types_quicktime))
7294 elseif (in_array($type, $types_wmedia))
7298 elseif (in_array($type, $types_mp3))
7314 class SimplePie_Caption
7322 // Constructor, used to input the data
7323 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7325 $this->type = $type;
7326 $this->lang = $lang;
7327 $this->startTime = $startTime;
7328 $this->endTime = $endTime;
7329 $this->text = $text;
7332 function __toString()
7334 // There is no $this->data here
7335 return md5(serialize($this));
7338 function get_endtime()
7340 if ($this->endTime !== null)
7342 return $this->endTime;
7350 function get_language()
7352 if ($this->lang !== null)
7362 function get_starttime()
7364 if ($this->startTime !== null)
7366 return $this->startTime;
7376 if ($this->text !== null)
7388 if ($this->type !== null)
7399 class SimplePie_Credit
7405 // Constructor, used to input the data
7406 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7408 $this->role = $role;
7409 $this->scheme = $scheme;
7410 $this->name = $name;
7413 function __toString()
7415 // There is no $this->data here
7416 return md5(serialize($this));
7421 if ($this->role !== null)
7431 function get_scheme()
7433 if ($this->scheme !== null)
7435 return $this->scheme;
7445 if ($this->name !== null)
7456 class SimplePie_Copyright
7461 // Constructor, used to input the data
7462 function SimplePie_Copyright($url = null, $label = null)
7465 $this->label = $label;
7468 function __toString()
7470 // There is no $this->data here
7471 return md5(serialize($this));
7476 if ($this->url !== null)
7486 function get_attribution()
7488 if ($this->label !== null)
7490 return $this->label;
7499 class SimplePie_Rating
7504 // Constructor, used to input the data
7505 function SimplePie_Rating($scheme = null, $value = null)
7507 $this->scheme = $scheme;
7508 $this->value = $value;
7511 function __toString()
7513 // There is no $this->data here
7514 return md5(serialize($this));
7517 function get_scheme()
7519 if ($this->scheme !== null)
7521 return $this->scheme;
7529 function get_value()
7531 if ($this->value !== null)
7533 return $this->value;
7542 class SimplePie_Restriction
7548 // Constructor, used to input the data
7549 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7551 $this->relationship = $relationship;
7552 $this->type = $type;
7553 $this->value = $value;
7556 function __toString()
7558 // There is no $this->data here
7559 return md5(serialize($this));
7562 function get_relationship()
7564 if ($this->relationship !== null)
7566 return $this->relationship;
7576 if ($this->type !== null)
7586 function get_value()
7588 if ($this->value !== null)
7590 return $this->value;
7600 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7602 class SimplePie_File
7606 var $success = true;
7607 var $headers = array();
7612 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7614 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $proxy = "")
7616 if (class_exists('idna_convert'))
7618 $idn = new idna_convert;
7619 $parsed = SimplePie_Misc::parse_url($url);
7620 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7623 $this->useragent = $useragent;
7624 if (preg_match('/^http(s)?:\/\//i', $url))
7626 if ($useragent === null)
7628 $useragent = ini_get('user_agent');
7629 $this->useragent = $useragent;
7631 if (!is_array($headers))
7635 if (!$force_fsockopen && function_exists('curl_exec'))
7637 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7639 $headers2 = array();
7640 foreach ($headers as $key => $value)
7642 $headers2[] = "$key: $value";
7644 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7646 curl_setopt($fp, CURLOPT_ENCODING, '');
7648 curl_setopt($fp, CURLOPT_URL, $url);
7649 curl_setopt($fp, CURLOPT_HEADER, 1);
7650 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7651 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7652 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7653 curl_setopt($fp, CURLOPT_REFERER, $url);
7654 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7655 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7656 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7658 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7659 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7663 curl_setopt($fp, CURLOPT_PROXY, $proxy);
7666 $this->headers = curl_exec($fp);
7667 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7669 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7670 $this->headers = curl_exec($fp);
7672 if (curl_errno($fp))
7674 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7675 $this->success = false;
7679 $info = curl_getinfo($fp);
7681 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7682 $this->headers = array_pop($this->headers);
7683 $parser = new SimplePie_HTTP_Parser($this->headers);
7684 if ($parser->parse())
7686 $this->headers = $parser->headers;
7687 $this->body = $parser->body;
7688 $this->status_code = $parser->status_code;
7689 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7692 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7693 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7700 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7701 $url_parts = parse_url($url);
7702 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7704 $url_parts['host'] = "ssl://$url_parts[host]";
7705 $url_parts['port'] = 443;
7707 if (!isset($url_parts['port']))
7709 $url_parts['port'] = 80;
7712 $proxy_parts = explode(':', $proxy);
7713 if (!isset($proxy_parts[1])) {
7714 $proxy_parts[1] = 80;
7716 $host = $proxy_parts[0];
7717 $port = $proxy_parts[1];
7719 $host = $url_parts['host'];
7720 $port = $url_parts['port'];
7722 $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
7725 $this->error = 'fsockopen error: ' . $errstr;
7726 $this->success = false;
7730 stream_set_timeout($fp, $timeout);
7734 if (isset($url_parts['path']))
7736 if (isset($url_parts['query']))
7738 $get = "$url_parts[path]?$url_parts[query]";
7742 $get = $url_parts['path'];
7750 $out = "GET $get HTTP/1.0\r\n";
7751 $out .= "Host: $url_parts[host]\r\n";
7752 $out .= "User-Agent: $useragent\r\n";
7753 if (extension_loaded('zlib'))
7755 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7758 if (isset($url_parts['user']) && isset($url_parts['pass']))
7760 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7762 foreach ($headers as $key => $value)
7764 $out .= "$key: $value\r\n";
7766 $out .= "Connection: Close\r\n\r\n";
7769 $info = stream_get_meta_data($fp);
7771 $this->headers = '';
7772 while (!$info['eof'] && !$info['timed_out'])
7774 $this->headers .= fread($fp, 1160);
7775 $info = stream_get_meta_data($fp);
7777 if (!$info['timed_out'])
7779 $parser = new SimplePie_HTTP_Parser($this->headers);
7780 if ($parser->parse())
7782 $this->headers = $parser->headers;
7783 $this->body = $parser->body;
7784 $this->status_code = $parser->status_code;
7785 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7788 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7789 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7791 if (isset($this->headers['content-encoding']))
7793 // Hey, we act dumb elsewhere, so let's do that here too
7794 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7798 $decoder = new SimplePie_gzdecode($this->body);
7799 if (!$decoder->parse())
7801 $this->error = 'Unable to decode HTTP "gzip" stream';
7802 $this->success = false;
7806 $this->body = $decoder->data;
7811 if (($body = gzuncompress($this->body)) === false)
7813 if (($body = gzinflate($this->body)) === false)
7815 $this->error = 'Unable to decode HTTP "deflate" stream';
7816 $this->success = false;
7819 $this->body = $body;
7823 $this->error = 'Unknown content coding';
7824 $this->success = false;
7831 $this->error = 'fsocket timed out';
7832 $this->success = false;
7840 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7841 if (!$this->body = file_get_contents($url))
7843 $this->error = 'file_get_contents could not read the file';
7844 $this->success = false;
7851 * HTTP Response Parser
7853 * @package SimplePie
7855 class SimplePie_HTTP_Parser
7863 var $http_version = 0.0;
7871 var $status_code = 0;
7882 * Key/value pairs of the headers
7887 var $headers = array();
7890 * Body of the response
7898 * Current state of the state machine
7903 var $state = 'http_version';
7914 * Input data length (to avoid calling strlen() everytime this is needed)
7919 var $data_length = 0;
7922 * Current position of the pointer
7930 * Name of the hedaer currently being parsed
7938 * Value of the hedaer currently being parsed
7946 * Create an instance of the class with the input data
7949 * @param string $data Input data
7951 function SimplePie_HTTP_Parser($data)
7953 $this->data = $data;
7954 $this->data_length = strlen($this->data);
7958 * Parse the input data
7961 * @return bool true on success, false on failure
7965 while ($this->state && $this->state !== 'emit' && $this->has_data())
7967 $state = $this->state;
7971 if ($this->state === 'emit' || $this->state === 'body')
7977 $this->http_version = '';
7978 $this->status_code = '';
7980 $this->headers = array();
7987 * Check whether there is data beyond the pointer
7990 * @return bool true if there is further data, false if not
7994 return (bool) ($this->position < $this->data_length);
7998 * See if the next character is LWS
8001 * @return bool true if the next character is LWS, false if not
8003 function is_linear_whitespace()
8005 return (bool) ($this->data[$this->position] === "\x09"
8006 || $this->data[$this->position] === "\x20"
8007 || ($this->data[$this->position] === "\x0A"
8008 && isset($this->data[$this->position + 1])
8009 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8013 * Parse the HTTP version
8017 function http_version()
8019 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8021 $len = strspn($this->data, '0123456789.', 5);
8022 $this->http_version = substr($this->data, 5, $len);
8023 $this->position += 5 + $len;
8024 if (substr_count($this->http_version, '.') <= 1)
8026 $this->http_version = (float) $this->http_version;
8027 $this->position += strspn($this->data, "\x09\x20", $this->position);
8028 $this->state = 'status';
8032 $this->state = false;
8037 $this->state = false;
8042 * Parse the status code
8048 if ($len = strspn($this->data, '0123456789', $this->position))
8050 $this->status_code = (int) substr($this->data, $this->position, $len);
8051 $this->position += $len;
8052 $this->state = 'reason';
8056 $this->state = false;
8061 * Parse the reason phrase
8067 $len = strcspn($this->data, "\x0A", $this->position);
8068 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8069 $this->position += $len + 1;
8070 $this->state = 'new_line';
8074 * Deal with a new line, shifting data around as needed
8080 $this->value = trim($this->value, "\x0D\x20");
8081 if ($this->name !== '' && $this->value !== '')
8083 $this->name = strtolower($this->name);
8084 if (isset($this->headers[$this->name]))
8086 $this->headers[$this->name] .= ', ' . $this->value;
8090 $this->headers[$this->name] = $this->value;
8095 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8097 $this->position += 2;
8098 $this->state = 'body';
8100 elseif ($this->data[$this->position] === "\x0A")
8103 $this->state = 'body';
8107 $this->state = 'name';
8112 * Parse a header name
8118 $len = strcspn($this->data, "\x0A:", $this->position);
8119 if (isset($this->data[$this->position + $len]))
8121 if ($this->data[$this->position + $len] === "\x0A")
8123 $this->position += $len;
8124 $this->state = 'new_line';
8128 $this->name = substr($this->data, $this->position, $len);
8129 $this->position += $len + 1;
8130 $this->state = 'value';
8135 $this->state = false;
8140 * Parse LWS, replacing consecutive LWS characters with a single space
8144 function linear_whitespace()
8148 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8150 $this->position += 2;
8152 elseif ($this->data[$this->position] === "\x0A")
8156 $this->position += strspn($this->data, "\x09\x20", $this->position);
8157 } while ($this->has_data() && $this->is_linear_whitespace());
8158 $this->value .= "\x20";
8162 * See what state to move to while within non-quoted header values
8168 if ($this->is_linear_whitespace())
8170 $this->linear_whitespace();
8174 switch ($this->data[$this->position])
8178 $this->state = 'quote';
8183 $this->state = 'new_line';
8187 $this->state = 'value_char';
8194 * Parse a header value while outside quotes
8198 function value_char()
8200 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8201 $this->value .= substr($this->data, $this->position, $len);
8202 $this->position += $len;
8203 $this->state = 'value';
8207 * See what state to move to while within quoted header values
8213 if ($this->is_linear_whitespace())
8215 $this->linear_whitespace();
8219 switch ($this->data[$this->position])
8223 $this->state = 'value';
8228 $this->state = 'new_line';
8233 $this->state = 'quote_escaped';
8237 $this->state = 'quote_char';
8244 * Parse a header value while within quotes
8248 function quote_char()
8250 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8251 $this->value .= substr($this->data, $this->position, $len);
8252 $this->position += $len;
8253 $this->state = 'value';
8257 * Parse an escaped character within quotes
8261 function quote_escaped()
8263 $this->value .= $this->data[$this->position];
8265 $this->state = 'quote';
8275 $this->body = substr($this->data, $this->position);
8276 $this->state = 'emit';
8283 * @package SimplePie
8285 class SimplePie_gzdecode
8291 * @see gzdecode::$data
8293 var $compressed_data;
8296 * Size of compressed data
8300 var $compressed_size;
8303 * Minimum size of a valid gzip string
8307 var $min_compressed_size = 18;
8310 * Current position of pointer
8327 * @see gzdecode::$compressed_data
8356 * @see gzdecode::$extra_field
8357 * @see gzdecode::$SI2
8365 * @see gzdecode::$extra_field
8366 * @see gzdecode::$SI1
8371 * Extra field content
8374 * @see gzdecode::$SI1
8375 * @see gzdecode::$SI2
8387 * Human readable comment
8394 * Don't allow anything to be set
8398 function __set($name, $value)
8400 trigger_error("Cannot write property $name", E_USER_ERROR);
8404 * Set the compressed string and related properties
8408 function SimplePie_gzdecode($data)
8410 $this->compressed_data = $data;
8411 $this->compressed_size = strlen($data);
8415 * Decode the GZIP stream
8421 if ($this->compressed_size >= $this->min_compressed_size)
8423 // Check ID1, ID2, and CM
8424 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8429 // Get the FLG (FLaGs)
8430 $this->flags = ord($this->compressed_data[3]);
8432 // FLG bits above (1 << 4) are reserved
8433 if ($this->flags > 0x1F)
8438 // Advance the pointer after the above
8439 $this->position += 4;
8442 $mtime = substr($this->compressed_data, $this->position, 4);
8443 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8444 if (current(unpack('S', "\x00\x01")) === 1)
8446 $mtime = strrev($mtime);
8448 $this->MTIME = current(unpack('l', $mtime));
8449 $this->position += 4;
8451 // Get the XFL (eXtra FLags)
8452 $this->XFL = ord($this->compressed_data[$this->position++]);
8454 // Get the OS (Operating System)
8455 $this->OS = ord($this->compressed_data[$this->position++]);
8458 if ($this->flags & 4)
8460 // Read subfield IDs
8461 $this->SI1 = $this->compressed_data[$this->position++];
8462 $this->SI2 = $this->compressed_data[$this->position++];
8464 // SI2 set to zero is reserved for future use
8465 if ($this->SI2 === "\x00")
8470 // Get the length of the extra field
8471 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8474 // Check the length of the string is still valid
8475 $this->min_compressed_size += $len + 4;
8476 if ($this->compressed_size >= $this->min_compressed_size)
8478 // Set the extra field to the given data
8479 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8480 $this->position += $len;
8489 if ($this->flags & 8)
8491 // Get the length of the filename
8492 $len = strspn($this->compressed_data, "\x00", $this->position);
8494 // Check the length of the string is still valid
8495 $this->min_compressed_size += $len + 1;
8496 if ($this->compressed_size >= $this->min_compressed_size)
8498 // Set the original filename to the given string
8499 $this->filename = substr($this->compressed_data, $this->position, $len);
8500 $this->position += $len + 1;
8508 // Parse the FCOMMENT
8509 if ($this->flags & 16)
8511 // Get the length of the comment
8512 $len = strspn($this->compressed_data, "\x00", $this->position);
8514 // Check the length of the string is still valid
8515 $this->min_compressed_size += $len + 1;
8516 if ($this->compressed_size >= $this->min_compressed_size)
8518 // Set the original comment to the given string
8519 $this->comment = substr($this->compressed_data, $this->position, $len);
8520 $this->position += $len + 1;
8529 if ($this->flags & 2)
8531 // Check the length of the string is still valid
8532 $this->min_compressed_size += $len + 2;
8533 if ($this->compressed_size >= $this->min_compressed_size)
8536 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8538 // Check the CRC matches
8539 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8541 $this->position += 2;
8554 // Decompress the actual data
8555 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8561 $this->position = $this->compressed_size - 8;
8564 // Check CRC of data
8565 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8566 $this->position += 4;
8567 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8572 // Check ISIZE of data
8573 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8574 $this->position += 4;
8575 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8580 // Wow, against all odds, we've actually got a valid gzip string
8590 class SimplePie_Cache
8593 * Don't call the constructor. Please.
8597 function SimplePie_Cache()
8599 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8603 * Create a new SimplePie_Cache object
8608 static function create($location, $filename, $extension)
8610 return new SimplePie_Cache_File($location, $filename, $extension);
8614 class SimplePie_Cache_File
8621 function SimplePie_Cache_File($location, $filename, $extension)
8623 $this->location = $location;
8624 $this->filename = rawurlencode($filename);
8625 $this->extension = rawurlencode($extension);
8626 $this->name = "$location/$this->filename.$this->extension";
8629 function save($data)
8631 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8633 if (is_a($data, 'SimplePie'))
8635 $data = $data->data;
8638 $data = serialize($data);
8640 if (function_exists('file_put_contents'))
8642 return (bool) file_put_contents($this->name, $data);
8646 $fp = fopen($this->name, 'wb');
8660 if (file_exists($this->name) && is_readable($this->name))
8662 return unserialize(file_get_contents($this->name));
8669 if (file_exists($this->name))
8671 return filemtime($this->name);
8678 if (file_exists($this->name))
8680 return touch($this->name);
8687 if (file_exists($this->name))
8689 return unlink($this->name);
8695 class SimplePie_Misc
8697 function time_hms($seconds)
8701 $hours = floor($seconds / 3600);
8702 $remainder = $seconds % 3600;
8705 $time .= $hours.':';
8708 $minutes = floor($remainder / 60);
8709 $seconds = $remainder % 60;
8710 if ($minutes < 10 && $hours > 0)
8712 $minutes = '0' . $minutes;
8716 $seconds = '0' . $seconds;
8719 $time .= $minutes.':';
8725 static function absolutize_url($relative, $base)
8727 if ($relative !== '')
8729 $relative = SimplePie_Misc::parse_url($relative);
8730 if ($relative['scheme'] !== '')
8732 $target = $relative;
8734 elseif ($base !== '')
8736 $base = SimplePie_Misc::parse_url($base);
8737 $target = SimplePie_Misc::parse_url('');
8738 if ($relative['authority'] !== '')
8740 $target = $relative;
8741 $target['scheme'] = $base['scheme'];
8745 $target['scheme'] = $base['scheme'];
8746 $target['authority'] = $base['authority'];
8747 if ($relative['path'] !== '')
8749 if (strpos($relative['path'], '/') === 0)
8751 $target['path'] = $relative['path'];
8753 elseif ($base['authority'] !== '' && $base['path'] === '')
8755 $target['path'] = '/' . $relative['path'];
8757 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8759 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8763 $target['path'] = $relative['path'];
8765 $target['query'] = $relative['query'];
8769 $target['path'] = $base['path'];
8770 if ($relative['query'] !== '')
8772 $target['query'] = $relative['query'];
8774 elseif ($base['query'] !== '')
8776 $target['query'] = $base['query'];
8780 $target['fragment'] = $relative['fragment'];
8784 // No base URL, just return the relative URL
8785 $target = $relative;
8787 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8793 $return = SimplePie_Misc::normalize_url($return);
8797 static function remove_dot_segments($input)
8800 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8802 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8803 if (strpos($input, '../') === 0)
8805 $input = substr($input, 3);
8807 elseif (strpos($input, './') === 0)
8809 $input = substr($input, 2);
8811 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
8812 elseif (strpos($input, '/./') === 0)
8814 $input = substr_replace($input, '/', 0, 3);
8816 elseif ($input == '/.')
8820 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
8821 elseif (strpos($input, '/../') === 0)
8823 $input = substr_replace($input, '/', 0, 4);
8824 $output = substr_replace($output, '', strrpos($output, '/'));
8826 elseif ($input == '/..')
8829 $output = substr_replace($output, '', strrpos($output, '/'));
8831 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8832 elseif ($input == '.' || $input == '..')
8836 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
8837 elseif (($pos = strpos($input, '/', 1)) !== false)
8839 $output .= substr($input, 0, $pos);
8840 $input = substr_replace($input, '', 0, $pos);
8848 return $output . $input;
8851 static function get_element($realname, $string)
8854 $name = preg_quote($realname, '/');
8855 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8857 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8859 $return[$i]['tag'] = $realname;
8860 $return[$i]['full'] = $matches[$i][0][0];
8861 $return[$i]['offset'] = $matches[$i][0][1];
8862 if (strlen($matches[$i][3][0]) <= 2)
8864 $return[$i]['self_closing'] = true;
8868 $return[$i]['self_closing'] = false;
8869 $return[$i]['content'] = $matches[$i][4][0];
8871 $return[$i]['attribs'] = array();
8872 if (isset($matches[$i][2][0]) && preg_match_all('/[\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]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
8874 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8876 if (count($attribs[$j]) == 2)
8878 $attribs[$j][2] = $attribs[$j][1];
8880 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8888 function element_implode($element)
8890 $full = "<$element[tag]";
8891 foreach ($element['attribs'] as $key => $value)
8893 $key = strtolower($key);
8894 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8896 if ($element['self_closing'])
8902 $full .= ">$element[content]</$element[tag]>";
8907 static function error($message, $level, $file, $line)
8912 $note = 'PHP Error';
8914 case E_USER_WARNING:
8915 $note = 'PHP Warning';
8918 $note = 'PHP Notice';
8921 $note = 'Unknown Error';
8924 error_log("$note: $message in $file on line $line", 0);
8929 * If a file has been cached, retrieve and display it.
8931 * This is most useful for caching images (get_favicon(), etc.),
8932 * however it works for all cached files. This WILL NOT display ANY
8933 * file/image/page/whatever, but rather only display what has already
8934 * been cached by SimplePie.
8937 * @see SimplePie::get_favicon()
8938 * @param str $identifier_url URL that is used to identify the content.
8939 * This may or may not be the actual URL of the live content.
8940 * @param str $cache_location Location of SimplePie's cache. Defaults
8942 * @param str $cache_extension The file extension that the file was
8943 * cached with. Defaults to 'spc'.
8944 * @param str $cache_class Name of the cache-handling class being used
8945 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8946 * as-is unless you've overloaded the class.
8947 * @param str $cache_name_function Obsolete. Exists for backwards
8948 * compatibility reasons only.
8950 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8952 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8954 if ($file = $cache->load())
8956 if (isset($file['headers']['content-type']))
8958 header('Content-type:' . $file['headers']['content-type']);
8962 header('Content-type: application/octet-stream');
8964 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8969 die('Cached file for ' . $identifier_url . ' cannot be found.');
8972 static function fix_protocol($url, $http = 1)
8974 $url = SimplePie_Misc::normalize_url($url);
8975 $parsed = SimplePie_Misc::parse_url($url);
8976 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8978 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8981 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8983 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8986 if ($http == 2 && $parsed['scheme'] !== '')
8990 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8992 return substr_replace($url, 'podcast', 0, 4);
8994 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8996 return substr_replace($url, 'itpc', 0, 4);
9004 static function parse_url($url)
9006 static $cache = array();
9007 if (isset($cache[$url]))
9009 return $cache[$url];
9011 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
9013 for ($i = count($match); $i <= 9; $i++)
9017 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
9021 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
9025 static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9030 $return .= "$scheme:";
9032 if ($authority !== '')
9034 $return .= "//$authority";
9042 $return .= "?$query";
9044 if ($fragment !== '')
9046 $return .= "#$fragment";
9051 static function normalize_url($url)
9053 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9054 $url = SimplePie_Misc::parse_url($url);
9055 $url['scheme'] = strtolower($url['scheme']);
9056 if ($url['authority'] !== '')
9058 $url['authority'] = strtolower($url['authority']);
9059 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9061 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9064 static function percent_encoding_normalization($match)
9066 $integer = hexdec($match[1]);
9067 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9069 return chr($integer);
9073 return strtoupper($match[0]);
9078 * Remove bad UTF-8 bytes
9080 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9081 * FAQ: Multilingual Forms (modified to include full ASCII range)
9083 * @author Geoffrey Sneddon
9084 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9085 * @param string $str String to remove bad UTF-8 bytes from
9086 * @return string UTF-8 string
9088 function utf8_bad_replace($str)
9090 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9094 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9098 elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
9100 return implode("\xEF\xBF\xBD", $matches[0]);
9102 elseif ($str !== '')
9104 return "\xEF\xBF\xBD";
9113 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9117 * @param string $string Windows-1252 encoded string
9118 * @return string UTF-8 encoded string
9120 static function windows_1252_to_utf8($string)
9122 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
9124 return strtr($string, $convert_table);
9127 static function change_encoding($data, $input, $output)
9129 $input = SimplePie_Misc::encoding($input);
9130 $output = SimplePie_Misc::encoding($output);
9132 // We fail to fail on non US-ASCII bytes
9133 if ($input === 'US-ASCII')
9135 static $non_ascii_octects = '';
9136 if (!$non_ascii_octects)
9138 for ($i = 0x80; $i <= 0xFF; $i++)
9140 $non_ascii_octects .= chr($i);
9143 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9146 // This is first, as behaviour of this is completely predictable
9147 if ($input === 'Windows-1252' && $output === 'UTF-8')
9149 return SimplePie_Misc::windows_1252_to_utf8($data);
9151 // This is second, as behaviour of this varies only with PHP version
9152 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9156 // This is last, as behaviour of this varies with OS userland and PHP version
9157 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9161 // If we can't do anything, just fail
9168 static function encoding($charset)
9170 /* Character sets are case-insensitive, and also need some further
9171 normalization in the real world (though we'll return them in the form given
9172 in their registration). */
9173 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9175 case 'adobestandardencoding':
9176 case 'csadobestandardencoding':
9177 return 'Adobe-Standard-Encoding';
9179 case 'adobesymbolencoding':
9181 return 'Adobe-Symbol-Encoding';
9187 return 'Amiga-1251';
9189 case 'ansix31101983':
9191 case 'csiso99naplps':
9194 return 'ANSI_X3.110-1983';
9198 case 'csiso89asmo449':
9209 return 'Big5-HKSCS';
9220 case 'csiso4unitedkingdom':
9228 case 'csiso47bsviewdata':
9230 return 'BS_viewdata';
9238 case 'csaz243419851':
9239 case 'csiso121canadian1':
9242 return 'CSA_Z243.4-1985-1';
9245 case 'csaz243419852':
9246 case 'csiso122canadian2':
9249 return 'CSA_Z243.4-1985-2';
9251 case 'csaz24341985gr':
9252 case 'csiso123csaz24341985gr':
9254 return 'CSA_Z243.4-1985-gr';
9256 case 'csiso139csn369103':
9259 return 'CSN_369103';
9266 case 'csiso21german':
9277 case 'csiso646danish':
9284 case 'csibmebcdicatde':
9286 return 'EBCDIC-AT-DE';
9288 case 'csebcdicatdea':
9290 return 'EBCDIC-AT-DE-A';
9292 case 'csebcdiccafr':
9294 return 'EBCDIC-CA-FR';
9296 case 'csebcdicdkno':
9298 return 'EBCDIC-DK-NO';
9300 case 'csebcdicdknoa':
9302 return 'EBCDIC-DK-NO-A';
9310 return 'EBCDIC-ES-A';
9314 return 'EBCDIC-ES-S';
9316 case 'csebcdicfise':
9318 return 'EBCDIC-FI-SE';
9320 case 'csebcdicfisea':
9322 return 'EBCDIC-FI-SE-A';
9344 case 'csiso111ecmacyrillic':
9345 case 'ecmacyrillic':
9348 return 'ECMA-cyrillic';
9350 case 'csiso17spanish':
9356 case 'csiso85spanish2':
9362 case 'cseucfixwidjapanese':
9363 case 'extendedunixcodefixedwidthforjapanese':
9364 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9366 case 'cseucpkdfmtjapanese':
9368 case 'extendedunixcodepackedformatforjapanese':
9369 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9381 case 'csiso58gb231280':
9387 case 'csiso57gb1988':
9391 return 'GB_1988-80';
9393 case 'csiso153gost1976874':
9397 return 'GOST_19768-74';
9400 case 'csiso150greekccitt':
9403 return 'greek-ccitt';
9405 case 'csiso88greek7':
9410 case 'csiso18greek7old':
9413 return 'greek7-old';
9417 return 'HP-DeskTop';
9429 return 'HP-Pi-font';
9438 return 'HZ-GB-2312';
9440 case 'csibmsymbols':
9442 return 'IBM-Symbols';
9451 case 'pcmultilingual850euro':
9456 case 'ebcdiclatin9euro':
9462 case 'ebcdicus37euro':
9468 case 'ebcdicde273euro':
9474 case 'ebcdicdk277euro':
9475 case 'ebcdicno277euro':
9481 case 'ebcdicfi278euro':
9482 case 'ebcdicse278euro':
9488 case 'ebcdicit280euro':
9494 case 'ebcdices284euro':
9500 case 'ebcdicgb285euro':
9506 case 'ebcdicfr297euro':
9512 case 'ebcdicinternational500euro':
9518 case 'ebcdicis871euro':
9593 case 'ebcdicjpkana':
9623 case 'cspc8codepage437':
9635 case 'cspc775baltic':
9641 case 'cspc850multilingual':
9684 case 'cspc862latinhebrew':
9726 case 'ebcdiccproece':
9739 case 'ebcdiccyrillic':
9780 case 'csiso143iecp271':
9790 case 'csiso50inis8':
9795 case 'csiso51iniscyrillic':
9796 case 'iniscyrillic':
9798 return 'INIS-cyrillic';
9805 return 'ISO-2022-CN';
9807 case 'iso2022cnext':
9808 return 'ISO-2022-CN-EXT';
9812 return 'ISO-2022-JP';
9814 case 'csiso2022jp2':
9816 return 'ISO-2022-JP-2';
9820 return 'ISO-2022-KR';
9822 case 'cswindows30latin1':
9823 case 'iso88591windows30latin1':
9824 return 'ISO-8859-1-Windows-3.0-Latin-1';
9826 case 'cswindows31latin1':
9827 case 'iso88591windows31latin1':
9828 return 'ISO-8859-1-Windows-3.1-Latin-1';
9834 case 'iso885921987':
9837 return 'ISO-8859-2';
9839 case 'cswindows31latin2':
9840 case 'iso88592windowslatin2':
9841 return 'ISO-8859-2-Windows-Latin-2';
9847 case 'iso885931988':
9850 return 'ISO-8859-3';
9856 case 'iso885941988':
9859 return 'ISO-8859-4';
9861 case 'csisolatincyrillic':
9866 case 'iso885951988':
9867 return 'ISO-8859-5';
9871 case 'csisolatinarabic':
9876 case 'iso885961987':
9877 return 'ISO-8859-6';
9882 return 'ISO-8859-6-E';
9887 return 'ISO-8859-6-I';
9889 case 'csisolatingreek':
9897 case 'iso885971987':
9898 return 'ISO-8859-7';
9900 case 'csisolatinhebrew':
9905 case 'iso885981988':
9906 return 'ISO-8859-8';
9911 return 'ISO-8859-8-E';
9916 return 'ISO-8859-8-I';
9918 case 'cswindows31latin5':
9919 case 'iso88599windowslatin5':
9920 return 'ISO-8859-9-Windows-Latin-5';
9925 case 'iso8859101992':
9928 return 'ISO-8859-10';
9931 return 'ISO-8859-13';
9937 case 'iso8859141998':
9940 return 'ISO-8859-14';
9945 return 'ISO-8859-15';
9950 case 'iso8859162001':
9953 return 'ISO-8859-16';
9956 return 'ISO-10646-J-1';
9959 case 'iso10646ucs2':
9960 return 'ISO-10646-UCS-2';
9963 case 'iso10646ucs4':
9964 return 'ISO-10646-UCS-4';
9966 case 'csunicodeascii':
9967 case 'iso10646ucsbasic':
9968 return 'ISO-10646-UCS-Basic';
9970 case 'csunicodelatin1':
9972 case 'iso10646unicodelatin1':
9973 return 'ISO-10646-Unicode-Latin1';
9975 case 'csiso10646utf1':
9976 case 'iso10646utf1':
9977 return 'ISO-10646-UTF-1';
9983 return 'ISO-11548-1';
9989 case 'csunicodeibm1261':
9990 case 'isounicodeibm1261':
9991 return 'ISO-Unicode-IBM-1261';
9993 case 'csunicodeibm1264':
9994 case 'isounicodeibm1264':
9995 return 'ISO-Unicode-IBM-1264';
9997 case 'csunicodeibm1265':
9998 case 'isounicodeibm1265':
9999 return 'ISO-Unicode-IBM-1265';
10001 case 'csunicodeibm1268':
10002 case 'isounicodeibm1268':
10003 return 'ISO-Unicode-IBM-1268';
10005 case 'csunicodeibm1276':
10006 case 'isounicodeibm1276':
10007 return 'ISO-Unicode-IBM-1276';
10009 case 'csiso646basic1983':
10010 case 'iso646basic1983':
10012 return 'ISO_646.basic:1983';
10014 case 'csiso2intlrefversion':
10017 case 'iso646irv1983':
10018 return 'ISO_646.irv:1983';
10023 case 'iso20331983':
10024 return 'ISO_2033-1983';
10026 case 'csiso5427cyrillic':
10032 case 'iso5427cyrillic1981':
10033 case 'iso54271981':
10034 return 'ISO_5427:1981';
10036 case 'csiso5428greek':
10038 case 'iso54281980':
10039 return 'ISO_5428:1980';
10041 case 'csiso6937add':
10044 return 'ISO_6937-2-25';
10046 case 'csisotextcomm':
10048 case 'iso69372add':
10049 return 'ISO_6937-2-add';
10051 case 'csiso8859supp':
10053 case 'iso8859supp':
10055 return 'ISO_8859-supp';
10057 case 'csiso10367box':
10059 case 'iso10367box':
10060 return 'ISO_10367-box';
10062 case 'csiso15italian':
10068 case 'csiso13jisc6220jp':
10070 case 'jisc62201969':
10071 case 'jisc62201969jp':
10074 return 'JIS_C6220-1969-jp';
10076 case 'csiso14jisc6220ro':
10079 case 'jisc62201969ro':
10081 return 'JIS_C6220-1969-ro';
10083 case 'csiso42jisc62261978':
10085 case 'jisc62261978':
10086 return 'JIS_C6226-1978';
10088 case 'csiso87jisx0208':
10090 case 'jisc62261983':
10091 case 'jisx02081983':
10093 return 'JIS_C6226-1983';
10095 case 'csiso91jisc62291984a':
10097 case 'jisc62291984a':
10099 return 'JIS_C6229-1984-a';
10101 case 'csiso92jisc62991984b':
10103 case 'iso646jpocrb':
10104 case 'jisc62291984b':
10106 return 'JIS_C6229-1984-b';
10108 case 'csiso93jis62291984badd':
10110 case 'jisc62291984badd':
10112 return 'JIS_C6229-1984-b-add';
10114 case 'csiso94jis62291984hand':
10116 case 'jisc62291984hand':
10118 return 'JIS_C6229-1984-hand';
10120 case 'csiso95jis62291984handadd':
10122 case 'jisc62291984handadd':
10123 case 'jpocrhandadd':
10124 return 'JIS_C6229-1984-hand-add';
10126 case 'csiso96jisc62291984kana':
10128 case 'jisc62291984kana':
10129 return 'JIS_C6229-1984-kana';
10131 case 'csjisencoding':
10132 case 'jisencoding':
10133 return 'JIS_Encoding';
10135 case 'cshalfwidthkatakana':
10138 return 'JIS_X0201';
10140 case 'csiso159jisx02121990':
10142 case 'jisx02121990':
10144 return 'JIS_X0212-1990';
10146 case 'csiso141jusib1002':
10152 return 'JUS_I.B1.002';
10154 case 'csiso147macedonian':
10156 case 'jusib1003mac':
10158 return 'JUS_I.B1.003-mac';
10160 case 'csiso146serbian':
10162 case 'jusib1003serb':
10164 return 'JUS_I.B1.003-serb';
10166 case 'koi7switched':
10167 return 'KOI7-switched';
10184 case 'strk10482002':
10187 case 'csiso19latingreek':
10190 return 'latin-greek';
10192 case 'csiso27latingreek1':
10194 case 'latingreek1':
10195 return 'Latin-greek-1';
10197 case 'csiso158lap':
10201 return 'latin-lap';
10203 case 'csmacintosh':
10206 return 'macintosh';
10208 case 'csmicrosoftpublishing':
10209 case 'microsoftpublishing':
10210 return 'Microsoft-Publishing';
10220 case 'csiso86hungarian':
10225 return 'MSZ_7795.3';
10230 return 'NATS-DANO';
10232 case 'csnatsdanoadd':
10234 case 'natsdanoadd':
10235 return 'NATS-DANO-ADD';
10240 return 'NATS-SEFI';
10242 case 'csnatssefiadd':
10244 case 'natssefiadd':
10245 return 'NATS-SEFI-ADD';
10247 case 'csiso151cuba':
10252 return 'NC_NC00-10:81';
10254 case 'csiso69french':
10259 return 'NF_Z_62-010';
10261 case 'csiso25french':
10264 case 'nfz620101973':
10265 return 'NF_Z_62-010_(1973)';
10267 case 'csiso60danishnorwegian':
10268 case 'csiso60norwegian1':
10273 return 'NS_4551-1';
10275 case 'csiso61norwegian2':
10280 return 'NS_4551-2';
10282 case 'osdebcdicdf03irv':
10283 return 'OSD_EBCDIC_DF03_IRV';
10285 case 'osdebcdicdf041':
10286 return 'OSD_EBCDIC_DF04_1';
10288 case 'osdebcdicdf0415':
10289 return 'OSD_EBCDIC_DF04_15';
10291 case 'cspc8danishnorwegian':
10292 case 'pc8danishnorwegian':
10293 return 'PC8-Danish-Norwegian';
10295 case 'cspc8turkish':
10297 return 'PC8-Turkish';
10299 case 'csiso16portuguese':
10305 case 'csiso84portuguese2':
10313 case 'cyrillicasian':
10321 case 'csiso10swedish':
10328 return 'SEN_850200_B';
10330 case 'csiso11swedishfornames':
10335 return 'SEN_850200_C';
10340 return 'Shift_JIS';
10342 case 'csiso102t617bit':
10345 return 'T.61-7bit';
10347 case 'csiso103t618bit':
10351 return 'T.61-8bit';
10353 case 'csiso128t101g2':
10362 case 'csunicode11':
10364 return 'UNICODE-1-1';
10366 case 'csunicode11utf7':
10367 case 'unicode11utf7':
10368 return 'UNICODE-1-1-UTF-7';
10370 case 'csunknown8bit':
10371 case 'unknown8bit':
10372 return 'UNKNOWN-8BIT';
10374 case 'ansix341968':
10375 case 'ansix341986':
10382 case 'iso646irv1991':
10415 case 'csventurainternational':
10416 case 'venturainternational':
10417 return 'Ventura-International';
10419 case 'csventuramath':
10420 case 'venturamath':
10421 return 'Ventura-Math';
10423 case 'csventuraus':
10425 return 'Ventura-US';
10427 case 'csiso70videotexsupp1':
10429 case 'videotexsuppl':
10430 return 'videotex-suppl';
10440 case 'cswindows31j':
10442 return 'Windows-31J';
10446 return 'Windows-874';
10451 case 'csksc56011987':
10455 case 'ksc56011987':
10456 case 'ksc56011989':
10457 return 'Windows-949';
10459 case 'windows1250':
10460 return 'windows-1250';
10462 case 'windows1251':
10463 return 'windows-1251';
10466 case 'csisolatin1':
10470 case 'iso885911987':
10473 case 'windows1252':
10474 return 'Windows-1252';
10476 case 'windows1252':
10477 return 'windows-1252';
10479 case 'windows1253':
10480 return 'windows-1253';
10482 case 'csisolatin5':
10485 case 'iso885991989':
10488 case 'windows1254':
10489 return 'Windows-1254';
10491 case 'windows1254':
10492 return 'windows-1254';
10494 case 'windows1255':
10495 return 'windows-1255';
10497 case 'windows1256':
10498 return 'windows-1256';
10500 case 'windows1257':
10501 return 'windows-1257';
10503 case 'windows1258':
10504 return 'windows-1258';
10511 function get_curl_version()
10513 if (is_array($curl = curl_version()))
10515 $curl = $curl['version'];
10517 elseif (substr($curl, 0, 5) == 'curl/')
10519 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10521 elseif (substr($curl, 0, 8) == 'libcurl/')
10523 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10532 function is_subclass_of($class1, $class2)
10534 if (func_num_args() != 2)
10536 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10538 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10540 return is_subclass_of($class1, $class2);
10542 elseif (is_string($class1) && is_string($class2))
10544 if (class_exists($class1))
10546 if (class_exists($class2))
10548 $class2 = strtolower($class2);
10549 while ($class1 = strtolower(get_parent_class($class1)))
10551 if ($class1 == $class2)
10560 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10567 * Strip HTML comments
10570 * @param string $data Data to strip comments from
10571 * @return string Comment stripped string
10573 function strip_comments($data)
10576 while (($start = strpos($data, '<!--')) !== false)
10578 $output .= substr($data, 0, $start);
10579 if (($end = strpos($data, '-->', $start)) !== false)
10581 $data = substr_replace($data, '', 0, $end + 3);
10588 return $output . $data;
10591 function parse_date($dt)
10593 $parser = SimplePie_Parse_Date::get();
10594 return $parser->parse($dt);
10598 * Decode HTML entities
10602 * @param string $data Input data
10603 * @return string Output data
10605 function entities_decode($data)
10607 $decoder = new SimplePie_Decode_HTML_Entities($data);
10608 return $decoder->parse();
10612 * Remove RFC822 comments
10615 * @param string $data Data to strip comments from
10616 * @return string Comment stripped string
10618 function uncomment_rfc822($string)
10620 $string = (string) $string;
10622 $length = strlen($string);
10627 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10629 $output .= substr($string, $position, $pos - $position);
10630 $position = $pos + 1;
10631 if ($string[$pos - 1] !== '\\')
10634 while ($depth && $position < $length)
10636 $position += strcspn($string, '()', $position);
10637 if ($string[$position - 1] === '\\')
10642 elseif (isset($string[$position]))
10644 switch ($string[$position])
10667 $output .= substr($string, $position);
10672 function parse_mime($mime)
10674 if (($pos = strpos($mime, ';')) === false)
10676 return trim($mime);
10680 return trim(substr($mime, 0, $pos));
10684 function htmlspecialchars_decode($string, $quote_style)
10686 if (function_exists('htmlspecialchars_decode'))
10688 return htmlspecialchars_decode($string, $quote_style);
10692 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10696 function atom_03_construct_type($attribs)
10698 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10700 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10704 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10706 if (isset($attribs['']['type']))
10708 switch (strtolower(trim($attribs['']['type'])))
10712 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10716 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10719 case 'application/xhtml+xml':
10720 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10723 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10728 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10732 static function atom_10_construct_type($attribs)
10734 if (isset($attribs['']['type']))
10736 switch (strtolower(trim($attribs['']['type'])))
10739 return SIMPLEPIE_CONSTRUCT_TEXT;
10742 return SIMPLEPIE_CONSTRUCT_HTML;
10745 return SIMPLEPIE_CONSTRUCT_XHTML;
10748 return SIMPLEPIE_CONSTRUCT_NONE;
10751 return SIMPLEPIE_CONSTRUCT_TEXT;
10754 function atom_10_content_construct_type($attribs)
10756 if (isset($attribs['']['type']))
10758 $type = strtolower(trim($attribs['']['type']));
10762 return SIMPLEPIE_CONSTRUCT_TEXT;
10765 return SIMPLEPIE_CONSTRUCT_HTML;
10768 return SIMPLEPIE_CONSTRUCT_XHTML;
10770 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10772 return SIMPLEPIE_CONSTRUCT_NONE;
10776 return SIMPLEPIE_CONSTRUCT_BASE64;
10781 return SIMPLEPIE_CONSTRUCT_TEXT;
10785 static function is_isegment_nz_nc($string)
10787 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
10790 function space_seperated_tokens($string)
10792 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10793 $string_length = strlen($string);
10795 $position = strspn($string, $space_characters);
10798 while ($position < $string_length)
10800 $len = strcspn($string, $space_characters, $position);
10801 $tokens[] = substr($string, $position, $len);
10803 $position += strspn($string, $space_characters, $position);
10809 function array_unique($array)
10811 if (version_compare(PHP_VERSION, '5.2', '>='))
10813 return array_unique($array);
10817 $array = (array) $array;
10818 $new_array = array();
10819 $new_array_strings = array();
10820 foreach ($array as $key => $value)
10822 if (is_object($value))
10824 if (method_exists($value, '__toString'))
10826 $cmp = $value->__toString();
10830 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10833 elseif (is_array($value))
10835 $cmp = (string) reset($value);
10839 $cmp = (string) $value;
10841 if (!in_array($cmp, $new_array_strings))
10843 $new_array[$key] = $value;
10844 $new_array_strings[] = $cmp;
10852 * Converts a unicode codepoint to a UTF-8 character
10856 * @param int $codepoint Unicode codepoint
10857 * @return string UTF-8 character
10859 function codepoint_to_utf8($codepoint)
10861 static $cache = array();
10862 $codepoint = (int) $codepoint;
10863 if (isset($cache[$codepoint]))
10865 return $cache[$codepoint];
10867 elseif ($codepoint < 0)
10869 return $cache[$codepoint] = false;
10871 else if ($codepoint <= 0x7f)
10873 return $cache[$codepoint] = chr($codepoint);
10875 else if ($codepoint <= 0x7ff)
10877 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10879 else if ($codepoint <= 0xffff)
10881 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10883 else if ($codepoint <= 0x10ffff)
10885 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10889 // U+FFFD REPLACEMENT CHARACTER
10890 return $cache[$codepoint] = "\xEF\xBF\xBD";
10895 * Re-implementation of PHP 5's stripos()
10897 * Returns the numeric position of the first occurrence of needle in the
10902 * @param object $haystack
10903 * @param string $needle Note that the needle may be a string of one or more
10904 * characters. If needle is not a string, it is converted to an integer
10905 * and applied as the ordinal value of a character.
10906 * @param int $offset The optional offset parameter allows you to specify which
10907 * character in haystack to start searching. The position returned is still
10908 * relative to the beginning of haystack.
10909 * @return bool If needle is not found, stripos() will return boolean false.
10911 function stripos($haystack, $needle, $offset = 0)
10913 if (function_exists('stripos'))
10915 return stripos($haystack, $needle, $offset);
10919 if (is_string($needle))
10921 $needle = strtolower($needle);
10923 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10925 $needle = strtolower(chr($needle));
10929 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10933 return strpos(strtolower($haystack), $needle, $offset);
10938 * Similar to parse_str()
10940 * Returns an associative array of name/value pairs, where the value is an
10941 * array of values that have used the same name
10945 * @param string $str The input string.
10948 function parse_str($str)
10951 $str = explode('&', $str);
10953 foreach ($str as $section)
10955 if (strpos($section, '=') !== false)
10957 list($name, $value) = explode('=', $section, 2);
10958 $return[urldecode($name)][] = urldecode($value);
10962 $return[urldecode($section)][] = null;
10970 * Detect XML encoding, as per XML 1.0 Appendix F.1
10972 * @todo Add support for EBCDIC
10973 * @param string $data XML data
10974 * @return array Possible encodings
10976 static function xml_encoding($data)
10978 // UTF-32 Big Endian BOM
10979 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10981 $encoding[] = 'UTF-32BE';
10983 // UTF-32 Little Endian BOM
10984 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10986 $encoding[] = 'UTF-32LE';
10988 // UTF-16 Big Endian BOM
10989 elseif (substr($data, 0, 2) === "\xFE\xFF")
10991 $encoding[] = 'UTF-16BE';
10993 // UTF-16 Little Endian BOM
10994 elseif (substr($data, 0, 2) === "\xFF\xFE")
10996 $encoding[] = 'UTF-16LE';
10999 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11001 $encoding[] = 'UTF-8';
11003 // UTF-32 Big Endian Without BOM
11004 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
11006 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11008 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11009 if ($parser->parse())
11011 $encoding[] = $parser->encoding;
11014 $encoding[] = 'UTF-32BE';
11016 // UTF-32 Little Endian Without BOM
11017 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
11019 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11021 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11022 if ($parser->parse())
11024 $encoding[] = $parser->encoding;
11027 $encoding[] = 'UTF-32LE';
11029 // UTF-16 Big Endian Without BOM
11030 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11032 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11034 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11035 if ($parser->parse())
11037 $encoding[] = $parser->encoding;
11040 $encoding[] = 'UTF-16BE';
11042 // UTF-16 Little Endian Without BOM
11043 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11045 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11047 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11048 if ($parser->parse())
11050 $encoding[] = $parser->encoding;
11053 $encoding[] = 'UTF-16LE';
11055 // US-ASCII (or superset)
11056 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11058 if ($pos = strpos($data, "\x3F\x3E"))
11060 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11061 if ($parser->parse())
11063 $encoding[] = $parser->encoding;
11066 $encoding[] = 'UTF-8';
11068 // Fallback to UTF-8
11071 $encoding[] = 'UTF-8';
11078 * Decode HTML Entities
11080 * This implements HTML5 as of revision 967 (2007-06-28)
11082 * @package SimplePie
11084 class SimplePie_Decode_HTML_Entities
11087 * Data to be parsed
11095 * Currently consumed bytes
11100 var $consumed = '';
11103 * Position of the current byte being parsed
11111 * Create an instance of the class with the input data
11114 * @param string $data Input data
11116 function SimplePie_Decode_HTML_Entities($data)
11118 $this->data = $data;
11122 * Parse the input data
11125 * @return string Output data
11129 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11133 $this->consumed = '';
11135 return $this->data;
11139 * Consume the next byte
11142 * @return mixed The next byte, or false, if there is no more data
11146 if (isset($this->data[$this->position]))
11148 $this->consumed .= $this->data[$this->position];
11149 return $this->data[$this->position++];
11153 $this->consumed = false;
11159 * Consume a range of characters
11162 * @param string $chars Characters to consume
11163 * @return mixed A series of characters that match the range, or false
11165 function consume_range($chars)
11167 if ($len = strspn($this->data, $chars, $this->position))
11169 $data = substr($this->data, $this->position, $len);
11170 $this->consumed .= $data;
11171 $this->position += $len;
11176 $this->consumed = false;
11182 * Unconsume one byte
11186 function unconsume()
11188 $this->consumed = substr($this->consumed, 0, -1);
11199 switch ($this->consume())
11213 switch ($this->consume())
11217 $range = '0123456789ABCDEFabcdef';
11222 $range = '0123456789';
11224 $this->unconsume();
11228 if ($codepoint = $this->consume_range($range))
11230 static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
11234 $codepoint = hexdec($codepoint);
11238 $codepoint = intval($codepoint);
11241 if (isset($windows_1252_specials[$codepoint]))
11243 $replacement = $windows_1252_specials[$codepoint];
11247 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11250 if ($this->consume() != ';')
11252 $this->unconsume();
11255 $consumed_length = strlen($this->consumed);
11256 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11257 $this->position += strlen($replacement) - $consumed_length;
11262 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
11264 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11266 $consumed = substr($this->consumed, 1);
11267 if (isset($entities[$consumed]))
11269 $match = $consumed;
11273 if ($match !== null)
11275 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11276 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11286 * @package SimplePie
11288 class SimplePie_Parse_Date
11293 * @access protected
11299 * List of days, calendar day name => ordinal day number in the week
11301 * @access protected
11364 'keskiviikko' => 3,
11388 * List of months, calendar month name => calendar month number
11390 * @access protected
11393 var $month = array(
11404 // No long form of May
11533 * List of timezones, abbreviation => offset from UTC
11535 * @access protected
11538 var $timezone = array(
11741 * Cached PCRE for SimplePie_Parse_Date::$day
11743 * @access protected
11749 * Cached PCRE for SimplePie_Parse_Date::$month
11751 * @access protected
11757 * Array of user-added callback methods
11762 var $built_in = array();
11765 * Array of user-added callback methods
11770 var $user = array();
11773 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11774 * self::month_pcre, and self::built_in
11778 function SimplePie_Parse_Date()
11780 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11781 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11784 if (!isset($cache[get_class($this)]))
11786 if (extension_loaded('Reflection'))
11788 $class = new ReflectionClass(get_class($this));
11789 $methods = $class->getMethods();
11790 $all_methods = array();
11791 foreach ($methods as $method)
11793 $all_methods[] = $method->getName();
11798 $all_methods = get_class_methods($this);
11801 foreach ($all_methods as $method)
11803 if (strtolower(substr($method, 0, 5)) === 'date_')
11805 $cache[get_class($this)][] = $method;
11810 foreach ($cache[get_class($this)] as $method)
11812 $this->built_in[] = $method;
11821 static function get()
11826 $object = new SimplePie_Parse_Date;
11836 * @param string $date Date to parse
11837 * @return int Timestamp corresponding to date string, or false on failure
11839 function parse($date)
11841 foreach ($this->user as $method)
11843 if (($returned = call_user_func($method, $date)) !== false)
11849 foreach ($this->built_in as $method)
11851 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11861 * Add a callback method to parse a date
11865 * @param callback $callback
11867 function add_callback($callback)
11869 if (is_callable($callback))
11871 $this->user[] = $callback;
11875 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11880 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11881 * well as allowing any of upper or lower case "T", horizontal tabs, or
11882 * spaces to be used as the time seperator (including more than one))
11884 * @access protected
11885 * @return int Timestamp
11887 function date_w3cdtf($date)
11892 $year = '([0-9]{4})';
11893 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11894 $decimal = '([0-9]*)';
11895 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11896 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11898 if (preg_match($pcre, $date, $match))
11901 Capturing subpatterns:
11908 7: Decimal fraction of a second
11912 11: Timezone minutes
11915 // Fill in empty matches
11916 for ($i = count($match); $i <= 3; $i++)
11921 for ($i = count($match); $i <= 7; $i++)
11926 // Numeric timezone
11927 if (isset($match[9]) && $match[9] !== '')
11929 $timezone = $match[10] * 3600;
11930 $timezone += $match[11] * 60;
11931 if ($match[9] === '-')
11933 $timezone = 0 - $timezone;
11941 // Convert the number of seconds to an integer, taking decimals into account
11942 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11944 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11953 * Remove RFC822 comments
11955 * @access protected
11956 * @param string $data Data to strip comments from
11957 * @return string Comment stripped string
11959 function remove_rfc2822_comments($string)
11961 $string = (string) $string;
11963 $length = strlen($string);
11968 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11970 $output .= substr($string, $position, $pos - $position);
11971 $position = $pos + 1;
11972 if ($string[$pos - 1] !== '\\')
11975 while ($depth && $position < $length)
11977 $position += strcspn($string, '()', $position);
11978 if ($string[$position - 1] === '\\')
11983 elseif (isset($string[$position]))
11985 switch ($string[$position])
12008 $output .= substr($string, $position);
12014 * Parse RFC2822's date format
12016 * @access protected
12017 * @return int Timestamp
12019 function date_rfc2822($date)
12024 $wsp = '[\x09\x20]';
12025 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
12026 $optional_fws = $fws . '?';
12027 $day_name = $this->day_pcre;
12028 $month = $this->month_pcre;
12029 $day = '([0-9]{1,2})';
12030 $hour = $minute = $second = '([0-9]{2})';
12031 $year = '([0-9]{2,4})';
12032 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
12033 $character_zone = '([A-Z]{1,5})';
12034 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
12035 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
12037 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
12040 Capturing subpatterns:
12050 10: Timezone minutes
12051 11: Alphabetic timezone
12054 // Find the month number
12055 $month = $this->month[strtolower($match[3])];
12057 // Numeric timezone
12058 if ($match[8] !== '')
12060 $timezone = $match[9] * 3600;
12061 $timezone += $match[10] * 60;
12062 if ($match[8] === '-')
12064 $timezone = 0 - $timezone;
12067 // Character timezone
12068 elseif (isset($this->timezone[strtoupper($match[11])]))
12070 $timezone = $this->timezone[strtoupper($match[11])];
12072 // Assume everything else to be -0000
12078 // Deal with 2/3 digit years
12079 if ($match[4] < 50)
12083 elseif ($match[4] < 1000)
12088 // Second is optional, if it is empty set it to zero
12089 if ($match[7] !== '')
12091 $second = $match[7];
12098 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12107 * Parse RFC850's date format
12109 * @access protected
12110 * @return int Timestamp
12112 function date_rfc850($date)
12117 $space = '[\x09\x20]+';
12118 $day_name = $this->day_pcre;
12119 $month = $this->month_pcre;
12120 $day = '([0-9]{1,2})';
12121 $year = $hour = $minute = $second = '([0-9]{2})';
12122 $zone = '([A-Z]{1,5})';
12123 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12125 if (preg_match($pcre, $date, $match))
12128 Capturing subpatterns:
12140 $month = $this->month[strtolower($match[3])];
12142 // Character timezone
12143 if (isset($this->timezone[strtoupper($match[8])]))
12145 $timezone = $this->timezone[strtoupper($match[8])];
12147 // Assume everything else to be -0000
12153 // Deal with 2 digit year
12154 if ($match[4] < 50)
12163 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12172 * Parse C99's asctime()'s date format
12174 * @access protected
12175 * @return int Timestamp
12177 function date_asctime($date)
12182 $space = '[\x09\x20]+';
12183 $wday_name = $this->day_pcre;
12184 $mon_name = $this->month_pcre;
12185 $day = '([0-9]{1,2})';
12186 $hour = $sec = $min = '([0-9]{2})';
12187 $year = '([0-9]{4})';
12188 $terminator = '\x0A?\x00?';
12189 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12191 if (preg_match($pcre, $date, $match))
12194 Capturing subpatterns:
12204 $month = $this->month[strtolower($match[2])];
12205 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12214 * Parse dates using strtotime()
12216 * @access protected
12217 * @return int Timestamp
12219 function date_strtotime($date)
12221 $strtotime = strtotime($date);
12222 if ($strtotime === -1 || $strtotime === false)
12234 * Content-type sniffing
12236 * @package SimplePie
12238 class SimplePie_Content_Type_Sniffer
12243 * @var SimplePie_File
12249 * Create an instance of the class with the input file
12252 * @param SimplePie_Content_Type_Sniffer $file Input file
12254 function SimplePie_Content_Type_Sniffer($file)
12256 $this->file = $file;
12260 * Get the Content-Type of the specified file
12263 * @return string Actual Content-Type
12265 function get_type()
12267 if (isset($this->file->headers['content-type']))
12269 if (!isset($this->file->headers['content-encoding'])
12270 && ($this->file->headers['content-type'] === 'text/plain'
12271 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12272 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12274 return $this->text_or_binary();
12277 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12279 $official = substr($this->file->headers['content-type'], 0, $pos);
12283 $official = $this->file->headers['content-type'];
12285 $official = strtolower($official);
12287 if ($official === 'unknown/unknown'
12288 || $official === 'application/unknown')
12290 return $this->unknown();
12292 elseif (substr($official, -4) === '+xml'
12293 || $official === 'text/xml'
12294 || $official === 'application/xml')
12298 elseif (substr($official, 0, 6) === 'image/')
12300 if ($return = $this->image())
12309 elseif ($official === 'text/html')
12311 return $this->feed_or_html();
12320 return $this->unknown();
12325 * Sniff text or binary
12328 * @return string Actual Content-Type
12330 function text_or_binary()
12332 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12333 || substr($this->file->body, 0, 2) === "\xFF\xFE"
12334 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12335 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12337 return 'text/plain';
12339 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12341 return 'application/octect-stream';
12345 return 'text/plain';
12353 * @return string Actual Content-Type
12357 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12358 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12359 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12360 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12362 return 'text/html';
12364 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12366 return 'application/pdf';
12368 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12370 return 'application/postscript';
12372 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12373 || substr($this->file->body, 0, 6) === 'GIF89a')
12375 return 'image/gif';
12377 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12379 return 'image/png';
12381 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12383 return 'image/jpeg';
12385 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12387 return 'image/bmp';
12391 return $this->text_or_binary();
12399 * @return string Actual Content-Type
12403 if (substr($this->file->body, 0, 6) === 'GIF87a'
12404 || substr($this->file->body, 0, 6) === 'GIF89a')
12406 return 'image/gif';
12408 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12410 return 'image/png';
12412 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12414 return 'image/jpeg';
12416 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12418 return 'image/bmp';
12430 * @return string Actual Content-Type
12432 function feed_or_html()
12434 $len = strlen($this->file->body);
12435 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12437 while ($pos < $len)
12439 switch ($this->file->body[$pos])
12445 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12453 return 'text/html';
12456 if (substr($this->file->body, $pos, 3) === '!--')
12459 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12465 return 'text/html';
12468 elseif (substr($this->file->body, $pos, 1) === '!')
12470 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12476 return 'text/html';
12479 elseif (substr($this->file->body, $pos, 1) === '?')
12481 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12487 return 'text/html';
12490 elseif (substr($this->file->body, $pos, 3) === 'rss'
12491 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12493 return 'application/rss+xml';
12495 elseif (substr($this->file->body, $pos, 4) === 'feed')
12497 return 'application/atom+xml';
12501 return 'text/html';
12505 return 'text/html';
12510 * Parses the XML Declaration
12512 * @package SimplePie
12514 class SimplePie_XML_Declaration_Parser
12522 var $version = '1.0';
12530 var $encoding = 'UTF-8';
12538 var $standalone = false;
12541 * Current state of the state machine
12546 var $state = 'before_version_name';
12557 * Input data length (to avoid calling strlen() everytime this is needed)
12562 var $data_length = 0;
12565 * Current position of the pointer
12573 * Create an instance of the class with the input data
12576 * @param string $data Input data
12578 function SimplePie_XML_Declaration_Parser($data)
12580 $this->data = $data;
12581 $this->data_length = strlen($this->data);
12585 * Parse the input data
12588 * @return bool true on success, false on failure
12592 while ($this->state && $this->state !== 'emit' && $this->has_data())
12594 $state = $this->state;
12598 if ($this->state === 'emit')
12604 $this->version = '';
12605 $this->encoding = '';
12606 $this->standalone = '';
12612 * Check whether there is data beyond the pointer
12615 * @return bool true if there is further data, false if not
12617 function has_data()
12619 return (bool) ($this->position < $this->data_length);
12623 * Advance past any whitespace
12625 * @return int Number of whitespace characters passed
12627 function skip_whitespace()
12629 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12630 $this->position += $whitespace;
12631 return $whitespace;
12637 function get_value()
12639 $quote = substr($this->data, $this->position, 1);
12640 if ($quote === '"' || $quote === "'")
12643 $len = strcspn($this->data, $quote, $this->position);
12644 if ($this->has_data())
12646 $value = substr($this->data, $this->position, $len);
12647 $this->position += $len + 1;
12654 function before_version_name()
12656 if ($this->skip_whitespace())
12658 $this->state = 'version_name';
12662 $this->state = false;
12666 function version_name()
12668 if (substr($this->data, $this->position, 7) === 'version')
12670 $this->position += 7;
12671 $this->skip_whitespace();
12672 $this->state = 'version_equals';
12676 $this->state = false;
12680 function version_equals()
12682 if (substr($this->data, $this->position, 1) === '=')
12685 $this->skip_whitespace();
12686 $this->state = 'version_value';
12690 $this->state = false;
12694 function version_value()
12696 if ($this->version = $this->get_value())
12698 $this->skip_whitespace();
12699 if ($this->has_data())
12701 $this->state = 'encoding_name';
12705 $this->state = 'emit';
12710 $this->state = 'standalone_name';
12714 function encoding_name()
12716 if (substr($this->data, $this->position, 8) === 'encoding')
12718 $this->position += 8;
12719 $this->skip_whitespace();
12720 $this->state = 'encoding_equals';
12724 $this->state = false;
12728 function encoding_equals()
12730 if (substr($this->data, $this->position, 1) === '=')
12733 $this->skip_whitespace();
12734 $this->state = 'encoding_value';
12738 $this->state = false;
12742 function encoding_value()
12744 if ($this->encoding = $this->get_value())
12746 $this->skip_whitespace();
12747 if ($this->has_data())
12749 $this->state = 'standalone_name';
12753 $this->state = 'emit';
12758 $this->state = false;
12762 function standalone_name()
12764 if (substr($this->data, $this->position, 10) === 'standalone')
12766 $this->position += 10;
12767 $this->skip_whitespace();
12768 $this->state = 'standalone_equals';
12772 $this->state = false;
12776 function standalone_equals()
12778 if (substr($this->data, $this->position, 1) === '=')
12781 $this->skip_whitespace();
12782 $this->state = 'standalone_value';
12786 $this->state = false;
12790 function standalone_value()
12792 if ($standalone = $this->get_value())
12794 switch ($standalone)
12797 $this->standalone = true;
12801 $this->standalone = false;
12805 $this->state = false;
12809 $this->skip_whitespace();
12810 if ($this->has_data())
12812 $this->state = false;
12816 $this->state = 'emit';
12821 $this->state = false;
12826 class SimplePie_Locator
12831 var $local = array();
12832 var $elsewhere = array();
12833 var $file_class = 'SimplePie_File';
12834 var $cached_entities = array();
12837 var $base_location = 0;
12838 var $checked_feeds = 0;
12839 var $max_checked_feeds = 10;
12840 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12843 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer', $proxy = "")
12845 $this->file =& $file;
12846 $this->file_class = $file_class;
12847 $this->useragent = $useragent;
12848 $this->timeout = $timeout;
12849 $this->max_checked_feeds = $max_checked_feeds;
12850 $this->content_type_sniffer_class = $content_type_sniffer_class;
12851 $this->proxy = $proxy;
12854 function find($type = SIMPLEPIE_LOCATOR_ALL)
12856 if ($this->is_feed($this->file))
12858 return $this->file;
12861 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12863 $sniffer = new $this->content_type_sniffer_class($this->file);
12864 if ($sniffer->get_type() !== 'text/html')
12870 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12875 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12880 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12882 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12887 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12892 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12897 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12905 function is_feed(&$file)
12907 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12909 $sniffer = new $this->content_type_sniffer_class($file);
12910 $sniffed = $sniffer->get_type();
12911 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12920 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12930 function get_base()
12932 $this->http_base = $this->file->url;
12933 $this->base = $this->http_base;
12934 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12935 foreach ($elements as $element)
12937 if ($element['attribs']['href']['data'] !== '')
12939 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12940 $this->base_location = $element['offset'];
12946 function autodiscovery()
12948 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
12950 foreach ($links as $link)
12952 if ($this->checked_feeds == $this->max_checked_feeds)
12956 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12958 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12960 if ($this->base_location < $link['offset'])
12962 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12966 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12969 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))))
12971 $this->checked_feeds++;
12972 $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
12973 if ($this->is_feed($feed))
12984 function get_links()
12986 $links = SimplePie_Misc::get_element('a', $this->file->body);
12987 foreach ($links as $link)
12989 if (isset($link['attribs']['href']['data']))
12991 $href = trim($link['attribs']['href']['data']);
12992 $parsed = SimplePie_Misc::parse_url($href);
12993 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12995 if ($this->base_location < $link['offset'])
12997 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
13001 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
13004 $current = SimplePie_Misc::parse_url($this->file->url);
13006 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
13008 $this->local[] = $href;
13012 $this->elsewhere[] = $href;
13017 $this->local = array_unique($this->local);
13018 $this->elsewhere = array_unique($this->elsewhere);
13019 if (!empty($this->local) || !empty($this->elsewhere))
13026 function extension(&$array)
13028 foreach ($array as $key => $value)
13030 if ($this->checked_feeds == $this->max_checked_feeds)
13034 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
13036 $this->checked_feeds++;
13037 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13038 if ($this->is_feed($feed))
13044 unset($array[$key]);
13051 function body(&$array)
13053 foreach ($array as $key => $value)
13055 if ($this->checked_feeds == $this->max_checked_feeds)
13059 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13061 $this->checked_feeds++;
13062 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13063 if ($this->is_feed($feed))
13069 unset($array[$key]);
13077 class SimplePie_Parser
13082 var $current_column;
13084 var $separator = ' ';
13086 var $namespace = array('');
13087 var $element = array('');
13088 var $xml_base = array('');
13089 var $xml_base_explicit = array(false);
13090 var $xml_lang = array('');
13091 var $data = array();
13092 var $datas = array(array());
13093 var $current_xhtml_construct = -1;
13096 function parse(&$data, $encoding)
13098 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13099 if (strtoupper($encoding) == 'US-ASCII')
13101 $this->encoding = 'UTF-8';
13105 $this->encoding = $encoding;
13109 // UTF-32 Big Endian BOM
13110 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13112 $data = substr($data, 4);
13114 // UTF-32 Little Endian BOM
13115 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13117 $data = substr($data, 4);
13119 // UTF-16 Big Endian BOM
13120 elseif (substr($data, 0, 2) === "\xFE\xFF")
13122 $data = substr($data, 2);
13124 // UTF-16 Little Endian BOM
13125 elseif (substr($data, 0, 2) === "\xFF\xFE")
13127 $data = substr($data, 2);
13130 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13132 $data = substr($data, 3);
13135 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13137 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13138 if ($declaration->parse())
13140 $data = substr($data, $pos + 2);
13141 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13145 $this->error_string = 'SimplePie bug! Please report this!';
13150 // Work around libxml bug
13151 $data = str_replace('<', '<', $data);
13152 $data = str_replace('>', '>', $data);
13153 $data = str_replace('&', '&', $data);
13154 $data = str_replace(''', ''', $data);
13155 $data = str_replace('"', '"', $data);
13159 // Create the parser
13160 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13161 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13162 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13163 xml_set_object($xml, $this);
13164 xml_set_character_data_handler($xml, 'cdata');
13165 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13168 if (!xml_parse($xml, $data, true))
13170 $this->error_code = xml_get_error_code($xml);
13171 $this->error_string = xml_error_string($this->error_code);
13174 $this->current_line = xml_get_current_line_number($xml);
13175 $this->current_column = xml_get_current_column_number($xml);
13176 $this->current_byte = xml_get_current_byte_index($xml);
13177 xml_parser_free($xml);
13181 function get_error_code()
13183 return $this->error_code;
13186 function get_error_string()
13188 return $this->error_string;
13191 function get_current_line()
13193 return $this->current_line;
13196 function get_current_column()
13198 return $this->current_column;
13201 function get_current_byte()
13203 return $this->current_byte;
13206 function get_data()
13208 return $this->data;
13211 function tag_open($parser, $tag, $attributes)
13213 if ($this->feed === 0)
13217 elseif ($this->feed == false)
13219 if (in_array($tag, array(
13220 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13221 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13223 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13234 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13236 $attribs = array();
13237 foreach ($attributes as $name => $value)
13239 list($attrib_namespace, $attribute) = $this->split_ns($name);
13240 $attribs[$attrib_namespace][$attribute] = $value;
13243 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13245 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13246 $this->xml_base_explicit[] = true;
13250 $this->xml_base[] = end($this->xml_base);
13251 $this->xml_base_explicit[] = end($this->xml_base_explicit);
13254 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13256 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13260 $this->xml_lang[] = end($this->xml_lang);
13263 if ($this->current_xhtml_construct >= 0)
13265 $this->current_xhtml_construct++;
13266 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13268 $this->data['data'] .= '<' . end($this->element);
13269 if (isset($attribs['']))
13271 foreach ($attribs[''] as $name => $value)
13273 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13276 $this->data['data'] .= '>';
13281 $this->datas[] =& $this->data;
13282 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13283 $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
13284 if ((end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] == 'xml')
13285 || (end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] == 'xhtml'))
13287 $this->current_xhtml_construct = 0;
13292 function cdata($parser, $cdata)
13294 if ($this->current_xhtml_construct >= 0)
13296 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13298 elseif ($this->feed > 1)
13300 $this->data['data'] .= $cdata;
13304 function tag_close($parser, $tag)
13311 if ($this->current_xhtml_construct >= 0)
13313 $this->current_xhtml_construct--;
13314 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
13316 $this->data['data'] .= '</' . end($this->element) . '>';
13319 if ($this->current_xhtml_construct == -1)
13321 $this->data =& $this->datas[$this->feed];
13322 array_pop($this->datas);
13325 array_pop($this->element);
13326 array_pop($this->namespace);
13327 array_pop($this->xml_base);
13328 array_pop($this->xml_base_explicit);
13329 array_pop($this->xml_lang);
13333 function split_ns($string)
13335 static $cache = array();
13336 if (!isset($cache[$string]))
13338 if ($pos = strpos($string, $this->separator))
13340 static $separator_length;
13341 if (!$separator_length)
13343 $separator_length = strlen($this->separator);
13345 $namespace = substr($string, 0, $pos);
13346 $local_name = substr($string, $pos + $separator_length);
13347 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13349 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13352 // Normalize the Media RSS namespaces
13353 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13355 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13357 $cache[$string] = array($namespace, $local_name);
13361 $cache[$string] = array('', $string);
13364 return $cache[$string];
13369 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
13371 class SimplePie_Sanitize
13377 var $remove_div = true;
13378 var $image_handler = '';
13379 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13380 var $encode_instead_of_strip = false;
13381 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13382 var $strip_comments = false;
13383 var $output_encoding = 'UTF-8';
13384 var $enable_cache = true;
13385 var $cache_location = './cache';
13386 var $cache_name_function = 'md5';
13387 var $cache_class = 'SimplePie_Cache';
13388 var $file_class = 'SimplePie_File';
13390 var $useragent = '';
13391 var $force_fsockopen = false;
13394 var $replace_url_attributes = array(
13397 'blockquote' => 'cite',
13399 'form' => 'action',
13400 'img' => array('longdesc', 'src'),
13406 function remove_div($enable = true)
13408 $this->remove_div = (bool) $enable;
13411 function set_image_handler($page = false)
13415 $this->image_handler = (string) $page;
13419 $this->image_handler = false;
13423 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13425 if (isset($enable_cache))
13427 $this->enable_cache = (bool) $enable_cache;
13430 if ($cache_location)
13432 $this->cache_location = (string) $cache_location;
13435 if ($cache_name_function)
13437 $this->cache_name_function = (string) $cache_name_function;
13442 $this->cache_class = (string) $cache_class;
13446 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13450 $this->file_class = (string) $file_class;
13455 $this->timeout = (string) $timeout;
13460 $this->useragent = (string) $useragent;
13463 if ($force_fsockopen)
13465 $this->force_fsockopen = (string) $force_fsockopen;
13469 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13473 if (is_array($tags))
13475 $this->strip_htmltags = $tags;
13479 $this->strip_htmltags = explode(',', $tags);
13484 $this->strip_htmltags = false;
13488 function encode_instead_of_strip($encode = false)
13490 $this->encode_instead_of_strip = (bool) $encode;
13493 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13497 if (is_array($attribs))
13499 $this->strip_attributes = $attribs;
13503 $this->strip_attributes = explode(',', $attribs);
13508 $this->strip_attributes = false;
13512 function strip_comments($strip = false)
13514 $this->strip_comments = (bool) $strip;
13517 function set_output_encoding($encoding = 'UTF-8')
13519 $this->output_encoding = (string) $encoding;
13523 * Set element/attribute key/value pairs of HTML attributes
13524 * containing URLs that need to be resolved relative to the feed
13528 * @param array $element_attribute Element/attribute key/value pairs
13530 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'))
13532 $this->replace_url_attributes = (array) $element_attribute;
13535 function sanitize($data, $type, $base = '')
13537 $data = trim($data);
13538 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13540 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13542 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
13544 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13548 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13552 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13554 $data = base64_decode($data);
13557 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13559 if ($this->remove_div)
13561 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13562 $data = preg_replace('/<\/div>$/', '', $data);
13566 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13570 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13573 if ($this->strip_comments)
13575 $data = SimplePie_Misc::strip_comments($data);
13578 // Strip out HTML tags and attributes that might cause various security problems.
13579 // Based on recommendations by Mark Pilgrim at:
13580 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13581 if ($this->strip_htmltags)
13583 foreach ($this->strip_htmltags as $tag)
13585 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13586 while (preg_match($pcre, $data))
13588 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13593 if ($this->strip_attributes)
13595 foreach ($this->strip_attributes as $attrib)
13597 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
13601 // Replace relative URLs
13602 $this->base = $base;
13603 foreach ($this->replace_url_attributes as $element => $attributes)
13605 $data = $this->replace_urls($data, $element, $attributes);
13608 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13609 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13611 $images = SimplePie_Misc::get_element('img', $data);
13612 foreach ($images as $img)
13614 if (isset($img['attribs']['src']['data']))
13616 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13617 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13619 if ($cache->load())
13621 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13622 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13626 $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen, $this->proxy);
13627 $headers = $file->headers;
13629 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13631 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13633 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13634 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13638 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13646 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13647 $data = trim($data);
13650 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13652 $data = SimplePie_Misc::absolutize_url($data, $base);
13655 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13657 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13660 if ($this->output_encoding != 'UTF-8')
13662 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13668 function replace_urls($data, $tag, $attributes)
13670 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13672 $elements = SimplePie_Misc::get_element($tag, $data);
13673 foreach ($elements as $element)
13675 if (is_array($attributes))
13677 foreach ($attributes as $attribute)
13679 if (isset($element['attribs'][$attribute]['data']))
13681 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13682 $new_element = SimplePie_Misc::element_implode($element);
13683 $data = str_replace($element['full'], $new_element, $data);
13684 $element['full'] = $new_element;
13688 elseif (isset($element['attribs'][$attributes]['data']))
13690 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13691 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13698 function do_strip_htmltags($match)
13700 if ($this->encode_instead_of_strip)
13702 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13704 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13705 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13706 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13710 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13713 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))