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:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1531 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
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">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'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7073 // Flash Media Player file types.
7074 // Preferred handler for MP3 file types.
7075 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7080 $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>";
7084 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7088 // QuickTime 7 file types. Need to test with QuickTime 6.
7089 // Only handle MP3's if the Flash Media Player is not present.
7090 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7095 if ($placeholder != ""){
7096 $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>";
7099 $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>";
7104 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7109 elseif ($handler == 'wmedia')
7114 $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>";
7118 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7123 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7128 function get_real_type($find_handler = false)
7130 // If it's Odeo, let's get it out of the way.
7131 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7136 // Mime-types by handler.
7137 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7138 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7139 $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
7140 $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
7141 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7143 if ($this->get_type() !== null)
7145 $type = strtolower($this->type);
7152 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7153 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7155 switch (strtolower($this->get_extension()))
7160 $type = 'audio/acc';
7167 $type = 'audio/aiff';
7171 $type = 'audio/wav';
7178 $type = 'audio/midi';
7182 $type = 'audio/x-m4a';
7187 $type = 'audio/mp3';
7191 $type = 'audio/wav';
7195 $type = 'audio/x-ms-wax';
7199 $type = 'audio/x-ms-wma';
7205 $type = 'video/3gpp';
7210 $type = 'video/3gpp2';
7214 $type = 'video/x-ms-asf';
7218 $type = 'video/x-flv';
7232 $type = 'video/mpeg';
7236 $type = 'video/x-m4v';
7241 $type = 'video/quicktime';
7246 $type = 'video/mp4';
7250 $type = 'video/sd-video';
7254 $type = 'video/x-ms-wm';
7258 $type = 'video/x-ms-wmv';
7262 $type = 'video/x-ms-wvx';
7267 $type = 'application/futuresplash';
7271 $type = 'application/x-shockwave-flash';
7278 if (in_array($type, $types_flash))
7282 elseif (in_array($type, $types_fmedia))
7286 elseif (in_array($type, $types_quicktime))
7290 elseif (in_array($type, $types_wmedia))
7294 elseif (in_array($type, $types_mp3))
7310 class SimplePie_Caption
7318 // Constructor, used to input the data
7319 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7321 $this->type = $type;
7322 $this->lang = $lang;
7323 $this->startTime = $startTime;
7324 $this->endTime = $endTime;
7325 $this->text = $text;
7328 function __toString()
7330 // There is no $this->data here
7331 return md5(serialize($this));
7334 function get_endtime()
7336 if ($this->endTime !== null)
7338 return $this->endTime;
7346 function get_language()
7348 if ($this->lang !== null)
7358 function get_starttime()
7360 if ($this->startTime !== null)
7362 return $this->startTime;
7372 if ($this->text !== null)
7384 if ($this->type !== null)
7395 class SimplePie_Credit
7401 // Constructor, used to input the data
7402 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7404 $this->role = $role;
7405 $this->scheme = $scheme;
7406 $this->name = $name;
7409 function __toString()
7411 // There is no $this->data here
7412 return md5(serialize($this));
7417 if ($this->role !== null)
7427 function get_scheme()
7429 if ($this->scheme !== null)
7431 return $this->scheme;
7441 if ($this->name !== null)
7452 class SimplePie_Copyright
7457 // Constructor, used to input the data
7458 function SimplePie_Copyright($url = null, $label = null)
7461 $this->label = $label;
7464 function __toString()
7466 // There is no $this->data here
7467 return md5(serialize($this));
7472 if ($this->url !== null)
7482 function get_attribution()
7484 if ($this->label !== null)
7486 return $this->label;
7495 class SimplePie_Rating
7500 // Constructor, used to input the data
7501 function SimplePie_Rating($scheme = null, $value = null)
7503 $this->scheme = $scheme;
7504 $this->value = $value;
7507 function __toString()
7509 // There is no $this->data here
7510 return md5(serialize($this));
7513 function get_scheme()
7515 if ($this->scheme !== null)
7517 return $this->scheme;
7525 function get_value()
7527 if ($this->value !== null)
7529 return $this->value;
7538 class SimplePie_Restriction
7544 // Constructor, used to input the data
7545 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7547 $this->relationship = $relationship;
7548 $this->type = $type;
7549 $this->value = $value;
7552 function __toString()
7554 // There is no $this->data here
7555 return md5(serialize($this));
7558 function get_relationship()
7560 if ($this->relationship !== null)
7562 return $this->relationship;
7572 if ($this->type !== null)
7582 function get_value()
7584 if ($this->value !== null)
7586 return $this->value;
7596 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7598 class SimplePie_File
7602 var $success = true;
7603 var $headers = array();
7608 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7610 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $proxy = "")
7612 if (class_exists('idna_convert'))
7614 $idn =& new idna_convert;
7615 $parsed = SimplePie_Misc::parse_url($url);
7616 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7619 $this->useragent = $useragent;
7620 if (preg_match('/^http(s)?:\/\//i', $url))
7622 if ($useragent === null)
7624 $useragent = ini_get('user_agent');
7625 $this->useragent = $useragent;
7627 if (!is_array($headers))
7631 if (!$force_fsockopen && function_exists('curl_exec'))
7633 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7635 $headers2 = array();
7636 foreach ($headers as $key => $value)
7638 $headers2[] = "$key: $value";
7640 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7642 curl_setopt($fp, CURLOPT_ENCODING, '');
7644 curl_setopt($fp, CURLOPT_URL, $url);
7645 curl_setopt($fp, CURLOPT_HEADER, 1);
7646 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7647 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7648 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7649 curl_setopt($fp, CURLOPT_REFERER, $url);
7650 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7651 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7652 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7654 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7655 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7659 curl_setopt($fp, CURLOPT_PROXY, $proxy);
7662 $this->headers = curl_exec($fp);
7663 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7665 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7666 $this->headers = curl_exec($fp);
7668 if (curl_errno($fp))
7670 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7671 $this->success = false;
7675 $info = curl_getinfo($fp);
7677 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7678 $this->headers = array_pop($this->headers);
7679 $parser =& new SimplePie_HTTP_Parser($this->headers);
7680 if ($parser->parse())
7682 $this->headers = $parser->headers;
7683 $this->body = $parser->body;
7684 $this->status_code = $parser->status_code;
7685 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)
7688 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7689 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7696 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7697 $url_parts = parse_url($url);
7698 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7700 $url_parts['host'] = "ssl://$url_parts[host]";
7701 $url_parts['port'] = 443;
7703 if (!isset($url_parts['port']))
7705 $url_parts['port'] = 80;
7708 $proxy_parts = explode(':', $proxy);
7709 if (!isset($proxy_parts[1])) {
7710 $proxy_parts[1] = 80;
7712 $host = $proxy_parts[0];
7713 $port = $proxy_parts[1];
7715 $host = $url_parts['host'];
7716 $port = $url_parts['port'];
7718 $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
7721 $this->error = 'fsockopen error: ' . $errstr;
7722 $this->success = false;
7726 stream_set_timeout($fp, $timeout);
7730 if (isset($url_parts['path']))
7732 if (isset($url_parts['query']))
7734 $get = "$url_parts[path]?$url_parts[query]";
7738 $get = $url_parts['path'];
7746 $out = "GET $get HTTP/1.0\r\n";
7747 $out .= "Host: $url_parts[host]\r\n";
7748 $out .= "User-Agent: $useragent\r\n";
7749 if (extension_loaded('zlib'))
7751 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7754 if (isset($url_parts['user']) && isset($url_parts['pass']))
7756 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7758 foreach ($headers as $key => $value)
7760 $out .= "$key: $value\r\n";
7762 $out .= "Connection: Close\r\n\r\n";
7765 $info = stream_get_meta_data($fp);
7767 $this->headers = '';
7768 while (!$info['eof'] && !$info['timed_out'])
7770 $this->headers .= fread($fp, 1160);
7771 $info = stream_get_meta_data($fp);
7773 if (!$info['timed_out'])
7775 $parser =& new SimplePie_HTTP_Parser($this->headers);
7776 if ($parser->parse())
7778 $this->headers = $parser->headers;
7779 $this->body = $parser->body;
7780 $this->status_code = $parser->status_code;
7781 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)
7784 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7785 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7787 if (isset($this->headers['content-encoding']))
7789 // Hey, we act dumb elsewhere, so let's do that here too
7790 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7794 $decoder = new SimplePie_gzdecode($this->body);
7795 if (!$decoder->parse())
7797 $this->error = 'Unable to decode HTTP "gzip" stream';
7798 $this->success = false;
7802 $this->body = $decoder->data;
7807 if (($body = gzuncompress($this->body)) === false)
7809 if (($body = gzinflate($this->body)) === false)
7811 $this->error = 'Unable to decode HTTP "deflate" stream';
7812 $this->success = false;
7815 $this->body = $body;
7819 $this->error = 'Unknown content coding';
7820 $this->success = false;
7827 $this->error = 'fsocket timed out';
7828 $this->success = false;
7836 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7837 if (!$this->body = file_get_contents($url))
7839 $this->error = 'file_get_contents could not read the file';
7840 $this->success = false;
7847 * HTTP Response Parser
7849 * @package SimplePie
7851 class SimplePie_HTTP_Parser
7859 var $http_version = 0.0;
7867 var $status_code = 0;
7878 * Key/value pairs of the headers
7883 var $headers = array();
7886 * Body of the response
7894 * Current state of the state machine
7899 var $state = 'http_version';
7910 * Input data length (to avoid calling strlen() everytime this is needed)
7915 var $data_length = 0;
7918 * Current position of the pointer
7926 * Name of the hedaer currently being parsed
7934 * Value of the hedaer currently being parsed
7942 * Create an instance of the class with the input data
7945 * @param string $data Input data
7947 function SimplePie_HTTP_Parser($data)
7949 $this->data = $data;
7950 $this->data_length = strlen($this->data);
7954 * Parse the input data
7957 * @return bool true on success, false on failure
7961 while ($this->state && $this->state !== 'emit' && $this->has_data())
7963 $state = $this->state;
7967 if ($this->state === 'emit' || $this->state === 'body')
7973 $this->http_version = '';
7974 $this->status_code = '';
7976 $this->headers = array();
7983 * Check whether there is data beyond the pointer
7986 * @return bool true if there is further data, false if not
7990 return (bool) ($this->position < $this->data_length);
7994 * See if the next character is LWS
7997 * @return bool true if the next character is LWS, false if not
7999 function is_linear_whitespace()
8001 return (bool) ($this->data[$this->position] === "\x09"
8002 || $this->data[$this->position] === "\x20"
8003 || ($this->data[$this->position] === "\x0A"
8004 && isset($this->data[$this->position + 1])
8005 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8009 * Parse the HTTP version
8013 function http_version()
8015 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8017 $len = strspn($this->data, '0123456789.', 5);
8018 $this->http_version = substr($this->data, 5, $len);
8019 $this->position += 5 + $len;
8020 if (substr_count($this->http_version, '.') <= 1)
8022 $this->http_version = (float) $this->http_version;
8023 $this->position += strspn($this->data, "\x09\x20", $this->position);
8024 $this->state = 'status';
8028 $this->state = false;
8033 $this->state = false;
8038 * Parse the status code
8044 if ($len = strspn($this->data, '0123456789', $this->position))
8046 $this->status_code = (int) substr($this->data, $this->position, $len);
8047 $this->position += $len;
8048 $this->state = 'reason';
8052 $this->state = false;
8057 * Parse the reason phrase
8063 $len = strcspn($this->data, "\x0A", $this->position);
8064 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8065 $this->position += $len + 1;
8066 $this->state = 'new_line';
8070 * Deal with a new line, shifting data around as needed
8076 $this->value = trim($this->value, "\x0D\x20");
8077 if ($this->name !== '' && $this->value !== '')
8079 $this->name = strtolower($this->name);
8080 if (isset($this->headers[$this->name]))
8082 $this->headers[$this->name] .= ', ' . $this->value;
8086 $this->headers[$this->name] = $this->value;
8091 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8093 $this->position += 2;
8094 $this->state = 'body';
8096 elseif ($this->data[$this->position] === "\x0A")
8099 $this->state = 'body';
8103 $this->state = 'name';
8108 * Parse a header name
8114 $len = strcspn($this->data, "\x0A:", $this->position);
8115 if (isset($this->data[$this->position + $len]))
8117 if ($this->data[$this->position + $len] === "\x0A")
8119 $this->position += $len;
8120 $this->state = 'new_line';
8124 $this->name = substr($this->data, $this->position, $len);
8125 $this->position += $len + 1;
8126 $this->state = 'value';
8131 $this->state = false;
8136 * Parse LWS, replacing consecutive LWS characters with a single space
8140 function linear_whitespace()
8144 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8146 $this->position += 2;
8148 elseif ($this->data[$this->position] === "\x0A")
8152 $this->position += strspn($this->data, "\x09\x20", $this->position);
8153 } while ($this->has_data() && $this->is_linear_whitespace());
8154 $this->value .= "\x20";
8158 * See what state to move to while within non-quoted header values
8164 if ($this->is_linear_whitespace())
8166 $this->linear_whitespace();
8170 switch ($this->data[$this->position])
8174 $this->state = 'quote';
8179 $this->state = 'new_line';
8183 $this->state = 'value_char';
8190 * Parse a header value while outside quotes
8194 function value_char()
8196 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8197 $this->value .= substr($this->data, $this->position, $len);
8198 $this->position += $len;
8199 $this->state = 'value';
8203 * See what state to move to while within quoted header values
8209 if ($this->is_linear_whitespace())
8211 $this->linear_whitespace();
8215 switch ($this->data[$this->position])
8219 $this->state = 'value';
8224 $this->state = 'new_line';
8229 $this->state = 'quote_escaped';
8233 $this->state = 'quote_char';
8240 * Parse a header value while within quotes
8244 function quote_char()
8246 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8247 $this->value .= substr($this->data, $this->position, $len);
8248 $this->position += $len;
8249 $this->state = 'value';
8253 * Parse an escaped character within quotes
8257 function quote_escaped()
8259 $this->value .= $this->data[$this->position];
8261 $this->state = 'quote';
8271 $this->body = substr($this->data, $this->position);
8272 $this->state = 'emit';
8279 * @package SimplePie
8281 class SimplePie_gzdecode
8287 * @see gzdecode::$data
8289 var $compressed_data;
8292 * Size of compressed data
8296 var $compressed_size;
8299 * Minimum size of a valid gzip string
8303 var $min_compressed_size = 18;
8306 * Current position of pointer
8323 * @see gzdecode::$compressed_data
8352 * @see gzdecode::$extra_field
8353 * @see gzdecode::$SI2
8361 * @see gzdecode::$extra_field
8362 * @see gzdecode::$SI1
8367 * Extra field content
8370 * @see gzdecode::$SI1
8371 * @see gzdecode::$SI2
8383 * Human readable comment
8390 * Don't allow anything to be set
8394 function __set($name, $value)
8396 trigger_error("Cannot write property $name", E_USER_ERROR);
8400 * Set the compressed string and related properties
8404 function SimplePie_gzdecode($data)
8406 $this->compressed_data = $data;
8407 $this->compressed_size = strlen($data);
8411 * Decode the GZIP stream
8417 if ($this->compressed_size >= $this->min_compressed_size)
8419 // Check ID1, ID2, and CM
8420 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8425 // Get the FLG (FLaGs)
8426 $this->flags = ord($this->compressed_data[3]);
8428 // FLG bits above (1 << 4) are reserved
8429 if ($this->flags > 0x1F)
8434 // Advance the pointer after the above
8435 $this->position += 4;
8438 $mtime = substr($this->compressed_data, $this->position, 4);
8439 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8440 if (current(unpack('S', "\x00\x01")) === 1)
8442 $mtime = strrev($mtime);
8444 $this->MTIME = current(unpack('l', $mtime));
8445 $this->position += 4;
8447 // Get the XFL (eXtra FLags)
8448 $this->XFL = ord($this->compressed_data[$this->position++]);
8450 // Get the OS (Operating System)
8451 $this->OS = ord($this->compressed_data[$this->position++]);
8454 if ($this->flags & 4)
8456 // Read subfield IDs
8457 $this->SI1 = $this->compressed_data[$this->position++];
8458 $this->SI2 = $this->compressed_data[$this->position++];
8460 // SI2 set to zero is reserved for future use
8461 if ($this->SI2 === "\x00")
8466 // Get the length of the extra field
8467 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8470 // Check the length of the string is still valid
8471 $this->min_compressed_size += $len + 4;
8472 if ($this->compressed_size >= $this->min_compressed_size)
8474 // Set the extra field to the given data
8475 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8476 $this->position += $len;
8485 if ($this->flags & 8)
8487 // Get the length of the filename
8488 $len = strspn($this->compressed_data, "\x00", $this->position);
8490 // Check the length of the string is still valid
8491 $this->min_compressed_size += $len + 1;
8492 if ($this->compressed_size >= $this->min_compressed_size)
8494 // Set the original filename to the given string
8495 $this->filename = substr($this->compressed_data, $this->position, $len);
8496 $this->position += $len + 1;
8504 // Parse the FCOMMENT
8505 if ($this->flags & 16)
8507 // Get the length of the comment
8508 $len = strspn($this->compressed_data, "\x00", $this->position);
8510 // Check the length of the string is still valid
8511 $this->min_compressed_size += $len + 1;
8512 if ($this->compressed_size >= $this->min_compressed_size)
8514 // Set the original comment to the given string
8515 $this->comment = substr($this->compressed_data, $this->position, $len);
8516 $this->position += $len + 1;
8525 if ($this->flags & 2)
8527 // Check the length of the string is still valid
8528 $this->min_compressed_size += $len + 2;
8529 if ($this->compressed_size >= $this->min_compressed_size)
8532 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8534 // Check the CRC matches
8535 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8537 $this->position += 2;
8550 // Decompress the actual data
8551 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8557 $this->position = $this->compressed_size - 8;
8560 // Check CRC of data
8561 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8562 $this->position += 4;
8563 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8568 // Check ISIZE of data
8569 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8570 $this->position += 4;
8571 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8576 // Wow, against all odds, we've actually got a valid gzip string
8586 class SimplePie_Cache
8589 * Don't call the constructor. Please.
8593 function SimplePie_Cache()
8595 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8599 * Create a new SimplePie_Cache object
8604 function create($location, $filename, $extension)
8606 return new SimplePie_Cache_File($location, $filename, $extension);
8610 class SimplePie_Cache_File
8617 function SimplePie_Cache_File($location, $filename, $extension)
8619 $this->location = $location;
8620 $this->filename = rawurlencode($filename);
8621 $this->extension = rawurlencode($extension);
8622 $this->name = "$location/$this->filename.$this->extension";
8625 function save($data)
8627 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8629 if (is_a($data, 'SimplePie'))
8631 $data = $data->data;
8634 $data = serialize($data);
8636 if (function_exists('file_put_contents'))
8638 return (bool) file_put_contents($this->name, $data);
8642 $fp = fopen($this->name, 'wb');
8656 if (file_exists($this->name) && is_readable($this->name))
8658 return unserialize(file_get_contents($this->name));
8665 if (file_exists($this->name))
8667 return filemtime($this->name);
8674 if (file_exists($this->name))
8676 return touch($this->name);
8683 if (file_exists($this->name))
8685 return unlink($this->name);
8691 class SimplePie_Misc
8693 function time_hms($seconds)
8697 $hours = floor($seconds / 3600);
8698 $remainder = $seconds % 3600;
8701 $time .= $hours.':';
8704 $minutes = floor($remainder / 60);
8705 $seconds = $remainder % 60;
8706 if ($minutes < 10 && $hours > 0)
8708 $minutes = '0' . $minutes;
8712 $seconds = '0' . $seconds;
8715 $time .= $minutes.':';
8721 function absolutize_url($relative, $base)
8723 if ($relative !== '')
8725 $relative = SimplePie_Misc::parse_url($relative);
8726 if ($relative['scheme'] !== '')
8728 $target = $relative;
8730 elseif ($base !== '')
8732 $base = SimplePie_Misc::parse_url($base);
8733 $target = SimplePie_Misc::parse_url('');
8734 if ($relative['authority'] !== '')
8736 $target = $relative;
8737 $target['scheme'] = $base['scheme'];
8741 $target['scheme'] = $base['scheme'];
8742 $target['authority'] = $base['authority'];
8743 if ($relative['path'] !== '')
8745 if (strpos($relative['path'], '/') === 0)
8747 $target['path'] = $relative['path'];
8749 elseif ($base['authority'] !== '' && $base['path'] === '')
8751 $target['path'] = '/' . $relative['path'];
8753 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8755 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8759 $target['path'] = $relative['path'];
8761 $target['query'] = $relative['query'];
8765 $target['path'] = $base['path'];
8766 if ($relative['query'] !== '')
8768 $target['query'] = $relative['query'];
8770 elseif ($base['query'] !== '')
8772 $target['query'] = $base['query'];
8776 $target['fragment'] = $relative['fragment'];
8780 // No base URL, just return the relative URL
8781 $target = $relative;
8783 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8789 $return = SimplePie_Misc::normalize_url($return);
8793 function remove_dot_segments($input)
8796 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8798 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8799 if (strpos($input, '../') === 0)
8801 $input = substr($input, 3);
8803 elseif (strpos($input, './') === 0)
8805 $input = substr($input, 2);
8807 // 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,
8808 elseif (strpos($input, '/./') === 0)
8810 $input = substr_replace($input, '/', 0, 3);
8812 elseif ($input == '/.')
8816 // 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,
8817 elseif (strpos($input, '/../') === 0)
8819 $input = substr_replace($input, '/', 0, 4);
8820 $output = substr_replace($output, '', strrpos($output, '/'));
8822 elseif ($input == '/..')
8825 $output = substr_replace($output, '', strrpos($output, '/'));
8827 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8828 elseif ($input == '.' || $input == '..')
8832 // 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
8833 elseif (($pos = strpos($input, '/', 1)) !== false)
8835 $output .= substr($input, 0, $pos);
8836 $input = substr_replace($input, '', 0, $pos);
8844 return $output . $input;
8847 function get_element($realname, $string)
8850 $name = preg_quote($realname, '/');
8851 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8853 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8855 $return[$i]['tag'] = $realname;
8856 $return[$i]['full'] = $matches[$i][0][0];
8857 $return[$i]['offset'] = $matches[$i][0][1];
8858 if (strlen($matches[$i][3][0]) <= 2)
8860 $return[$i]['self_closing'] = true;
8864 $return[$i]['self_closing'] = false;
8865 $return[$i]['content'] = $matches[$i][4][0];
8867 $return[$i]['attribs'] = array();
8868 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))
8870 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8872 if (count($attribs[$j]) == 2)
8874 $attribs[$j][2] = $attribs[$j][1];
8876 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8884 function element_implode($element)
8886 $full = "<$element[tag]";
8887 foreach ($element['attribs'] as $key => $value)
8889 $key = strtolower($key);
8890 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8892 if ($element['self_closing'])
8898 $full .= ">$element[content]</$element[tag]>";
8903 function error($message, $level, $file, $line)
8908 $note = 'PHP Error';
8910 case E_USER_WARNING:
8911 $note = 'PHP Warning';
8914 $note = 'PHP Notice';
8917 $note = 'Unknown Error';
8920 error_log("$note: $message in $file on line $line", 0);
8925 * If a file has been cached, retrieve and display it.
8927 * This is most useful for caching images (get_favicon(), etc.),
8928 * however it works for all cached files. This WILL NOT display ANY
8929 * file/image/page/whatever, but rather only display what has already
8930 * been cached by SimplePie.
8933 * @see SimplePie::get_favicon()
8934 * @param str $identifier_url URL that is used to identify the content.
8935 * This may or may not be the actual URL of the live content.
8936 * @param str $cache_location Location of SimplePie's cache. Defaults
8938 * @param str $cache_extension The file extension that the file was
8939 * cached with. Defaults to 'spc'.
8940 * @param str $cache_class Name of the cache-handling class being used
8941 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8942 * as-is unless you've overloaded the class.
8943 * @param str $cache_name_function Obsolete. Exists for backwards
8944 * compatibility reasons only.
8946 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8948 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8950 if ($file = $cache->load())
8952 if (isset($file['headers']['content-type']))
8954 header('Content-type:' . $file['headers']['content-type']);
8958 header('Content-type: application/octet-stream');
8960 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8965 die('Cached file for ' . $identifier_url . ' cannot be found.');
8968 function fix_protocol($url, $http = 1)
8970 $url = SimplePie_Misc::normalize_url($url);
8971 $parsed = SimplePie_Misc::parse_url($url);
8972 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8974 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8977 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8979 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8982 if ($http == 2 && $parsed['scheme'] !== '')
8986 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8988 return substr_replace($url, 'podcast', 0, 4);
8990 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8992 return substr_replace($url, 'itpc', 0, 4);
9000 function parse_url($url)
9002 static $cache = array();
9003 if (isset($cache[$url]))
9005 return $cache[$url];
9007 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
9009 for ($i = count($match); $i <= 9; $i++)
9013 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
9017 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
9021 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9026 $return .= "$scheme:";
9028 if ($authority !== '')
9030 $return .= "//$authority";
9038 $return .= "?$query";
9040 if ($fragment !== '')
9042 $return .= "#$fragment";
9047 function normalize_url($url)
9049 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9050 $url = SimplePie_Misc::parse_url($url);
9051 $url['scheme'] = strtolower($url['scheme']);
9052 if ($url['authority'] !== '')
9054 $url['authority'] = strtolower($url['authority']);
9055 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9057 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9060 function percent_encoding_normalization($match)
9062 $integer = hexdec($match[1]);
9063 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9065 return chr($integer);
9069 return strtoupper($match[0]);
9074 * Remove bad UTF-8 bytes
9076 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9077 * FAQ: Multilingual Forms (modified to include full ASCII range)
9079 * @author Geoffrey Sneddon
9080 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9081 * @param string $str String to remove bad UTF-8 bytes from
9082 * @return string UTF-8 string
9084 function utf8_bad_replace($str)
9086 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9090 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9094 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))
9096 return implode("\xEF\xBF\xBD", $matches[0]);
9098 elseif ($str !== '')
9100 return "\xEF\xBF\xBD";
9109 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9113 * @param string $string Windows-1252 encoded string
9114 * @return string UTF-8 encoded string
9116 function windows_1252_to_utf8($string)
9118 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");
9120 return strtr($string, $convert_table);
9123 function change_encoding($data, $input, $output)
9125 $input = SimplePie_Misc::encoding($input);
9126 $output = SimplePie_Misc::encoding($output);
9128 // We fail to fail on non US-ASCII bytes
9129 if ($input === 'US-ASCII')
9131 static $non_ascii_octects = '';
9132 if (!$non_ascii_octects)
9134 for ($i = 0x80; $i <= 0xFF; $i++)
9136 $non_ascii_octects .= chr($i);
9139 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9142 // This is first, as behaviour of this is completely predictable
9143 if ($input === 'Windows-1252' && $output === 'UTF-8')
9145 return SimplePie_Misc::windows_1252_to_utf8($data);
9147 // This is second, as behaviour of this varies only with PHP version
9148 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9152 // This is last, as behaviour of this varies with OS userland and PHP version
9153 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9157 // If we can't do anything, just fail
9164 function encoding($charset)
9166 /* Character sets are case-insensitive, and also need some further
9167 normalization in the real world (though we'll return them in the form given
9168 in their registration). */
9169 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9171 case 'adobestandardencoding':
9172 case 'csadobestandardencoding':
9173 return 'Adobe-Standard-Encoding';
9175 case 'adobesymbolencoding':
9177 return 'Adobe-Symbol-Encoding';
9183 return 'Amiga-1251';
9185 case 'ansix31101983':
9187 case 'csiso99naplps':
9190 return 'ANSI_X3.110-1983';
9194 case 'csiso89asmo449':
9205 return 'Big5-HKSCS';
9216 case 'csiso4unitedkingdom':
9224 case 'csiso47bsviewdata':
9226 return 'BS_viewdata';
9234 case 'csaz243419851':
9235 case 'csiso121canadian1':
9238 return 'CSA_Z243.4-1985-1';
9241 case 'csaz243419852':
9242 case 'csiso122canadian2':
9245 return 'CSA_Z243.4-1985-2';
9247 case 'csaz24341985gr':
9248 case 'csiso123csaz24341985gr':
9250 return 'CSA_Z243.4-1985-gr';
9252 case 'csiso139csn369103':
9255 return 'CSN_369103';
9262 case 'csiso21german':
9273 case 'csiso646danish':
9280 case 'csibmebcdicatde':
9282 return 'EBCDIC-AT-DE';
9284 case 'csebcdicatdea':
9286 return 'EBCDIC-AT-DE-A';
9288 case 'csebcdiccafr':
9290 return 'EBCDIC-CA-FR';
9292 case 'csebcdicdkno':
9294 return 'EBCDIC-DK-NO';
9296 case 'csebcdicdknoa':
9298 return 'EBCDIC-DK-NO-A';
9306 return 'EBCDIC-ES-A';
9310 return 'EBCDIC-ES-S';
9312 case 'csebcdicfise':
9314 return 'EBCDIC-FI-SE';
9316 case 'csebcdicfisea':
9318 return 'EBCDIC-FI-SE-A';
9340 case 'csiso111ecmacyrillic':
9341 case 'ecmacyrillic':
9344 return 'ECMA-cyrillic';
9346 case 'csiso17spanish':
9352 case 'csiso85spanish2':
9358 case 'cseucfixwidjapanese':
9359 case 'extendedunixcodefixedwidthforjapanese':
9360 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9362 case 'cseucpkdfmtjapanese':
9364 case 'extendedunixcodepackedformatforjapanese':
9365 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9377 case 'csiso58gb231280':
9383 case 'csiso57gb1988':
9387 return 'GB_1988-80';
9389 case 'csiso153gost1976874':
9393 return 'GOST_19768-74';
9396 case 'csiso150greekccitt':
9399 return 'greek-ccitt';
9401 case 'csiso88greek7':
9406 case 'csiso18greek7old':
9409 return 'greek7-old';
9413 return 'HP-DeskTop';
9425 return 'HP-Pi-font';
9434 return 'HZ-GB-2312';
9436 case 'csibmsymbols':
9438 return 'IBM-Symbols';
9447 case 'pcmultilingual850euro':
9452 case 'ebcdiclatin9euro':
9458 case 'ebcdicus37euro':
9464 case 'ebcdicde273euro':
9470 case 'ebcdicdk277euro':
9471 case 'ebcdicno277euro':
9477 case 'ebcdicfi278euro':
9478 case 'ebcdicse278euro':
9484 case 'ebcdicit280euro':
9490 case 'ebcdices284euro':
9496 case 'ebcdicgb285euro':
9502 case 'ebcdicfr297euro':
9508 case 'ebcdicinternational500euro':
9514 case 'ebcdicis871euro':
9589 case 'ebcdicjpkana':
9619 case 'cspc8codepage437':
9631 case 'cspc775baltic':
9637 case 'cspc850multilingual':
9680 case 'cspc862latinhebrew':
9722 case 'ebcdiccproece':
9735 case 'ebcdiccyrillic':
9776 case 'csiso143iecp271':
9786 case 'csiso50inis8':
9791 case 'csiso51iniscyrillic':
9792 case 'iniscyrillic':
9794 return 'INIS-cyrillic';
9801 return 'ISO-2022-CN';
9803 case 'iso2022cnext':
9804 return 'ISO-2022-CN-EXT';
9808 return 'ISO-2022-JP';
9810 case 'csiso2022jp2':
9812 return 'ISO-2022-JP-2';
9816 return 'ISO-2022-KR';
9818 case 'cswindows30latin1':
9819 case 'iso88591windows30latin1':
9820 return 'ISO-8859-1-Windows-3.0-Latin-1';
9822 case 'cswindows31latin1':
9823 case 'iso88591windows31latin1':
9824 return 'ISO-8859-1-Windows-3.1-Latin-1';
9830 case 'iso885921987':
9833 return 'ISO-8859-2';
9835 case 'cswindows31latin2':
9836 case 'iso88592windowslatin2':
9837 return 'ISO-8859-2-Windows-Latin-2';
9843 case 'iso885931988':
9846 return 'ISO-8859-3';
9852 case 'iso885941988':
9855 return 'ISO-8859-4';
9857 case 'csisolatincyrillic':
9862 case 'iso885951988':
9863 return 'ISO-8859-5';
9867 case 'csisolatinarabic':
9872 case 'iso885961987':
9873 return 'ISO-8859-6';
9878 return 'ISO-8859-6-E';
9883 return 'ISO-8859-6-I';
9885 case 'csisolatingreek':
9893 case 'iso885971987':
9894 return 'ISO-8859-7';
9896 case 'csisolatinhebrew':
9901 case 'iso885981988':
9902 return 'ISO-8859-8';
9907 return 'ISO-8859-8-E';
9912 return 'ISO-8859-8-I';
9914 case 'cswindows31latin5':
9915 case 'iso88599windowslatin5':
9916 return 'ISO-8859-9-Windows-Latin-5';
9921 case 'iso8859101992':
9924 return 'ISO-8859-10';
9927 return 'ISO-8859-13';
9933 case 'iso8859141998':
9936 return 'ISO-8859-14';
9941 return 'ISO-8859-15';
9946 case 'iso8859162001':
9949 return 'ISO-8859-16';
9952 return 'ISO-10646-J-1';
9955 case 'iso10646ucs2':
9956 return 'ISO-10646-UCS-2';
9959 case 'iso10646ucs4':
9960 return 'ISO-10646-UCS-4';
9962 case 'csunicodeascii':
9963 case 'iso10646ucsbasic':
9964 return 'ISO-10646-UCS-Basic';
9966 case 'csunicodelatin1':
9968 case 'iso10646unicodelatin1':
9969 return 'ISO-10646-Unicode-Latin1';
9971 case 'csiso10646utf1':
9972 case 'iso10646utf1':
9973 return 'ISO-10646-UTF-1';
9979 return 'ISO-11548-1';
9985 case 'csunicodeibm1261':
9986 case 'isounicodeibm1261':
9987 return 'ISO-Unicode-IBM-1261';
9989 case 'csunicodeibm1264':
9990 case 'isounicodeibm1264':
9991 return 'ISO-Unicode-IBM-1264';
9993 case 'csunicodeibm1265':
9994 case 'isounicodeibm1265':
9995 return 'ISO-Unicode-IBM-1265';
9997 case 'csunicodeibm1268':
9998 case 'isounicodeibm1268':
9999 return 'ISO-Unicode-IBM-1268';
10001 case 'csunicodeibm1276':
10002 case 'isounicodeibm1276':
10003 return 'ISO-Unicode-IBM-1276';
10005 case 'csiso646basic1983':
10006 case 'iso646basic1983':
10008 return 'ISO_646.basic:1983';
10010 case 'csiso2intlrefversion':
10013 case 'iso646irv1983':
10014 return 'ISO_646.irv:1983';
10019 case 'iso20331983':
10020 return 'ISO_2033-1983';
10022 case 'csiso5427cyrillic':
10028 case 'iso5427cyrillic1981':
10029 case 'iso54271981':
10030 return 'ISO_5427:1981';
10032 case 'csiso5428greek':
10034 case 'iso54281980':
10035 return 'ISO_5428:1980';
10037 case 'csiso6937add':
10040 return 'ISO_6937-2-25';
10042 case 'csisotextcomm':
10044 case 'iso69372add':
10045 return 'ISO_6937-2-add';
10047 case 'csiso8859supp':
10049 case 'iso8859supp':
10051 return 'ISO_8859-supp';
10053 case 'csiso10367box':
10055 case 'iso10367box':
10056 return 'ISO_10367-box';
10058 case 'csiso15italian':
10064 case 'csiso13jisc6220jp':
10066 case 'jisc62201969':
10067 case 'jisc62201969jp':
10070 return 'JIS_C6220-1969-jp';
10072 case 'csiso14jisc6220ro':
10075 case 'jisc62201969ro':
10077 return 'JIS_C6220-1969-ro';
10079 case 'csiso42jisc62261978':
10081 case 'jisc62261978':
10082 return 'JIS_C6226-1978';
10084 case 'csiso87jisx0208':
10086 case 'jisc62261983':
10087 case 'jisx02081983':
10089 return 'JIS_C6226-1983';
10091 case 'csiso91jisc62291984a':
10093 case 'jisc62291984a':
10095 return 'JIS_C6229-1984-a';
10097 case 'csiso92jisc62991984b':
10099 case 'iso646jpocrb':
10100 case 'jisc62291984b':
10102 return 'JIS_C6229-1984-b';
10104 case 'csiso93jis62291984badd':
10106 case 'jisc62291984badd':
10108 return 'JIS_C6229-1984-b-add';
10110 case 'csiso94jis62291984hand':
10112 case 'jisc62291984hand':
10114 return 'JIS_C6229-1984-hand';
10116 case 'csiso95jis62291984handadd':
10118 case 'jisc62291984handadd':
10119 case 'jpocrhandadd':
10120 return 'JIS_C6229-1984-hand-add';
10122 case 'csiso96jisc62291984kana':
10124 case 'jisc62291984kana':
10125 return 'JIS_C6229-1984-kana';
10127 case 'csjisencoding':
10128 case 'jisencoding':
10129 return 'JIS_Encoding';
10131 case 'cshalfwidthkatakana':
10134 return 'JIS_X0201';
10136 case 'csiso159jisx02121990':
10138 case 'jisx02121990':
10140 return 'JIS_X0212-1990';
10142 case 'csiso141jusib1002':
10148 return 'JUS_I.B1.002';
10150 case 'csiso147macedonian':
10152 case 'jusib1003mac':
10154 return 'JUS_I.B1.003-mac';
10156 case 'csiso146serbian':
10158 case 'jusib1003serb':
10160 return 'JUS_I.B1.003-serb';
10162 case 'koi7switched':
10163 return 'KOI7-switched';
10180 case 'strk10482002':
10183 case 'csiso19latingreek':
10186 return 'latin-greek';
10188 case 'csiso27latingreek1':
10190 case 'latingreek1':
10191 return 'Latin-greek-1';
10193 case 'csiso158lap':
10197 return 'latin-lap';
10199 case 'csmacintosh':
10202 return 'macintosh';
10204 case 'csmicrosoftpublishing':
10205 case 'microsoftpublishing':
10206 return 'Microsoft-Publishing';
10216 case 'csiso86hungarian':
10221 return 'MSZ_7795.3';
10226 return 'NATS-DANO';
10228 case 'csnatsdanoadd':
10230 case 'natsdanoadd':
10231 return 'NATS-DANO-ADD';
10236 return 'NATS-SEFI';
10238 case 'csnatssefiadd':
10240 case 'natssefiadd':
10241 return 'NATS-SEFI-ADD';
10243 case 'csiso151cuba':
10248 return 'NC_NC00-10:81';
10250 case 'csiso69french':
10255 return 'NF_Z_62-010';
10257 case 'csiso25french':
10260 case 'nfz620101973':
10261 return 'NF_Z_62-010_(1973)';
10263 case 'csiso60danishnorwegian':
10264 case 'csiso60norwegian1':
10269 return 'NS_4551-1';
10271 case 'csiso61norwegian2':
10276 return 'NS_4551-2';
10278 case 'osdebcdicdf03irv':
10279 return 'OSD_EBCDIC_DF03_IRV';
10281 case 'osdebcdicdf041':
10282 return 'OSD_EBCDIC_DF04_1';
10284 case 'osdebcdicdf0415':
10285 return 'OSD_EBCDIC_DF04_15';
10287 case 'cspc8danishnorwegian':
10288 case 'pc8danishnorwegian':
10289 return 'PC8-Danish-Norwegian';
10291 case 'cspc8turkish':
10293 return 'PC8-Turkish';
10295 case 'csiso16portuguese':
10301 case 'csiso84portuguese2':
10309 case 'cyrillicasian':
10317 case 'csiso10swedish':
10324 return 'SEN_850200_B';
10326 case 'csiso11swedishfornames':
10331 return 'SEN_850200_C';
10336 return 'Shift_JIS';
10338 case 'csiso102t617bit':
10341 return 'T.61-7bit';
10343 case 'csiso103t618bit':
10347 return 'T.61-8bit';
10349 case 'csiso128t101g2':
10358 case 'csunicode11':
10360 return 'UNICODE-1-1';
10362 case 'csunicode11utf7':
10363 case 'unicode11utf7':
10364 return 'UNICODE-1-1-UTF-7';
10366 case 'csunknown8bit':
10367 case 'unknown8bit':
10368 return 'UNKNOWN-8BIT';
10370 case 'ansix341968':
10371 case 'ansix341986':
10378 case 'iso646irv1991':
10411 case 'csventurainternational':
10412 case 'venturainternational':
10413 return 'Ventura-International';
10415 case 'csventuramath':
10416 case 'venturamath':
10417 return 'Ventura-Math';
10419 case 'csventuraus':
10421 return 'Ventura-US';
10423 case 'csiso70videotexsupp1':
10425 case 'videotexsuppl':
10426 return 'videotex-suppl';
10436 case 'cswindows31j':
10438 return 'Windows-31J';
10442 return 'Windows-874';
10447 case 'csksc56011987':
10451 case 'ksc56011987':
10452 case 'ksc56011989':
10453 return 'Windows-949';
10455 case 'windows1250':
10456 return 'windows-1250';
10458 case 'windows1251':
10459 return 'windows-1251';
10462 case 'csisolatin1':
10466 case 'iso885911987':
10469 case 'windows1252':
10470 return 'Windows-1252';
10472 case 'windows1252':
10473 return 'windows-1252';
10475 case 'windows1253':
10476 return 'windows-1253';
10478 case 'csisolatin5':
10481 case 'iso885991989':
10484 case 'windows1254':
10485 return 'Windows-1254';
10487 case 'windows1254':
10488 return 'windows-1254';
10490 case 'windows1255':
10491 return 'windows-1255';
10493 case 'windows1256':
10494 return 'windows-1256';
10496 case 'windows1257':
10497 return 'windows-1257';
10499 case 'windows1258':
10500 return 'windows-1258';
10507 function get_curl_version()
10509 if (is_array($curl = curl_version()))
10511 $curl = $curl['version'];
10513 elseif (substr($curl, 0, 5) == 'curl/')
10515 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10517 elseif (substr($curl, 0, 8) == 'libcurl/')
10519 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10528 function is_subclass_of($class1, $class2)
10530 if (func_num_args() != 2)
10532 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10534 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10536 return is_subclass_of($class1, $class2);
10538 elseif (is_string($class1) && is_string($class2))
10540 if (class_exists($class1))
10542 if (class_exists($class2))
10544 $class2 = strtolower($class2);
10545 while ($class1 = strtolower(get_parent_class($class1)))
10547 if ($class1 == $class2)
10556 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10563 * Strip HTML comments
10566 * @param string $data Data to strip comments from
10567 * @return string Comment stripped string
10569 function strip_comments($data)
10572 while (($start = strpos($data, '<!--')) !== false)
10574 $output .= substr($data, 0, $start);
10575 if (($end = strpos($data, '-->', $start)) !== false)
10577 $data = substr_replace($data, '', 0, $end + 3);
10584 return $output . $data;
10587 function parse_date($dt)
10589 $parser = SimplePie_Parse_Date::get();
10590 return $parser->parse($dt);
10594 * Decode HTML entities
10598 * @param string $data Input data
10599 * @return string Output data
10601 function entities_decode($data)
10603 $decoder = new SimplePie_Decode_HTML_Entities($data);
10604 return $decoder->parse();
10608 * Remove RFC822 comments
10611 * @param string $data Data to strip comments from
10612 * @return string Comment stripped string
10614 function uncomment_rfc822($string)
10616 $string = (string) $string;
10618 $length = strlen($string);
10623 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10625 $output .= substr($string, $position, $pos - $position);
10626 $position = $pos + 1;
10627 if ($string[$pos - 1] !== '\\')
10630 while ($depth && $position < $length)
10632 $position += strcspn($string, '()', $position);
10633 if ($string[$position - 1] === '\\')
10638 elseif (isset($string[$position]))
10640 switch ($string[$position])
10663 $output .= substr($string, $position);
10668 function parse_mime($mime)
10670 if (($pos = strpos($mime, ';')) === false)
10672 return trim($mime);
10676 return trim(substr($mime, 0, $pos));
10680 function htmlspecialchars_decode($string, $quote_style)
10682 if (function_exists('htmlspecialchars_decode'))
10684 return htmlspecialchars_decode($string, $quote_style);
10688 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10692 function atom_03_construct_type($attribs)
10694 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10696 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10700 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10702 if (isset($attribs['']['type']))
10704 switch (strtolower(trim($attribs['']['type'])))
10708 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10712 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10715 case 'application/xhtml+xml':
10716 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10719 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10724 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10728 function atom_10_construct_type($attribs)
10730 if (isset($attribs['']['type']))
10732 switch (strtolower(trim($attribs['']['type'])))
10735 return SIMPLEPIE_CONSTRUCT_TEXT;
10738 return SIMPLEPIE_CONSTRUCT_HTML;
10741 return SIMPLEPIE_CONSTRUCT_XHTML;
10744 return SIMPLEPIE_CONSTRUCT_NONE;
10747 return SIMPLEPIE_CONSTRUCT_TEXT;
10750 function atom_10_content_construct_type($attribs)
10752 if (isset($attribs['']['type']))
10754 $type = strtolower(trim($attribs['']['type']));
10758 return SIMPLEPIE_CONSTRUCT_TEXT;
10761 return SIMPLEPIE_CONSTRUCT_HTML;
10764 return SIMPLEPIE_CONSTRUCT_XHTML;
10766 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10768 return SIMPLEPIE_CONSTRUCT_NONE;
10772 return SIMPLEPIE_CONSTRUCT_BASE64;
10777 return SIMPLEPIE_CONSTRUCT_TEXT;
10781 function is_isegment_nz_nc($string)
10783 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);
10786 function space_seperated_tokens($string)
10788 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10789 $string_length = strlen($string);
10791 $position = strspn($string, $space_characters);
10794 while ($position < $string_length)
10796 $len = strcspn($string, $space_characters, $position);
10797 $tokens[] = substr($string, $position, $len);
10799 $position += strspn($string, $space_characters, $position);
10805 function array_unique($array)
10807 if (version_compare(PHP_VERSION, '5.2', '>='))
10809 return array_unique($array);
10813 $array = (array) $array;
10814 $new_array = array();
10815 $new_array_strings = array();
10816 foreach ($array as $key => $value)
10818 if (is_object($value))
10820 if (method_exists($value, '__toString'))
10822 $cmp = $value->__toString();
10826 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10829 elseif (is_array($value))
10831 $cmp = (string) reset($value);
10835 $cmp = (string) $value;
10837 if (!in_array($cmp, $new_array_strings))
10839 $new_array[$key] = $value;
10840 $new_array_strings[] = $cmp;
10848 * Converts a unicode codepoint to a UTF-8 character
10852 * @param int $codepoint Unicode codepoint
10853 * @return string UTF-8 character
10855 function codepoint_to_utf8($codepoint)
10857 static $cache = array();
10858 $codepoint = (int) $codepoint;
10859 if (isset($cache[$codepoint]))
10861 return $cache[$codepoint];
10863 elseif ($codepoint < 0)
10865 return $cache[$codepoint] = false;
10867 else if ($codepoint <= 0x7f)
10869 return $cache[$codepoint] = chr($codepoint);
10871 else if ($codepoint <= 0x7ff)
10873 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10875 else if ($codepoint <= 0xffff)
10877 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10879 else if ($codepoint <= 0x10ffff)
10881 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10885 // U+FFFD REPLACEMENT CHARACTER
10886 return $cache[$codepoint] = "\xEF\xBF\xBD";
10891 * Re-implementation of PHP 5's stripos()
10893 * Returns the numeric position of the first occurrence of needle in the
10898 * @param object $haystack
10899 * @param string $needle Note that the needle may be a string of one or more
10900 * characters. If needle is not a string, it is converted to an integer
10901 * and applied as the ordinal value of a character.
10902 * @param int $offset The optional offset parameter allows you to specify which
10903 * character in haystack to start searching. The position returned is still
10904 * relative to the beginning of haystack.
10905 * @return bool If needle is not found, stripos() will return boolean false.
10907 function stripos($haystack, $needle, $offset = 0)
10909 if (function_exists('stripos'))
10911 return stripos($haystack, $needle, $offset);
10915 if (is_string($needle))
10917 $needle = strtolower($needle);
10919 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10921 $needle = strtolower(chr($needle));
10925 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10929 return strpos(strtolower($haystack), $needle, $offset);
10934 * Similar to parse_str()
10936 * Returns an associative array of name/value pairs, where the value is an
10937 * array of values that have used the same name
10941 * @param string $str The input string.
10944 function parse_str($str)
10947 $str = explode('&', $str);
10949 foreach ($str as $section)
10951 if (strpos($section, '=') !== false)
10953 list($name, $value) = explode('=', $section, 2);
10954 $return[urldecode($name)][] = urldecode($value);
10958 $return[urldecode($section)][] = null;
10966 * Detect XML encoding, as per XML 1.0 Appendix F.1
10968 * @todo Add support for EBCDIC
10969 * @param string $data XML data
10970 * @return array Possible encodings
10972 function xml_encoding($data)
10974 // UTF-32 Big Endian BOM
10975 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10977 $encoding[] = 'UTF-32BE';
10979 // UTF-32 Little Endian BOM
10980 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10982 $encoding[] = 'UTF-32LE';
10984 // UTF-16 Big Endian BOM
10985 elseif (substr($data, 0, 2) === "\xFE\xFF")
10987 $encoding[] = 'UTF-16BE';
10989 // UTF-16 Little Endian BOM
10990 elseif (substr($data, 0, 2) === "\xFF\xFE")
10992 $encoding[] = 'UTF-16LE';
10995 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10997 $encoding[] = 'UTF-8';
10999 // UTF-32 Big Endian Without BOM
11000 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")
11002 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11004 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11005 if ($parser->parse())
11007 $encoding[] = $parser->encoding;
11010 $encoding[] = 'UTF-32BE';
11012 // UTF-32 Little Endian Without BOM
11013 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")
11015 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11017 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11018 if ($parser->parse())
11020 $encoding[] = $parser->encoding;
11023 $encoding[] = 'UTF-32LE';
11025 // UTF-16 Big Endian Without BOM
11026 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11028 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11030 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11031 if ($parser->parse())
11033 $encoding[] = $parser->encoding;
11036 $encoding[] = 'UTF-16BE';
11038 // UTF-16 Little Endian Without BOM
11039 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11041 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11043 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11044 if ($parser->parse())
11046 $encoding[] = $parser->encoding;
11049 $encoding[] = 'UTF-16LE';
11051 // US-ASCII (or superset)
11052 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11054 if ($pos = strpos($data, "\x3F\x3E"))
11056 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11057 if ($parser->parse())
11059 $encoding[] = $parser->encoding;
11062 $encoding[] = 'UTF-8';
11064 // Fallback to UTF-8
11067 $encoding[] = 'UTF-8';
11074 * Decode HTML Entities
11076 * This implements HTML5 as of revision 967 (2007-06-28)
11078 * @package SimplePie
11080 class SimplePie_Decode_HTML_Entities
11083 * Data to be parsed
11091 * Currently consumed bytes
11096 var $consumed = '';
11099 * Position of the current byte being parsed
11107 * Create an instance of the class with the input data
11110 * @param string $data Input data
11112 function SimplePie_Decode_HTML_Entities($data)
11114 $this->data = $data;
11118 * Parse the input data
11121 * @return string Output data
11125 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11129 $this->consumed = '';
11131 return $this->data;
11135 * Consume the next byte
11138 * @return mixed The next byte, or false, if there is no more data
11142 if (isset($this->data[$this->position]))
11144 $this->consumed .= $this->data[$this->position];
11145 return $this->data[$this->position++];
11149 $this->consumed = false;
11155 * Consume a range of characters
11158 * @param string $chars Characters to consume
11159 * @return mixed A series of characters that match the range, or false
11161 function consume_range($chars)
11163 if ($len = strspn($this->data, $chars, $this->position))
11165 $data = substr($this->data, $this->position, $len);
11166 $this->consumed .= $data;
11167 $this->position += $len;
11172 $this->consumed = false;
11178 * Unconsume one byte
11182 function unconsume()
11184 $this->consumed = substr($this->consumed, 0, -1);
11195 switch ($this->consume())
11209 switch ($this->consume())
11213 $range = '0123456789ABCDEFabcdef';
11218 $range = '0123456789';
11220 $this->unconsume();
11224 if ($codepoint = $this->consume_range($range))
11226 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");
11230 $codepoint = hexdec($codepoint);
11234 $codepoint = intval($codepoint);
11237 if (isset($windows_1252_specials[$codepoint]))
11239 $replacement = $windows_1252_specials[$codepoint];
11243 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11246 if ($this->consume() != ';')
11248 $this->unconsume();
11251 $consumed_length = strlen($this->consumed);
11252 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11253 $this->position += strlen($replacement) - $consumed_length;
11258 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");
11260 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11262 $consumed = substr($this->consumed, 1);
11263 if (isset($entities[$consumed]))
11265 $match = $consumed;
11269 if ($match !== null)
11271 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11272 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11282 * @package SimplePie
11284 class SimplePie_Parse_Date
11289 * @access protected
11295 * List of days, calendar day name => ordinal day number in the week
11297 * @access protected
11360 'keskiviikko' => 3,
11384 * List of months, calendar month name => calendar month number
11386 * @access protected
11389 var $month = array(
11400 // No long form of May
11529 * List of timezones, abbreviation => offset from UTC
11531 * @access protected
11534 var $timezone = array(
11737 * Cached PCRE for SimplePie_Parse_Date::$day
11739 * @access protected
11745 * Cached PCRE for SimplePie_Parse_Date::$month
11747 * @access protected
11753 * Array of user-added callback methods
11758 var $built_in = array();
11761 * Array of user-added callback methods
11766 var $user = array();
11769 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11770 * self::month_pcre, and self::built_in
11774 function SimplePie_Parse_Date()
11776 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11777 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11780 if (!isset($cache[get_class($this)]))
11782 if (extension_loaded('Reflection'))
11784 $class = new ReflectionClass(get_class($this));
11785 $methods = $class->getMethods();
11786 $all_methods = array();
11787 foreach ($methods as $method)
11789 $all_methods[] = $method->getName();
11794 $all_methods = get_class_methods($this);
11797 foreach ($all_methods as $method)
11799 if (strtolower(substr($method, 0, 5)) === 'date_')
11801 $cache[get_class($this)][] = $method;
11806 foreach ($cache[get_class($this)] as $method)
11808 $this->built_in[] = $method;
11822 $object = new SimplePie_Parse_Date;
11832 * @param string $date Date to parse
11833 * @return int Timestamp corresponding to date string, or false on failure
11835 function parse($date)
11837 foreach ($this->user as $method)
11839 if (($returned = call_user_func($method, $date)) !== false)
11845 foreach ($this->built_in as $method)
11847 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11857 * Add a callback method to parse a date
11861 * @param callback $callback
11863 function add_callback($callback)
11865 if (is_callable($callback))
11867 $this->user[] = $callback;
11871 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11876 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11877 * well as allowing any of upper or lower case "T", horizontal tabs, or
11878 * spaces to be used as the time seperator (including more than one))
11880 * @access protected
11881 * @return int Timestamp
11883 function date_w3cdtf($date)
11888 $year = '([0-9]{4})';
11889 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11890 $decimal = '([0-9]*)';
11891 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11892 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11894 if (preg_match($pcre, $date, $match))
11897 Capturing subpatterns:
11904 7: Decimal fraction of a second
11908 11: Timezone minutes
11911 // Fill in empty matches
11912 for ($i = count($match); $i <= 3; $i++)
11917 for ($i = count($match); $i <= 7; $i++)
11922 // Numeric timezone
11923 if (isset($match[9]) && $match[9] !== '')
11925 $timezone = $match[10] * 3600;
11926 $timezone += $match[11] * 60;
11927 if ($match[9] === '-')
11929 $timezone = 0 - $timezone;
11937 // Convert the number of seconds to an integer, taking decimals into account
11938 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11940 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11949 * Remove RFC822 comments
11951 * @access protected
11952 * @param string $data Data to strip comments from
11953 * @return string Comment stripped string
11955 function remove_rfc2822_comments($string)
11957 $string = (string) $string;
11959 $length = strlen($string);
11964 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11966 $output .= substr($string, $position, $pos - $position);
11967 $position = $pos + 1;
11968 if ($string[$pos - 1] !== '\\')
11971 while ($depth && $position < $length)
11973 $position += strcspn($string, '()', $position);
11974 if ($string[$position - 1] === '\\')
11979 elseif (isset($string[$position]))
11981 switch ($string[$position])
12004 $output .= substr($string, $position);
12010 * Parse RFC2822's date format
12012 * @access protected
12013 * @return int Timestamp
12015 function date_rfc2822($date)
12020 $wsp = '[\x09\x20]';
12021 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
12022 $optional_fws = $fws . '?';
12023 $day_name = $this->day_pcre;
12024 $month = $this->month_pcre;
12025 $day = '([0-9]{1,2})';
12026 $hour = $minute = $second = '([0-9]{2})';
12027 $year = '([0-9]{2,4})';
12028 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
12029 $character_zone = '([A-Z]{1,5})';
12030 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
12031 $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';
12033 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
12036 Capturing subpatterns:
12046 10: Timezone minutes
12047 11: Alphabetic timezone
12050 // Find the month number
12051 $month = $this->month[strtolower($match[3])];
12053 // Numeric timezone
12054 if ($match[8] !== '')
12056 $timezone = $match[9] * 3600;
12057 $timezone += $match[10] * 60;
12058 if ($match[8] === '-')
12060 $timezone = 0 - $timezone;
12063 // Character timezone
12064 elseif (isset($this->timezone[strtoupper($match[11])]))
12066 $timezone = $this->timezone[strtoupper($match[11])];
12068 // Assume everything else to be -0000
12074 // Deal with 2/3 digit years
12075 if ($match[4] < 50)
12079 elseif ($match[4] < 1000)
12084 // Second is optional, if it is empty set it to zero
12085 if ($match[7] !== '')
12087 $second = $match[7];
12094 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12103 * Parse RFC850's date format
12105 * @access protected
12106 * @return int Timestamp
12108 function date_rfc850($date)
12113 $space = '[\x09\x20]+';
12114 $day_name = $this->day_pcre;
12115 $month = $this->month_pcre;
12116 $day = '([0-9]{1,2})';
12117 $year = $hour = $minute = $second = '([0-9]{2})';
12118 $zone = '([A-Z]{1,5})';
12119 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12121 if (preg_match($pcre, $date, $match))
12124 Capturing subpatterns:
12136 $month = $this->month[strtolower($match[3])];
12138 // Character timezone
12139 if (isset($this->timezone[strtoupper($match[8])]))
12141 $timezone = $this->timezone[strtoupper($match[8])];
12143 // Assume everything else to be -0000
12149 // Deal with 2 digit year
12150 if ($match[4] < 50)
12159 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12168 * Parse C99's asctime()'s date format
12170 * @access protected
12171 * @return int Timestamp
12173 function date_asctime($date)
12178 $space = '[\x09\x20]+';
12179 $wday_name = $this->day_pcre;
12180 $mon_name = $this->month_pcre;
12181 $day = '([0-9]{1,2})';
12182 $hour = $sec = $min = '([0-9]{2})';
12183 $year = '([0-9]{4})';
12184 $terminator = '\x0A?\x00?';
12185 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12187 if (preg_match($pcre, $date, $match))
12190 Capturing subpatterns:
12200 $month = $this->month[strtolower($match[2])];
12201 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12210 * Parse dates using strtotime()
12212 * @access protected
12213 * @return int Timestamp
12215 function date_strtotime($date)
12217 $strtotime = strtotime($date);
12218 if ($strtotime === -1 || $strtotime === false)
12230 * Content-type sniffing
12232 * @package SimplePie
12234 class SimplePie_Content_Type_Sniffer
12239 * @var SimplePie_File
12245 * Create an instance of the class with the input file
12248 * @param SimplePie_Content_Type_Sniffer $file Input file
12250 function SimplePie_Content_Type_Sniffer($file)
12252 $this->file = $file;
12256 * Get the Content-Type of the specified file
12259 * @return string Actual Content-Type
12261 function get_type()
12263 if (isset($this->file->headers['content-type']))
12265 if (!isset($this->file->headers['content-encoding'])
12266 && ($this->file->headers['content-type'] === 'text/plain'
12267 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12268 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12270 return $this->text_or_binary();
12273 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12275 $official = substr($this->file->headers['content-type'], 0, $pos);
12279 $official = $this->file->headers['content-type'];
12281 $official = strtolower($official);
12283 if ($official === 'unknown/unknown'
12284 || $official === 'application/unknown')
12286 return $this->unknown();
12288 elseif (substr($official, -4) === '+xml'
12289 || $official === 'text/xml'
12290 || $official === 'application/xml')
12294 elseif (substr($official, 0, 6) === 'image/')
12296 if ($return = $this->image())
12305 elseif ($official === 'text/html')
12307 return $this->feed_or_html();
12316 return $this->unknown();
12321 * Sniff text or binary
12324 * @return string Actual Content-Type
12326 function text_or_binary()
12328 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12329 || substr($this->file->body, 0, 2) === "\xFF\xFE"
12330 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12331 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12333 return 'text/plain';
12335 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12337 return 'application/octect-stream';
12341 return 'text/plain';
12349 * @return string Actual Content-Type
12353 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12354 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12355 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12356 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12358 return 'text/html';
12360 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12362 return 'application/pdf';
12364 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12366 return 'application/postscript';
12368 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12369 || substr($this->file->body, 0, 6) === 'GIF89a')
12371 return 'image/gif';
12373 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12375 return 'image/png';
12377 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12379 return 'image/jpeg';
12381 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12383 return 'image/bmp';
12387 return $this->text_or_binary();
12395 * @return string Actual Content-Type
12399 if (substr($this->file->body, 0, 6) === 'GIF87a'
12400 || substr($this->file->body, 0, 6) === 'GIF89a')
12402 return 'image/gif';
12404 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12406 return 'image/png';
12408 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12410 return 'image/jpeg';
12412 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12414 return 'image/bmp';
12426 * @return string Actual Content-Type
12428 function feed_or_html()
12430 $len = strlen($this->file->body);
12431 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12433 while ($pos < $len)
12435 switch ($this->file->body[$pos])
12441 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12449 return 'text/html';
12452 if (substr($this->file->body, $pos, 3) === '!--')
12455 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12461 return 'text/html';
12464 elseif (substr($this->file->body, $pos, 1) === '!')
12466 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12472 return 'text/html';
12475 elseif (substr($this->file->body, $pos, 1) === '?')
12477 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12483 return 'text/html';
12486 elseif (substr($this->file->body, $pos, 3) === 'rss'
12487 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12489 return 'application/rss+xml';
12491 elseif (substr($this->file->body, $pos, 4) === 'feed')
12493 return 'application/atom+xml';
12497 return 'text/html';
12501 return 'text/html';
12506 * Parses the XML Declaration
12508 * @package SimplePie
12510 class SimplePie_XML_Declaration_Parser
12518 var $version = '1.0';
12526 var $encoding = 'UTF-8';
12534 var $standalone = false;
12537 * Current state of the state machine
12542 var $state = 'before_version_name';
12553 * Input data length (to avoid calling strlen() everytime this is needed)
12558 var $data_length = 0;
12561 * Current position of the pointer
12569 * Create an instance of the class with the input data
12572 * @param string $data Input data
12574 function SimplePie_XML_Declaration_Parser($data)
12576 $this->data = $data;
12577 $this->data_length = strlen($this->data);
12581 * Parse the input data
12584 * @return bool true on success, false on failure
12588 while ($this->state && $this->state !== 'emit' && $this->has_data())
12590 $state = $this->state;
12594 if ($this->state === 'emit')
12600 $this->version = '';
12601 $this->encoding = '';
12602 $this->standalone = '';
12608 * Check whether there is data beyond the pointer
12611 * @return bool true if there is further data, false if not
12613 function has_data()
12615 return (bool) ($this->position < $this->data_length);
12619 * Advance past any whitespace
12621 * @return int Number of whitespace characters passed
12623 function skip_whitespace()
12625 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12626 $this->position += $whitespace;
12627 return $whitespace;
12633 function get_value()
12635 $quote = substr($this->data, $this->position, 1);
12636 if ($quote === '"' || $quote === "'")
12639 $len = strcspn($this->data, $quote, $this->position);
12640 if ($this->has_data())
12642 $value = substr($this->data, $this->position, $len);
12643 $this->position += $len + 1;
12650 function before_version_name()
12652 if ($this->skip_whitespace())
12654 $this->state = 'version_name';
12658 $this->state = false;
12662 function version_name()
12664 if (substr($this->data, $this->position, 7) === 'version')
12666 $this->position += 7;
12667 $this->skip_whitespace();
12668 $this->state = 'version_equals';
12672 $this->state = false;
12676 function version_equals()
12678 if (substr($this->data, $this->position, 1) === '=')
12681 $this->skip_whitespace();
12682 $this->state = 'version_value';
12686 $this->state = false;
12690 function version_value()
12692 if ($this->version = $this->get_value())
12694 $this->skip_whitespace();
12695 if ($this->has_data())
12697 $this->state = 'encoding_name';
12701 $this->state = 'emit';
12706 $this->state = 'standalone_name';
12710 function encoding_name()
12712 if (substr($this->data, $this->position, 8) === 'encoding')
12714 $this->position += 8;
12715 $this->skip_whitespace();
12716 $this->state = 'encoding_equals';
12720 $this->state = false;
12724 function encoding_equals()
12726 if (substr($this->data, $this->position, 1) === '=')
12729 $this->skip_whitespace();
12730 $this->state = 'encoding_value';
12734 $this->state = false;
12738 function encoding_value()
12740 if ($this->encoding = $this->get_value())
12742 $this->skip_whitespace();
12743 if ($this->has_data())
12745 $this->state = 'standalone_name';
12749 $this->state = 'emit';
12754 $this->state = false;
12758 function standalone_name()
12760 if (substr($this->data, $this->position, 10) === 'standalone')
12762 $this->position += 10;
12763 $this->skip_whitespace();
12764 $this->state = 'standalone_equals';
12768 $this->state = false;
12772 function standalone_equals()
12774 if (substr($this->data, $this->position, 1) === '=')
12777 $this->skip_whitespace();
12778 $this->state = 'standalone_value';
12782 $this->state = false;
12786 function standalone_value()
12788 if ($standalone = $this->get_value())
12790 switch ($standalone)
12793 $this->standalone = true;
12797 $this->standalone = false;
12801 $this->state = false;
12805 $this->skip_whitespace();
12806 if ($this->has_data())
12808 $this->state = false;
12812 $this->state = 'emit';
12817 $this->state = false;
12822 class SimplePie_Locator
12827 var $local = array();
12828 var $elsewhere = array();
12829 var $file_class = 'SimplePie_File';
12830 var $cached_entities = array();
12833 var $base_location = 0;
12834 var $checked_feeds = 0;
12835 var $max_checked_feeds = 10;
12836 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12839 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 = "")
12841 $this->file =& $file;
12842 $this->file_class = $file_class;
12843 $this->useragent = $useragent;
12844 $this->timeout = $timeout;
12845 $this->max_checked_feeds = $max_checked_feeds;
12846 $this->content_type_sniffer_class = $content_type_sniffer_class;
12847 $this->proxy = $proxy;
12850 function find($type = SIMPLEPIE_LOCATOR_ALL)
12852 if ($this->is_feed($this->file))
12854 return $this->file;
12857 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12859 $sniffer = new $this->content_type_sniffer_class($this->file);
12860 if ($sniffer->get_type() !== 'text/html')
12866 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12871 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12876 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12878 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12883 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12888 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12893 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12901 function is_feed(&$file)
12903 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12905 $sniffer = new $this->content_type_sniffer_class($file);
12906 $sniffed = $sniffer->get_type();
12907 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12916 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12926 function get_base()
12928 $this->http_base = $this->file->url;
12929 $this->base = $this->http_base;
12930 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12931 foreach ($elements as $element)
12933 if ($element['attribs']['href']['data'] !== '')
12935 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12936 $this->base_location = $element['offset'];
12942 function autodiscovery()
12944 $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));
12946 foreach ($links as $link)
12948 if ($this->checked_feeds == $this->max_checked_feeds)
12952 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12954 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12956 if ($this->base_location < $link['offset'])
12958 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12962 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12965 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'))))
12967 $this->checked_feeds++;
12968 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
12969 if ($this->is_feed($feed))
12980 function get_links()
12982 $links = SimplePie_Misc::get_element('a', $this->file->body);
12983 foreach ($links as $link)
12985 if (isset($link['attribs']['href']['data']))
12987 $href = trim($link['attribs']['href']['data']);
12988 $parsed = SimplePie_Misc::parse_url($href);
12989 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12991 if ($this->base_location < $link['offset'])
12993 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12997 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
13000 $current = SimplePie_Misc::parse_url($this->file->url);
13002 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
13004 $this->local[] = $href;
13008 $this->elsewhere[] = $href;
13013 $this->local = array_unique($this->local);
13014 $this->elsewhere = array_unique($this->elsewhere);
13015 if (!empty($this->local) || !empty($this->elsewhere))
13022 function extension(&$array)
13024 foreach ($array as $key => $value)
13026 if ($this->checked_feeds == $this->max_checked_feeds)
13030 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
13032 $this->checked_feeds++;
13033 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13034 if ($this->is_feed($feed))
13040 unset($array[$key]);
13047 function body(&$array)
13049 foreach ($array as $key => $value)
13051 if ($this->checked_feeds == $this->max_checked_feeds)
13055 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13057 $this->checked_feeds++;
13058 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13059 if ($this->is_feed($feed))
13065 unset($array[$key]);
13073 class SimplePie_Parser
13078 var $current_column;
13080 var $separator = ' ';
13082 var $namespace = array('');
13083 var $element = array('');
13084 var $xml_base = array('');
13085 var $xml_base_explicit = array(false);
13086 var $xml_lang = array('');
13087 var $data = array();
13088 var $datas = array(array());
13089 var $current_xhtml_construct = -1;
13092 function parse(&$data, $encoding)
13094 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13095 if (strtoupper($encoding) == 'US-ASCII')
13097 $this->encoding = 'UTF-8';
13101 $this->encoding = $encoding;
13105 // UTF-32 Big Endian BOM
13106 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13108 $data = substr($data, 4);
13110 // UTF-32 Little Endian BOM
13111 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13113 $data = substr($data, 4);
13115 // UTF-16 Big Endian BOM
13116 elseif (substr($data, 0, 2) === "\xFE\xFF")
13118 $data = substr($data, 2);
13120 // UTF-16 Little Endian BOM
13121 elseif (substr($data, 0, 2) === "\xFF\xFE")
13123 $data = substr($data, 2);
13126 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13128 $data = substr($data, 3);
13131 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13133 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13134 if ($declaration->parse())
13136 $data = substr($data, $pos + 2);
13137 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13141 $this->error_string = 'SimplePie bug! Please report this!';
13146 // Work around libxml bug
13147 $data = str_replace('<', '<', $data);
13148 $data = str_replace('>', '>', $data);
13149 $data = str_replace('&', '&', $data);
13150 $data = str_replace(''', ''', $data);
13151 $data = str_replace('"', '"', $data);
13155 // Create the parser
13156 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13157 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13158 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13159 xml_set_object($xml, $this);
13160 xml_set_character_data_handler($xml, 'cdata');
13161 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13164 if (!xml_parse($xml, $data, true))
13166 $this->error_code = xml_get_error_code($xml);
13167 $this->error_string = xml_error_string($this->error_code);
13170 $this->current_line = xml_get_current_line_number($xml);
13171 $this->current_column = xml_get_current_column_number($xml);
13172 $this->current_byte = xml_get_current_byte_index($xml);
13173 xml_parser_free($xml);
13177 function get_error_code()
13179 return $this->error_code;
13182 function get_error_string()
13184 return $this->error_string;
13187 function get_current_line()
13189 return $this->current_line;
13192 function get_current_column()
13194 return $this->current_column;
13197 function get_current_byte()
13199 return $this->current_byte;
13202 function get_data()
13204 return $this->data;
13207 function tag_open($parser, $tag, $attributes)
13209 if ($this->feed === 0)
13213 elseif ($this->feed == false)
13215 if (in_array($tag, array(
13216 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13217 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13219 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13230 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13232 $attribs = array();
13233 foreach ($attributes as $name => $value)
13235 list($attrib_namespace, $attribute) = $this->split_ns($name);
13236 $attribs[$attrib_namespace][$attribute] = $value;
13239 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13241 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13242 $this->xml_base_explicit[] = true;
13246 $this->xml_base[] = end($this->xml_base);
13247 $this->xml_base_explicit[] = end($this->xml_base_explicit);
13250 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13252 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13256 $this->xml_lang[] = end($this->xml_lang);
13259 if ($this->current_xhtml_construct >= 0)
13261 $this->current_xhtml_construct++;
13262 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13264 $this->data['data'] .= '<' . end($this->element);
13265 if (isset($attribs['']))
13267 foreach ($attribs[''] as $name => $value)
13269 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13272 $this->data['data'] .= '>';
13277 $this->datas[] =& $this->data;
13278 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13279 $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));
13280 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')
13281 || (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'))
13283 $this->current_xhtml_construct = 0;
13288 function cdata($parser, $cdata)
13290 if ($this->current_xhtml_construct >= 0)
13292 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13294 elseif ($this->feed > 1)
13296 $this->data['data'] .= $cdata;
13300 function tag_close($parser, $tag)
13307 if ($this->current_xhtml_construct >= 0)
13309 $this->current_xhtml_construct--;
13310 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')))
13312 $this->data['data'] .= '</' . end($this->element) . '>';
13315 if ($this->current_xhtml_construct == -1)
13317 $this->data =& $this->datas[$this->feed];
13318 array_pop($this->datas);
13321 array_pop($this->element);
13322 array_pop($this->namespace);
13323 array_pop($this->xml_base);
13324 array_pop($this->xml_base_explicit);
13325 array_pop($this->xml_lang);
13329 function split_ns($string)
13331 static $cache = array();
13332 if (!isset($cache[$string]))
13334 if ($pos = strpos($string, $this->separator))
13336 static $separator_length;
13337 if (!$separator_length)
13339 $separator_length = strlen($this->separator);
13341 $namespace = substr($string, 0, $pos);
13342 $local_name = substr($string, $pos + $separator_length);
13343 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13345 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13348 // Normalize the Media RSS namespaces
13349 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13351 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13353 $cache[$string] = array($namespace, $local_name);
13357 $cache[$string] = array('', $string);
13360 return $cache[$string];
13365 * @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
13367 class SimplePie_Sanitize
13373 var $remove_div = true;
13374 var $image_handler = '';
13375 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13376 var $encode_instead_of_strip = false;
13377 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13378 var $strip_comments = false;
13379 var $output_encoding = 'UTF-8';
13380 var $enable_cache = true;
13381 var $cache_location = './cache';
13382 var $cache_name_function = 'md5';
13383 var $cache_class = 'SimplePie_Cache';
13384 var $file_class = 'SimplePie_File';
13386 var $useragent = '';
13387 var $force_fsockopen = false;
13390 var $replace_url_attributes = array(
13393 'blockquote' => 'cite',
13395 'form' => 'action',
13396 'img' => array('longdesc', 'src'),
13402 function remove_div($enable = true)
13404 $this->remove_div = (bool) $enable;
13407 function set_image_handler($page = false)
13411 $this->image_handler = (string) $page;
13415 $this->image_handler = false;
13419 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13421 if (isset($enable_cache))
13423 $this->enable_cache = (bool) $enable_cache;
13426 if ($cache_location)
13428 $this->cache_location = (string) $cache_location;
13431 if ($cache_name_function)
13433 $this->cache_name_function = (string) $cache_name_function;
13438 $this->cache_class = (string) $cache_class;
13442 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13446 $this->file_class = (string) $file_class;
13451 $this->timeout = (string) $timeout;
13456 $this->useragent = (string) $useragent;
13459 if ($force_fsockopen)
13461 $this->force_fsockopen = (string) $force_fsockopen;
13465 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13469 if (is_array($tags))
13471 $this->strip_htmltags = $tags;
13475 $this->strip_htmltags = explode(',', $tags);
13480 $this->strip_htmltags = false;
13484 function encode_instead_of_strip($encode = false)
13486 $this->encode_instead_of_strip = (bool) $encode;
13489 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13493 if (is_array($attribs))
13495 $this->strip_attributes = $attribs;
13499 $this->strip_attributes = explode(',', $attribs);
13504 $this->strip_attributes = false;
13508 function strip_comments($strip = false)
13510 $this->strip_comments = (bool) $strip;
13513 function set_output_encoding($encoding = 'UTF-8')
13515 $this->output_encoding = (string) $encoding;
13519 * Set element/attribute key/value pairs of HTML attributes
13520 * containing URLs that need to be resolved relative to the feed
13524 * @param array $element_attribute Element/attribute key/value pairs
13526 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'))
13528 $this->replace_url_attributes = (array) $element_attribute;
13531 function sanitize($data, $type, $base = '')
13533 $data = trim($data);
13534 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13536 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13538 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))
13540 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13544 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13548 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13550 $data = base64_decode($data);
13553 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13555 if ($this->remove_div)
13557 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13558 $data = preg_replace('/<\/div>$/', '', $data);
13562 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13566 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13569 if ($this->strip_comments)
13571 $data = SimplePie_Misc::strip_comments($data);
13574 // Strip out HTML tags and attributes that might cause various security problems.
13575 // Based on recommendations by Mark Pilgrim at:
13576 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13577 if ($this->strip_htmltags)
13579 foreach ($this->strip_htmltags as $tag)
13581 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13582 while (preg_match($pcre, $data))
13584 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13589 if ($this->strip_attributes)
13591 foreach ($this->strip_attributes as $attrib)
13593 $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);
13597 // Replace relative URLs
13598 $this->base = $base;
13599 foreach ($this->replace_url_attributes as $element => $attributes)
13601 $data = $this->replace_urls($data, $element, $attributes);
13604 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13605 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13607 $images = SimplePie_Misc::get_element('img', $data);
13608 foreach ($images as $img)
13610 if (isset($img['attribs']['src']['data']))
13612 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13613 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13615 if ($cache->load())
13617 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13618 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13622 $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);
13623 $headers = $file->headers;
13625 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13627 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13629 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13630 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13634 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13642 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13643 $data = trim($data);
13646 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13648 $data = SimplePie_Misc::absolutize_url($data, $base);
13651 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13653 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13656 if ($this->output_encoding != 'UTF-8')
13658 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13664 function replace_urls($data, $tag, $attributes)
13666 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13668 $elements = SimplePie_Misc::get_element($tag, $data);
13669 foreach ($elements as $element)
13671 if (is_array($attributes))
13673 foreach ($attributes as $attribute)
13675 if (isset($element['attribs'][$attribute]['data']))
13677 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13678 $new_element = SimplePie_Misc::element_implode($element);
13679 $data = str_replace($element['full'], $new_element, $data);
13680 $element['full'] = $new_element;
13684 elseif (isset($element['attribs'][$attributes]['data']))
13686 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13687 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13694 function do_strip_htmltags($match)
13696 if ($this->encode_instead_of_strip)
13698 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13700 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13701 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13702 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13706 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13709 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))