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.
1030 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1031 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1033 function set_cache_class($class = 'SimplePie_Cache')
1035 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1037 $this->cache_class = $class;
1044 * Allows you to change which class SimplePie uses for auto-discovery.
1045 * Useful when you are overloading or extending SimplePie's default classes.
1048 * @param string $class Name of custom class.
1050 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1051 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1053 function set_locator_class($class = 'SimplePie_Locator')
1055 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1057 $this->locator_class = $class;
1064 * Allows you to change which class SimplePie uses for XML parsing.
1065 * Useful when you are overloading or extending SimplePie's default classes.
1068 * @param string $class Name of custom class.
1070 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1071 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1073 function set_parser_class($class = 'SimplePie_Parser')
1075 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1077 $this->parser_class = $class;
1084 * Allows you to change which class SimplePie uses for remote file fetching.
1085 * Useful when you are overloading or extending SimplePie's default classes.
1088 * @param string $class Name of custom class.
1090 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1091 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1093 function set_file_class($class = 'SimplePie_File')
1095 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1097 $this->file_class = $class;
1104 * Allows you to change which class SimplePie uses for data sanitization.
1105 * Useful when you are overloading or extending SimplePie's default classes.
1108 * @param string $class Name of custom class.
1110 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1111 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1113 function set_sanitize_class($class = 'SimplePie_Sanitize')
1115 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1117 $this->sanitize = new $class;
1118 $this->sanitize->proxy = $this->proxy;
1125 * Allows you to change which class SimplePie uses for handling feed items.
1126 * Useful when you are overloading or extending SimplePie's default classes.
1129 * @param string $class Name of custom class.
1131 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1132 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1134 function set_item_class($class = 'SimplePie_Item')
1136 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1138 $this->item_class = $class;
1145 * Allows you to change which class SimplePie uses for handling author data.
1146 * Useful when you are overloading or extending SimplePie's default classes.
1149 * @param string $class Name of custom class.
1151 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1152 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1154 function set_author_class($class = 'SimplePie_Author')
1156 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1158 $this->author_class = $class;
1165 * Allows you to change which class SimplePie uses for handling category data.
1166 * Useful when you are overloading or extending SimplePie's default classes.
1169 * @param string $class Name of custom class.
1171 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1172 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1174 function set_category_class($class = 'SimplePie_Category')
1176 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1178 $this->category_class = $class;
1185 * Allows you to change which class SimplePie uses for feed enclosures.
1186 * Useful when you are overloading or extending SimplePie's default classes.
1189 * @param string $class Name of custom class.
1191 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1192 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1194 function set_enclosure_class($class = 'SimplePie_Enclosure')
1196 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1198 $this->enclosure_class = $class;
1205 * Allows you to change which class SimplePie uses for <media:text> captions
1206 * Useful when you are overloading or extending SimplePie's default classes.
1209 * @param string $class Name of custom class.
1211 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1212 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1214 function set_caption_class($class = 'SimplePie_Caption')
1216 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1218 $this->caption_class = $class;
1225 * Allows you to change which class SimplePie uses for <media:copyright>
1226 * Useful when you are overloading or extending SimplePie's default classes.
1229 * @param string $class Name of custom class.
1231 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1232 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1234 function set_copyright_class($class = 'SimplePie_Copyright')
1236 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1238 $this->copyright_class = $class;
1245 * Allows you to change which class SimplePie uses for <media:credit>
1246 * Useful when you are overloading or extending SimplePie's default classes.
1249 * @param string $class Name of custom class.
1251 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1252 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1254 function set_credit_class($class = 'SimplePie_Credit')
1256 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1258 $this->credit_class = $class;
1265 * Allows you to change which class SimplePie uses for <media:rating>
1266 * Useful when you are overloading or extending SimplePie's default classes.
1269 * @param string $class Name of custom class.
1271 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1272 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1274 function set_rating_class($class = 'SimplePie_Rating')
1276 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1278 $this->rating_class = $class;
1285 * Allows you to change which class SimplePie uses for <media:restriction>
1286 * Useful when you are overloading or extending SimplePie's default classes.
1289 * @param string $class Name of custom class.
1291 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1292 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1294 function set_restriction_class($class = 'SimplePie_Restriction')
1296 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1298 $this->restriction_class = $class;
1305 * Allows you to change which class SimplePie uses for content-type sniffing.
1306 * Useful when you are overloading or extending SimplePie's default classes.
1309 * @param string $class Name of custom class.
1311 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1312 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1314 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1316 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1318 $this->content_type_sniffer_class = $class;
1325 * Allows you to change which class SimplePie uses item sources.
1326 * Useful when you are overloading or extending SimplePie's default classes.
1329 * @param string $class Name of custom class.
1331 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1332 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1334 function set_source_class($class = 'SimplePie_Source')
1336 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1338 $this->source_class = $class;
1345 * Allows you to override the default user agent string.
1348 * @param string $ua New user agent string.
1350 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1352 $this->useragent = (string) $ua;
1356 * Set callback function to create cache filename with
1359 * @param mixed $function Callback function
1361 function set_cache_name_function($function = 'md5')
1363 if (is_callable($function))
1365 $this->cache_name_function = $function;
1370 * Set javascript query string parameter
1373 * @param mixed $get Javascript query string parameter
1375 function set_javascript($get = 'js')
1379 $this->javascript = (string) $get;
1383 $this->javascript = false;
1388 * Set options to make SP as fast as possible. Forgoes a
1389 * substantial amount of data sanitization in favor of speed.
1392 * @param bool $set Whether to set them or not
1394 function set_stupidly_fast($set = false)
1398 $this->enable_order_by_date(false);
1399 $this->remove_div(false);
1400 $this->strip_comments(false);
1401 $this->strip_htmltags(false);
1402 $this->strip_attributes(false);
1403 $this->set_image_handler(false);
1408 * Set maximum number of feeds to check with autodiscovery
1411 * @param int $max Maximum number of feeds to check
1413 function set_max_checked_feeds($max = 10)
1415 $this->max_checked_feeds = (int) $max;
1418 function remove_div($enable = true)
1420 $this->sanitize->remove_div($enable);
1423 function strip_htmltags($tags = '', $encode = null)
1427 $tags = $this->strip_htmltags;
1429 $this->sanitize->strip_htmltags($tags);
1430 if ($encode !== null)
1432 $this->sanitize->encode_instead_of_strip($tags);
1436 function encode_instead_of_strip($enable = true)
1438 $this->sanitize->encode_instead_of_strip($enable);
1441 function strip_attributes($attribs = '')
1443 if ($attribs === '')
1445 $attribs = $this->strip_attributes;
1447 $this->sanitize->strip_attributes($attribs);
1450 function set_output_encoding($encoding = 'UTF-8')
1452 $this->sanitize->set_output_encoding($encoding);
1455 function strip_comments($strip = false)
1457 $this->sanitize->strip_comments($strip);
1461 * Set element/attribute key/value pairs of HTML attributes
1462 * containing URLs that need to be resolved relative to the feed
1466 * @param array $element_attribute Element/attribute key/value pairs
1468 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'))
1470 $this->sanitize->set_url_replacements($element_attribute);
1474 * Set the handler to enable the display of cached favicons.
1477 * @param str $page Web-accessible path to the handler_favicon.php file.
1478 * @param str $qs The query string that the value should be passed to.
1480 function set_favicon_handler($page = false, $qs = 'i')
1484 $this->favicon_handler = $page . '?' . $qs . '=';
1488 $this->favicon_handler = '';
1493 * Set the handler to enable the display of cached images.
1496 * @param str $page Web-accessible path to the handler_image.php file.
1497 * @param str $qs The query string that the value should be passed to.
1499 function set_image_handler($page = false, $qs = 'i')
1503 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1507 $this->image_handler = '';
1512 * Set the limit for items returned per-feed with multifeeds.
1515 * @param integer $limit The maximum number of items to return.
1517 function set_item_limit($limit = 0)
1519 $this->item_limit = (int) $limit;
1524 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1528 if (isset($_GET[$this->javascript]))
1530 if (function_exists('ob_gzhandler'))
1532 ob_start('ob_gzhandler');
1534 header('Content-type: text/javascript; charset: UTF-8');
1535 header('Cache-Control: must-revalidate');
1536 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1538 function embed_odeo(link) {
1539 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>');
1542 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1543 if (placeholder != '') {
1544 document.writeln('<embed type="'+type+'" style="cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1547 document.writeln('<embed type="'+type+'" style="cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1551 function embed_flash(bgcolor, width, height, link, loop, type) {
1552 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>');
1555 function embed_flv(width, height, link, placeholder, loop, player) {
1556 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>');
1559 function embed_wmedia(width, height, link) {
1560 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1566 // Pass whatever was set with config options over to the sanitizer.
1567 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1568 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1570 if ($this->feed_url !== null || $this->raw_data !== null)
1572 $this->data = array();
1573 $this->multifeed_objects = array();
1576 if ($this->feed_url !== null)
1578 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1579 // Decide whether to enable caching
1580 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1582 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1584 // If it's enabled and we don't want an XML dump, use the cache
1585 if ($cache && !$this->xml_dump)
1588 $this->data = $cache->load();
1589 if (!empty($this->data))
1591 // If the cache is for an outdated build of SimplePie
1592 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1595 $this->data = array();
1597 // If we've hit a collision just rerun it with caching disabled
1598 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1601 $this->data = array();
1603 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1604 elseif (isset($this->data['feed_url']))
1606 // If the autodiscovery cache is still valid use it.
1607 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1609 // Do not need to do feed autodiscovery yet.
1610 if ($this->data['feed_url'] == $this->data['url'])
1613 $this->data = array();
1617 $this->set_feed_url($this->data['feed_url']);
1618 return $this->init();
1622 // Check if the cache has been updated
1623 elseif ($cache->mtime() + $this->cache_duration < time())
1625 // If we have last-modified and/or etag set
1626 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1629 if (isset($this->data['headers']['last-modified']))
1631 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1633 if (isset($this->data['headers']['etag']))
1635 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1637 $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->proxy);
1640 if ($file->status_code == 304)
1647 $headers = $file->headers;
1656 // If the cache is still valid, just return true
1662 // If the cache is empty, delete it
1666 $this->data = array();
1669 // 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.
1672 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1674 $file =& $this->file;
1678 $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->proxy);
1681 // If the file connection has an error, set SimplePie::error to that and quit
1682 if (!$file->success)
1684 $this->error = $file->error;
1685 if (!empty($this->data))
1695 if (!$this->force_feed)
1697 // Check if the supplied URL is a feed, if it isn't, look for it.
1698 $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1699 if (!$locate->is_feed($file))
1701 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1703 if ($file = $locate->find($this->autodiscovery))
1707 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1708 if (!$cache->save($this))
1710 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1712 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1714 $this->feed_url = $file->url;
1718 $this->error = "A feed could not be found at $this->feed_url";
1719 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1726 $headers = $file->headers;
1727 $data = $file->body;
1728 $sniffer = new $this->content_type_sniffer_class($file);
1729 $sniffed = $sniffer->get_type();
1733 $data = $this->raw_data;
1736 // Set up array of possible encodings
1737 $encodings = array();
1739 // First check to see if input has been overridden.
1740 if ($this->input_encoding !== false)
1742 $encodings[] = $this->input_encoding;
1745 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1746 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1748 // RFC 3023 (only applies to sniffed content)
1749 if (isset($sniffed))
1751 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1753 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1755 $encodings[] = strtoupper($charset[1]);
1757 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1758 $encodings[] = 'UTF-8';
1760 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1762 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1764 $encodings[] = $charset[1];
1766 $encodings[] = 'US-ASCII';
1768 // Text MIME-type default
1769 elseif (substr($sniffed, 0, 5) === 'text/')
1771 $encodings[] = 'US-ASCII';
1775 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1776 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1777 $encodings[] = 'UTF-8';
1778 $encodings[] = 'ISO-8859-1';
1780 // There's no point in trying an encoding twice
1781 $encodings = array_unique($encodings);
1783 // If we want the XML, just output that with the most likely encoding and quit
1784 if ($this->xml_dump)
1786 header('Content-type: text/xml; charset=' . $encodings[0]);
1791 // Loop through each possible encoding, till we return something, or run out of possibilities
1792 foreach ($encodings as $encoding)
1794 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1795 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1797 // Create new parser
1798 $parser = new $this->parser_class();
1800 // If it's parsed fine
1801 if ($parser->parse($utf8_data, 'UTF-8'))
1803 $this->data = $parser->get_data();
1804 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1806 if (isset($headers))
1808 $this->data['headers'] = $headers;
1810 $this->data['build'] = SIMPLEPIE_BUILD;
1812 // Cache the file if caching is enabled
1813 if ($cache && !$cache->save($this))
1815 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1821 $this->error = "A feed could not be found at $this->feed_url";
1822 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1828 // We have an error, just set SimplePie::error to it and quit
1829 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1830 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1833 elseif (!empty($this->multifeed_url))
1837 $this->multifeed_objects = array();
1838 foreach ($this->multifeed_url as $url)
1842 // This keyword needs to defy coding standards for PHP4 compatibility
1843 $this->multifeed_objects[$i] = clone($this);
1847 $this->multifeed_objects[$i] = $this;
1849 $this->multifeed_objects[$i]->set_feed_url($url);
1850 $success |= $this->multifeed_objects[$i]->init();
1853 return (bool) $success;
1862 * Return the error message for the occured error
1865 * @return string Error message
1869 return $this->error;
1872 function get_encoding()
1874 return $this->sanitize->output_encoding;
1877 function handle_content_type($mime = 'text/html')
1879 if (!headers_sent())
1881 $header = "Content-type: $mime;";
1882 if ($this->get_encoding())
1884 $header .= ' charset=' . $this->get_encoding();
1888 $header .= ' charset=UTF-8';
1896 if (!isset($this->data['type']))
1898 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1899 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1901 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1903 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1905 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1907 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1909 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1910 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1911 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1912 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1916 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1917 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1918 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1919 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1921 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1924 elseif (isset($this->data['child']['']['rss']))
1926 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1927 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1929 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1932 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1933 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1935 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1938 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1942 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1949 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1953 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1957 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1961 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1968 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1971 return $this->data['type'];
1975 * Returns the URL for the favicon of the feed's website.
1977 * @todo Cache atom:icon
1981 function get_favicon()
1983 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1985 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1987 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1989 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1991 if ($this->cache && $this->favicon_handler)
1993 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1994 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1998 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
2002 $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen, $this->proxy);
2004 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
2006 $sniffer = new $this->content_type_sniffer_class($file);
2007 if (substr($sniffer->get_type(), 0, 6) === 'image/')
2009 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
2011 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
2015 trigger_error("$cache->name is not writeable", E_USER_WARNING);
2016 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2024 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2031 * @todo If we have a perm redirect we should return the new URL
2032 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2033 * @todo Also, |atom:link|@rel=self
2035 function subscribe_url()
2037 if ($this->feed_url !== null)
2039 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2047 function subscribe_feed()
2049 if ($this->feed_url !== null)
2051 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2059 function subscribe_outlook()
2061 if ($this->feed_url !== null)
2063 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2071 function subscribe_podcast()
2073 if ($this->feed_url !== null)
2075 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2083 function subscribe_itunes()
2085 if ($this->feed_url !== null)
2087 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2096 * Creates the subscribe_* methods' return data
2099 * @param string $feed_url String to prefix to the feed URL
2100 * @param string $site_url String to prefix to the site URL (and
2101 * suffix to the feed URL)
2102 * @return mixed URL if feed exists, false otherwise
2104 function subscribe_service($feed_url, $site_url = null)
2106 if ($this->subscribe_url())
2108 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2109 if ($site_url !== null && $this->get_link() !== null)
2111 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2121 function subscribe_aol()
2123 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2126 function subscribe_bloglines()
2128 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2131 function subscribe_eskobo()
2133 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2136 function subscribe_feedfeeds()
2138 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2141 function subscribe_feedster()
2143 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2146 function subscribe_google()
2148 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2151 function subscribe_gritwire()
2153 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2156 function subscribe_msn()
2158 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2161 function subscribe_netvibes()
2163 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2166 function subscribe_newsburst()
2168 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2171 function subscribe_newsgator()
2173 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2176 function subscribe_odeo()
2178 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2181 function subscribe_podnova()
2183 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2186 function subscribe_rojo()
2188 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2191 function subscribe_yahoo()
2193 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2196 function get_feed_tags($namespace, $tag)
2198 $type = $this->get_type();
2199 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2201 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2203 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2206 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2208 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2210 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2213 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2215 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2217 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2220 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2222 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2224 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2230 function get_channel_tags($namespace, $tag)
2232 $type = $this->get_type();
2233 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2235 if ($return = $this->get_feed_tags($namespace, $tag))
2240 if ($type & SIMPLEPIE_TYPE_RSS_10)
2242 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2244 if (isset($channel[0]['child'][$namespace][$tag]))
2246 return $channel[0]['child'][$namespace][$tag];
2250 if ($type & SIMPLEPIE_TYPE_RSS_090)
2252 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2254 if (isset($channel[0]['child'][$namespace][$tag]))
2256 return $channel[0]['child'][$namespace][$tag];
2260 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2262 if ($channel = $this->get_feed_tags('', 'channel'))
2264 if (isset($channel[0]['child'][$namespace][$tag]))
2266 return $channel[0]['child'][$namespace][$tag];
2273 function get_image_tags($namespace, $tag)
2275 $type = $this->get_type();
2276 if ($type & SIMPLEPIE_TYPE_RSS_10)
2278 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2280 if (isset($image[0]['child'][$namespace][$tag]))
2282 return $image[0]['child'][$namespace][$tag];
2286 if ($type & SIMPLEPIE_TYPE_RSS_090)
2288 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2290 if (isset($image[0]['child'][$namespace][$tag]))
2292 return $image[0]['child'][$namespace][$tag];
2296 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2298 if ($image = $this->get_channel_tags('', 'image'))
2300 if (isset($image[0]['child'][$namespace][$tag]))
2302 return $image[0]['child'][$namespace][$tag];
2309 function get_base($element = array())
2311 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2313 return $element['xml_base'];
2315 elseif ($this->get_link() !== null)
2317 return $this->get_link();
2321 return $this->subscribe_url();
2325 function sanitize($data, $type, $base = '')
2327 return $this->sanitize->sanitize($data, $type, $base);
2330 function get_title()
2332 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2334 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2336 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2338 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2340 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2342 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2344 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2346 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2348 elseif ($return = $this->get_channel_tags('', 'title'))
2350 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2352 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2354 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2356 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2358 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2366 function get_category($key = 0)
2368 $categories = $this->get_categories();
2369 if (isset($categories[$key]))
2371 return $categories[$key];
2379 function get_categories()
2381 $categories = array();
2383 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2388 if (isset($category['attribs']['']['term']))
2390 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2392 if (isset($category['attribs']['']['scheme']))
2394 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2396 if (isset($category['attribs']['']['label']))
2398 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2400 $categories[] = new $this->category_class($term, $scheme, $label);
2402 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2404 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2406 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2408 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2410 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2412 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2415 if (!empty($categories))
2417 return SimplePie_Misc::array_unique($categories);
2425 function get_author($key = 0)
2427 $authors = $this->get_authors();
2428 if (isset($authors[$key]))
2430 return $authors[$key];
2438 function get_authors()
2441 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2446 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2448 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2450 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2452 $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]));
2454 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2456 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2458 if ($name !== null || $email !== null || $uri !== null)
2460 $authors[] = new $this->author_class($name, $uri, $email);
2463 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2468 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2470 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2472 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2474 $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]));
2476 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2478 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2480 if ($name !== null || $email !== null || $url !== null)
2482 $authors[] = new $this->author_class($name, $url, $email);
2485 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2487 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2489 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2491 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2493 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2495 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2498 if (!empty($authors))
2500 return SimplePie_Misc::array_unique($authors);
2508 function get_contributor($key = 0)
2510 $contributors = $this->get_contributors();
2511 if (isset($contributors[$key]))
2513 return $contributors[$key];
2521 function get_contributors()
2523 $contributors = array();
2524 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2529 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2531 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2533 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2535 $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]));
2537 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2539 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2541 if ($name !== null || $email !== null || $uri !== null)
2543 $contributors[] = new $this->author_class($name, $uri, $email);
2546 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2551 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2553 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2555 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2557 $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]));
2559 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2561 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2563 if ($name !== null || $email !== null || $url !== null)
2565 $contributors[] = new $this->author_class($name, $url, $email);
2569 if (!empty($contributors))
2571 return SimplePie_Misc::array_unique($contributors);
2579 function get_link($key = 0, $rel = 'alternate')
2581 $links = $this->get_links($rel);
2582 if (isset($links[$key]))
2584 return $links[$key];
2593 * Added for parity between the parent-level and the item/entry-level.
2595 function get_permalink()
2597 return $this->get_link(0);
2600 function get_links($rel = 'alternate')
2602 if (!isset($this->data['links']))
2604 $this->data['links'] = array();
2605 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2607 foreach ($links as $link)
2609 if (isset($link['attribs']['']['href']))
2611 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2612 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2616 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2618 foreach ($links as $link)
2620 if (isset($link['attribs']['']['href']))
2622 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2623 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2628 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2630 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2632 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2634 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2636 if ($links = $this->get_channel_tags('', 'link'))
2638 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2641 $keys = array_keys($this->data['links']);
2642 foreach ($keys as $key)
2644 if (SimplePie_Misc::is_isegment_nz_nc($key))
2646 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2648 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2649 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2653 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2656 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2658 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2660 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2664 if (isset($this->data['links'][$rel]))
2666 return $this->data['links'][$rel];
2674 function get_description()
2676 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2678 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2680 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2682 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2684 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2688 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2692 elseif ($return = $this->get_channel_tags('', 'description'))
2694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2696 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2700 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2704 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2706 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2708 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2710 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2718 function get_copyright()
2720 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2722 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2724 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2726 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2728 elseif ($return = $this->get_channel_tags('', 'copyright'))
2730 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2732 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2734 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2736 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2738 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2746 function get_language()
2748 if ($return = $this->get_channel_tags('', 'language'))
2750 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2754 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2756 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2758 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2760 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2762 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2764 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2766 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2768 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2770 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2772 elseif (isset($this->data['headers']['content-language']))
2774 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2782 function get_latitude()
2784 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2786 return (float) $return[0]['data'];
2788 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2790 return (float) $match[1];
2798 function get_longitude()
2800 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2802 return (float) $return[0]['data'];
2804 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2806 return (float) $return[0]['data'];
2808 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2810 return (float) $match[2];
2818 function get_image_title()
2820 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2822 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2824 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2826 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2828 elseif ($return = $this->get_image_tags('', 'title'))
2830 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2832 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2834 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2836 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2838 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2846 function get_image_url()
2848 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2850 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2852 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2854 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2856 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2858 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2860 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2862 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2864 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2866 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2868 elseif ($return = $this->get_image_tags('', 'url'))
2870 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2878 function get_image_link()
2880 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2882 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2884 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2886 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2888 elseif ($return = $this->get_image_tags('', 'link'))
2890 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2898 function get_image_width()
2900 if ($return = $this->get_image_tags('', 'width'))
2902 return round($return[0]['data']);
2904 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2914 function get_image_height()
2916 if ($return = $this->get_image_tags('', 'height'))
2918 return round($return[0]['data']);
2920 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2930 function get_item_quantity($max = 0)
2932 $qty = count($this->get_items());
2939 return ($qty > $max) ? $max : $qty;
2943 function get_item($key = 0)
2945 $items = $this->get_items();
2946 if (isset($items[$key]))
2948 return $items[$key];
2956 function get_items($start = 0, $end = 0)
2958 if (!empty($this->multifeed_objects))
2960 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2962 elseif (!isset($this->data['items']))
2964 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
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_ATOM_03, 'entry'))
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_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2982 $keys = array_keys($items);
2983 foreach ($keys as $key)
2985 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2988 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2990 $keys = array_keys($items);
2991 foreach ($keys as $key)
2993 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2996 if ($items = $this->get_channel_tags('', 'item'))
2998 $keys = array_keys($items);
2999 foreach ($keys as $key)
3001 $this->data['items'][] = new $this->item_class($this, $items[$key]);
3006 if (!empty($this->data['items']))
3008 // If we want to order it by date, check if all items have a date, and then sort it
3009 if ($this->order_by_date)
3011 if (!isset($this->data['ordered_items']))
3014 foreach ($this->data['items'] as $item)
3016 if (!$item->get_date('U'))
3023 $this->data['ordered_items'] = $this->data['items'];
3026 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3029 $items = $this->data['ordered_items'];
3033 $items = $this->data['items'];
3036 // Slice the data as desired
3039 return array_slice($items, $start);
3043 return array_slice($items, $start, $end);
3052 function sort_items($a, $b)
3054 return $a->get_date('U') <= $b->get_date('U');
3057 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3059 if (is_array($urls) && sizeof($urls) > 0)
3062 foreach ($urls as $arg)
3064 if (is_a($arg, 'SimplePie'))
3066 $items = array_merge($items, $arg->get_items(0, $limit));
3070 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3075 foreach ($items as $item)
3077 if (!$item->get_date('U'))
3086 usort($items, array('SimplePie', 'sort_items'));
3091 return array_slice($items, $start);
3095 return array_slice($items, $start, $end);
3100 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3106 class SimplePie_Item
3109 var $data = array();
3111 function SimplePie_Item($feed, $data)
3113 $this->feed = $feed;
3114 $this->data = $data;
3117 function __toString()
3119 return md5(serialize($this->data));
3123 * Remove items that link back to this before destroying this object
3125 function __destruct()
3130 function get_item_tags($namespace, $tag)
3132 if (isset($this->data['child'][$namespace][$tag]))
3134 return $this->data['child'][$namespace][$tag];
3142 function get_base($element = array())
3144 return $this->feed->get_base($element);
3147 function sanitize($data, $type, $base = '')
3149 return $this->feed->sanitize($data, $type, $base);
3157 function get_id($hash = false)
3161 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3163 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3165 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3167 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3169 elseif ($return = $this->get_item_tags('', 'guid'))
3171 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3173 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3175 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3177 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3179 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3181 elseif (($return = $this->get_permalink()) !== null)
3185 elseif (($return = $this->get_title()) !== null)
3190 if ($this->get_permalink() !== null || $this->get_title() !== null)
3192 return md5($this->get_permalink() . $this->get_title());
3196 return md5(serialize($this->data));
3200 function get_title()
3202 if (!isset($this->data['title']))
3204 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3206 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3210 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3212 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3214 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3216 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3218 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3220 elseif ($return = $this->get_item_tags('', 'title'))
3222 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3224 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3226 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3228 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3230 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3234 $this->data['title'] = null;
3237 return $this->data['title'];
3240 function get_description($description_only = false)
3242 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3244 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3246 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3248 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3250 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3252 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3254 elseif ($return = $this->get_item_tags('', 'description'))
3256 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3258 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3260 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3262 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3264 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3266 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3268 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3270 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3272 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3274 elseif (!$description_only)
3276 return $this->get_content(true);
3284 function get_content($content_only = false)
3286 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3288 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3290 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3292 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3294 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3298 elseif (!$content_only)
3300 return $this->get_description(true);
3308 function get_category($key = 0)
3310 $categories = $this->get_categories();
3311 if (isset($categories[$key]))
3313 return $categories[$key];
3321 function get_categories()
3323 $categories = array();
3325 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3330 if (isset($category['attribs']['']['term']))
3332 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3334 if (isset($category['attribs']['']['scheme']))
3336 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3338 if (isset($category['attribs']['']['label']))
3340 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3342 $categories[] = new $this->feed->category_class($term, $scheme, $label);
3344 foreach ((array) $this->get_item_tags('', 'category') as $category)
3346 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3348 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3350 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3352 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3354 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3357 if (!empty($categories))
3359 return SimplePie_Misc::array_unique($categories);
3367 function get_author($key = 0)
3369 $authors = $this->get_authors();
3370 if (isset($authors[$key]))
3372 return $authors[$key];
3380 function get_contributor($key = 0)
3382 $contributors = $this->get_contributors();
3383 if (isset($contributors[$key]))
3385 return $contributors[$key];
3393 function get_contributors()
3395 $contributors = array();
3396 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3401 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3403 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3405 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3407 $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]));
3409 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3411 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3413 if ($name !== null || $email !== null || $uri !== null)
3415 $contributors[] = new $this->feed->author_class($name, $uri, $email);
3418 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3423 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3425 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3427 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3429 $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]));
3431 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3433 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3435 if ($name !== null || $email !== null || $url !== null)
3437 $contributors[] = new $this->feed->author_class($name, $url, $email);
3441 if (!empty($contributors))
3443 return SimplePie_Misc::array_unique($contributors);
3452 * @todo Atom inheritance (item author, source author, feed author)
3454 function get_authors()
3457 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3462 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3464 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3466 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3468 $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]));
3470 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3472 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3474 if ($name !== null || $email !== null || $uri !== null)
3476 $authors[] = new $this->feed->author_class($name, $uri, $email);
3479 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3484 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3486 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3488 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3490 $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]));
3492 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3494 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3496 if ($name !== null || $email !== null || $url !== null)
3498 $authors[] = new $this->feed->author_class($name, $url, $email);
3501 if ($author = $this->get_item_tags('', 'author'))
3503 $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3505 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3507 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3509 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3511 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3513 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3515 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3518 if (!empty($authors))
3520 return SimplePie_Misc::array_unique($authors);
3522 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3526 elseif ($authors = $this->feed->get_authors())
3536 function get_copyright()
3538 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3540 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3542 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3544 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3546 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3548 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3556 function get_date($date_format = 'j F Y, g:i a')
3558 if (!isset($this->data['date']))
3560 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3562 $this->data['date']['raw'] = $return[0]['data'];
3564 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3566 $this->data['date']['raw'] = $return[0]['data'];
3568 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3570 $this->data['date']['raw'] = $return[0]['data'];
3572 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3574 $this->data['date']['raw'] = $return[0]['data'];
3576 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3578 $this->data['date']['raw'] = $return[0]['data'];
3580 elseif ($return = $this->get_item_tags('', 'pubDate'))
3582 $this->data['date']['raw'] = $return[0]['data'];
3584 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3586 $this->data['date']['raw'] = $return[0]['data'];
3588 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3590 $this->data['date']['raw'] = $return[0]['data'];
3593 if (!empty($this->data['date']['raw']))
3595 $parser = SimplePie_Parse_Date::get();
3596 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3600 $this->data['date'] = null;
3603 if ($this->data['date'])
3605 $date_format = (string) $date_format;
3606 switch ($date_format)
3609 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3612 return $this->data['date']['parsed'];
3615 return date($date_format, $this->data['date']['parsed']);
3624 function get_local_date($date_format = '%c')
3628 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3630 elseif (($date = $this->get_date('U')) !== null)
3632 return strftime($date_format, $date);
3640 function get_permalink()
3642 $link = $this->get_link();
3643 $enclosure = $this->get_enclosure(0);
3648 elseif ($enclosure !== null)
3650 return $enclosure->get_link();
3658 function get_link($key = 0, $rel = 'alternate')
3660 $links = $this->get_links($rel);
3661 if ($links[$key] !== null)
3663 return $links[$key];
3671 function get_links($rel = 'alternate')
3673 if (!isset($this->data['links']))
3675 $this->data['links'] = array();
3676 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3678 if (isset($link['attribs']['']['href']))
3680 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3681 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3685 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3687 if (isset($link['attribs']['']['href']))
3689 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3690 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3693 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3695 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3697 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3699 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3701 if ($links = $this->get_item_tags('', 'link'))
3703 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3705 if ($links = $this->get_item_tags('', 'guid'))
3707 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3709 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3713 $keys = array_keys($this->data['links']);
3714 foreach ($keys as $key)
3716 if (SimplePie_Misc::is_isegment_nz_nc($key))
3718 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3720 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3721 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3725 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3728 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3730 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3732 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3735 if (isset($this->data['links'][$rel]))
3737 return $this->data['links'][$rel];
3746 * @todo Add ability to prefer one type of content over another (in a media group).
3748 function get_enclosure($key = 0, $prefer = null)
3750 $enclosures = $this->get_enclosures();
3751 if (isset($enclosures[$key]))
3753 return $enclosures[$key];
3762 * Grabs all available enclosures (podcasts, etc.)
3764 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3766 * 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.
3768 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3769 * @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).
3771 function get_enclosures()
3773 if (!isset($this->data['enclosures']))
3775 $this->data['enclosures'] = array();
3778 $captions_parent = null;
3779 $categories_parent = null;
3780 $copyrights_parent = null;
3781 $credits_parent = null;
3782 $description_parent = null;
3783 $duration_parent = null;
3784 $hashes_parent = null;
3785 $keywords_parent = null;
3786 $player_parent = null;
3787 $ratings_parent = null;
3788 $restrictions_parent = null;
3789 $thumbnails_parent = null;
3790 $title_parent = null;
3792 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3793 $parent = $this->get_feed();
3796 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3798 foreach ($captions as $caption)
3800 $caption_type = null;
3801 $caption_lang = null;
3802 $caption_startTime = null;
3803 $caption_endTime = null;
3804 $caption_text = null;
3805 if (isset($caption['attribs']['']['type']))
3807 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3809 if (isset($caption['attribs']['']['lang']))
3811 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3813 if (isset($caption['attribs']['']['start']))
3815 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3817 if (isset($caption['attribs']['']['end']))
3819 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3821 if (isset($caption['data']))
3823 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3825 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3828 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3830 foreach ($captions as $caption)
3832 $caption_type = null;
3833 $caption_lang = null;
3834 $caption_startTime = null;
3835 $caption_endTime = null;
3836 $caption_text = null;
3837 if (isset($caption['attribs']['']['type']))
3839 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3841 if (isset($caption['attribs']['']['lang']))
3843 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3845 if (isset($caption['attribs']['']['start']))
3847 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3849 if (isset($caption['attribs']['']['end']))
3851 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3853 if (isset($caption['data']))
3855 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3857 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3860 if (is_array($captions_parent))
3862 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3866 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3871 if (isset($category['data']))
3873 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3875 if (isset($category['attribs']['']['scheme']))
3877 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3881 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3883 if (isset($category['attribs']['']['label']))
3885 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3887 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3889 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3894 if (isset($category['data']))
3896 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3898 if (isset($category['attribs']['']['scheme']))
3900 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3904 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3906 if (isset($category['attribs']['']['label']))
3908 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3910 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3912 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3915 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3917 if (isset($category['attribs']['']['text']))
3919 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3921 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3923 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3925 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3927 if (isset($subcategory['attribs']['']['text']))
3929 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3931 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3935 if (is_array($categories_parent))
3937 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3941 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3943 $copyright_url = null;
3944 $copyright_label = null;
3945 if (isset($copyright[0]['attribs']['']['url']))
3947 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3949 if (isset($copyright[0]['data']))
3951 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3953 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3955 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3957 $copyright_url = null;
3958 $copyright_label = null;
3959 if (isset($copyright[0]['attribs']['']['url']))
3961 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3963 if (isset($copyright[0]['data']))
3965 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3967 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3971 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3973 foreach ($credits as $credit)
3975 $credit_role = null;
3976 $credit_scheme = null;
3977 $credit_name = null;
3978 if (isset($credit['attribs']['']['role']))
3980 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3982 if (isset($credit['attribs']['']['scheme']))
3984 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3988 $credit_scheme = 'urn:ebu';
3990 if (isset($credit['data']))
3992 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3994 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3997 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3999 foreach ($credits as $credit)
4001 $credit_role = null;
4002 $credit_scheme = null;
4003 $credit_name = null;
4004 if (isset($credit['attribs']['']['role']))
4006 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4008 if (isset($credit['attribs']['']['scheme']))
4010 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4014 $credit_scheme = 'urn:ebu';
4016 if (isset($credit['data']))
4018 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4020 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4023 if (is_array($credits_parent))
4025 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4029 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4031 if (isset($description_parent[0]['data']))
4033 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4036 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4038 if (isset($description_parent[0]['data']))
4040 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4045 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4050 if (isset($duration_parent[0]['data']))
4052 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4053 if (sizeof($temp) > 0)
4055 (int) $seconds = array_pop($temp);
4057 if (sizeof($temp) > 0)
4059 (int) $minutes = array_pop($temp);
4060 $seconds += $minutes * 60;
4062 if (sizeof($temp) > 0)
4064 (int) $hours = array_pop($temp);
4065 $seconds += $hours * 3600;
4068 $duration_parent = $seconds;
4073 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4075 foreach ($hashes_iterator as $hash)
4079 if (isset($hash['data']))
4081 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4083 if (isset($hash['attribs']['']['algo']))
4085 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4091 $hashes_parent[] = $algo.':'.$value;
4094 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4096 foreach ($hashes_iterator as $hash)
4100 if (isset($hash['data']))
4102 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4104 if (isset($hash['attribs']['']['algo']))
4106 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4112 $hashes_parent[] = $algo.':'.$value;
4115 if (is_array($hashes_parent))
4117 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4121 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4123 if (isset($keywords[0]['data']))
4125 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4126 foreach ($temp as $word)
4128 $keywords_parent[] = trim($word);
4133 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4135 if (isset($keywords[0]['data']))
4137 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4138 foreach ($temp as $word)
4140 $keywords_parent[] = trim($word);
4145 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4147 if (isset($keywords[0]['data']))
4149 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4150 foreach ($temp as $word)
4152 $keywords_parent[] = trim($word);
4157 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4159 if (isset($keywords[0]['data']))
4161 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4162 foreach ($temp as $word)
4164 $keywords_parent[] = trim($word);
4169 if (is_array($keywords_parent))
4171 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4175 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4177 if (isset($player_parent[0]['attribs']['']['url']))
4179 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4182 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4184 if (isset($player_parent[0]['attribs']['']['url']))
4186 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4191 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4193 foreach ($ratings as $rating)
4195 $rating_scheme = null;
4196 $rating_value = null;
4197 if (isset($rating['attribs']['']['scheme']))
4199 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4203 $rating_scheme = 'urn:simple';
4205 if (isset($rating['data']))
4207 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4209 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4212 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4214 foreach ($ratings as $rating)
4216 $rating_scheme = 'urn:itunes';
4217 $rating_value = null;
4218 if (isset($rating['data']))
4220 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4222 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4225 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4227 foreach ($ratings as $rating)
4229 $rating_scheme = null;
4230 $rating_value = null;
4231 if (isset($rating['attribs']['']['scheme']))
4233 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4237 $rating_scheme = 'urn:simple';
4239 if (isset($rating['data']))
4241 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4243 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4246 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4248 foreach ($ratings as $rating)
4250 $rating_scheme = 'urn:itunes';
4251 $rating_value = null;
4252 if (isset($rating['data']))
4254 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4256 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4259 if (is_array($ratings_parent))
4261 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4265 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4267 foreach ($restrictions as $restriction)
4269 $restriction_relationship = null;
4270 $restriction_type = null;
4271 $restriction_value = null;
4272 if (isset($restriction['attribs']['']['relationship']))
4274 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4276 if (isset($restriction['attribs']['']['type']))
4278 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4280 if (isset($restriction['data']))
4282 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4284 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4287 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4289 foreach ($restrictions as $restriction)
4291 $restriction_relationship = 'allow';
4292 $restriction_type = null;
4293 $restriction_value = 'itunes';
4294 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4296 $restriction_relationship = 'deny';
4298 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4301 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4303 foreach ($restrictions as $restriction)
4305 $restriction_relationship = null;
4306 $restriction_type = null;
4307 $restriction_value = null;
4308 if (isset($restriction['attribs']['']['relationship']))
4310 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4312 if (isset($restriction['attribs']['']['type']))
4314 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4316 if (isset($restriction['data']))
4318 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4320 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4323 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4325 foreach ($restrictions as $restriction)
4327 $restriction_relationship = 'allow';
4328 $restriction_type = null;
4329 $restriction_value = 'itunes';
4330 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4332 $restriction_relationship = 'deny';
4334 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4337 if (is_array($restrictions_parent))
4339 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4343 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4345 foreach ($thumbnails as $thumbnail)
4347 if (isset($thumbnail['attribs']['']['url']))
4349 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4353 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4355 foreach ($thumbnails as $thumbnail)
4357 if (isset($thumbnail['attribs']['']['url']))
4359 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4365 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4367 if (isset($title_parent[0]['data']))
4369 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4372 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4374 if (isset($title_parent[0]['data']))
4376 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4394 $samplingrate = null;
4404 $description = null;
4409 $restrictions = null;
4413 // If we have media:group tags, loop through them.
4414 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4416 // If we have media:content tags, loop through them.
4417 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4419 if (isset($content['attribs']['']['url']))
4432 $samplingrate = null;
4442 $description = null;
4447 $restrictions = null;
4451 // Start checking the attributes of media:content
4452 if (isset($content['attribs']['']['bitrate']))
4454 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4456 if (isset($content['attribs']['']['channels']))
4458 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4460 if (isset($content['attribs']['']['duration']))
4462 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4466 $duration = $duration_parent;
4468 if (isset($content['attribs']['']['expression']))
4470 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4472 if (isset($content['attribs']['']['framerate']))
4474 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4476 if (isset($content['attribs']['']['height']))
4478 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4480 if (isset($content['attribs']['']['lang']))
4482 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4484 if (isset($content['attribs']['']['fileSize']))
4486 $length = ceil($content['attribs']['']['fileSize']);
4488 if (isset($content['attribs']['']['medium']))
4490 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4492 if (isset($content['attribs']['']['samplingrate']))
4494 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4496 if (isset($content['attribs']['']['type']))
4498 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4500 if (isset($content['attribs']['']['width']))
4502 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4504 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4506 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4509 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4511 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4513 $caption_type = null;
4514 $caption_lang = null;
4515 $caption_startTime = null;
4516 $caption_endTime = null;
4517 $caption_text = null;
4518 if (isset($caption['attribs']['']['type']))
4520 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4522 if (isset($caption['attribs']['']['lang']))
4524 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4526 if (isset($caption['attribs']['']['start']))
4528 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4530 if (isset($caption['attribs']['']['end']))
4532 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4534 if (isset($caption['data']))
4536 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4538 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4540 if (is_array($captions))
4542 $captions = array_values(SimplePie_Misc::array_unique($captions));
4545 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4547 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4549 $caption_type = null;
4550 $caption_lang = null;
4551 $caption_startTime = null;
4552 $caption_endTime = null;
4553 $caption_text = null;
4554 if (isset($caption['attribs']['']['type']))
4556 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4558 if (isset($caption['attribs']['']['lang']))
4560 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4562 if (isset($caption['attribs']['']['start']))
4564 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4566 if (isset($caption['attribs']['']['end']))
4568 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4570 if (isset($caption['data']))
4572 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4574 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4576 if (is_array($captions))
4578 $captions = array_values(SimplePie_Misc::array_unique($captions));
4583 $captions = $captions_parent;
4587 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4589 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4594 if (isset($category['data']))
4596 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4598 if (isset($category['attribs']['']['scheme']))
4600 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4604 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4606 if (isset($category['attribs']['']['label']))
4608 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4610 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4613 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4615 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4620 if (isset($category['data']))
4622 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4624 if (isset($category['attribs']['']['scheme']))
4626 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4630 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4632 if (isset($category['attribs']['']['label']))
4634 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4636 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4639 if (is_array($categories) && is_array($categories_parent))
4641 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4643 elseif (is_array($categories))
4645 $categories = array_values(SimplePie_Misc::array_unique($categories));
4647 elseif (is_array($categories_parent))
4649 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4653 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4655 $copyright_url = null;
4656 $copyright_label = null;
4657 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4659 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4661 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4663 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4665 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4667 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4669 $copyright_url = null;
4670 $copyright_label = null;
4671 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4673 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4675 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4677 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4679 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4683 $copyrights = $copyrights_parent;
4687 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4689 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4691 $credit_role = null;
4692 $credit_scheme = null;
4693 $credit_name = null;
4694 if (isset($credit['attribs']['']['role']))
4696 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4698 if (isset($credit['attribs']['']['scheme']))
4700 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4704 $credit_scheme = 'urn:ebu';
4706 if (isset($credit['data']))
4708 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4710 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4712 if (is_array($credits))
4714 $credits = array_values(SimplePie_Misc::array_unique($credits));
4717 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4719 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4721 $credit_role = null;
4722 $credit_scheme = null;
4723 $credit_name = null;
4724 if (isset($credit['attribs']['']['role']))
4726 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4728 if (isset($credit['attribs']['']['scheme']))
4730 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4734 $credit_scheme = 'urn:ebu';
4736 if (isset($credit['data']))
4738 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4740 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4742 if (is_array($credits))
4744 $credits = array_values(SimplePie_Misc::array_unique($credits));
4749 $credits = $credits_parent;
4753 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4755 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4757 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4759 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4763 $description = $description_parent;
4767 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4769 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4773 if (isset($hash['data']))
4775 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4777 if (isset($hash['attribs']['']['algo']))
4779 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4785 $hashes[] = $algo.':'.$value;
4787 if (is_array($hashes))
4789 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4792 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4794 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4798 if (isset($hash['data']))
4800 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4802 if (isset($hash['attribs']['']['algo']))
4804 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4810 $hashes[] = $algo.':'.$value;
4812 if (is_array($hashes))
4814 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4819 $hashes = $hashes_parent;
4823 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4825 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4827 $temp = explode(',', $this->sanitize($content['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));
4839 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4841 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4843 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4844 foreach ($temp as $word)
4846 $keywords[] = trim($word);
4850 if (is_array($keywords))
4852 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4857 $keywords = $keywords_parent;
4861 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4863 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4865 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4867 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4871 $player = $player_parent;
4875 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4877 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4879 $rating_scheme = null;
4880 $rating_value = null;
4881 if (isset($rating['attribs']['']['scheme']))
4883 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4887 $rating_scheme = 'urn:simple';
4889 if (isset($rating['data']))
4891 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4893 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4895 if (is_array($ratings))
4897 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4900 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4902 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4904 $rating_scheme = null;
4905 $rating_value = null;
4906 if (isset($rating['attribs']['']['scheme']))
4908 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4912 $rating_scheme = 'urn:simple';
4914 if (isset($rating['data']))
4916 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4918 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4920 if (is_array($ratings))
4922 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4927 $ratings = $ratings_parent;
4931 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4933 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4935 $restriction_relationship = null;
4936 $restriction_type = null;
4937 $restriction_value = null;
4938 if (isset($restriction['attribs']['']['relationship']))
4940 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4942 if (isset($restriction['attribs']['']['type']))
4944 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4946 if (isset($restriction['data']))
4948 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4950 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4952 if (is_array($restrictions))
4954 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4957 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4959 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4961 $restriction_relationship = null;
4962 $restriction_type = null;
4963 $restriction_value = null;
4964 if (isset($restriction['attribs']['']['relationship']))
4966 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4968 if (isset($restriction['attribs']['']['type']))
4970 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4972 if (isset($restriction['data']))
4974 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4976 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4978 if (is_array($restrictions))
4980 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4985 $restrictions = $restrictions_parent;
4989 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4991 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4993 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4995 if (is_array($thumbnails))
4997 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5000 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5002 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5004 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5006 if (is_array($thumbnails))
5008 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5013 $thumbnails = $thumbnails_parent;
5017 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5019 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5021 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5023 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5027 $title = $title_parent;
5030 $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);
5035 // If we have standalone media:content tags, loop through them.
5036 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5038 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5040 if (isset($content['attribs']['']['url']))
5053 $samplingrate = null;
5063 $description = null;
5068 $restrictions = null;
5072 // Start checking the attributes of media:content
5073 if (isset($content['attribs']['']['bitrate']))
5075 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5077 if (isset($content['attribs']['']['channels']))
5079 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5081 if (isset($content['attribs']['']['duration']))
5083 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5087 $duration = $duration_parent;
5089 if (isset($content['attribs']['']['expression']))
5091 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5093 if (isset($content['attribs']['']['framerate']))
5095 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5097 if (isset($content['attribs']['']['height']))
5099 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5101 if (isset($content['attribs']['']['lang']))
5103 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5105 if (isset($content['attribs']['']['fileSize']))
5107 $length = ceil($content['attribs']['']['fileSize']);
5109 if (isset($content['attribs']['']['medium']))
5111 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5113 if (isset($content['attribs']['']['samplingrate']))
5115 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5117 if (isset($content['attribs']['']['type']))
5119 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5121 if (isset($content['attribs']['']['width']))
5123 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5125 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5127 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5130 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5132 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5134 $caption_type = null;
5135 $caption_lang = null;
5136 $caption_startTime = null;
5137 $caption_endTime = null;
5138 $caption_text = null;
5139 if (isset($caption['attribs']['']['type']))
5141 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5143 if (isset($caption['attribs']['']['lang']))
5145 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5147 if (isset($caption['attribs']['']['start']))
5149 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5151 if (isset($caption['attribs']['']['end']))
5153 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5155 if (isset($caption['data']))
5157 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5159 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5161 if (is_array($captions))
5163 $captions = array_values(SimplePie_Misc::array_unique($captions));
5168 $captions = $captions_parent;
5172 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5174 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5179 if (isset($category['data']))
5181 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5183 if (isset($category['attribs']['']['scheme']))
5185 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5189 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5191 if (isset($category['attribs']['']['label']))
5193 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5195 $categories[] = new $this->feed->category_class($term, $scheme, $label);
5198 if (is_array($categories) && is_array($categories_parent))
5200 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5202 elseif (is_array($categories))
5204 $categories = array_values(SimplePie_Misc::array_unique($categories));
5206 elseif (is_array($categories_parent))
5208 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5216 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5218 $copyright_url = null;
5219 $copyright_label = null;
5220 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5222 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5224 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5226 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5228 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
5232 $copyrights = $copyrights_parent;
5236 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5238 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5240 $credit_role = null;
5241 $credit_scheme = null;
5242 $credit_name = null;
5243 if (isset($credit['attribs']['']['role']))
5245 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5247 if (isset($credit['attribs']['']['scheme']))
5249 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5253 $credit_scheme = 'urn:ebu';
5255 if (isset($credit['data']))
5257 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5259 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5261 if (is_array($credits))
5263 $credits = array_values(SimplePie_Misc::array_unique($credits));
5268 $credits = $credits_parent;
5272 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5274 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5278 $description = $description_parent;
5282 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5284 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5288 if (isset($hash['data']))
5290 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5292 if (isset($hash['attribs']['']['algo']))
5294 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5300 $hashes[] = $algo.':'.$value;
5302 if (is_array($hashes))
5304 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5309 $hashes = $hashes_parent;
5313 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5315 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5317 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5318 foreach ($temp as $word)
5320 $keywords[] = trim($word);
5324 if (is_array($keywords))
5326 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5331 $keywords = $keywords_parent;
5335 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5337 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5341 $player = $player_parent;
5345 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5347 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5349 $rating_scheme = null;
5350 $rating_value = null;
5351 if (isset($rating['attribs']['']['scheme']))
5353 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5357 $rating_scheme = 'urn:simple';
5359 if (isset($rating['data']))
5361 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5363 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
5365 if (is_array($ratings))
5367 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5372 $ratings = $ratings_parent;
5376 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5378 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5380 $restriction_relationship = null;
5381 $restriction_type = null;
5382 $restriction_value = null;
5383 if (isset($restriction['attribs']['']['relationship']))
5385 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5387 if (isset($restriction['attribs']['']['type']))
5389 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5391 if (isset($restriction['data']))
5393 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5395 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5397 if (is_array($restrictions))
5399 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5404 $restrictions = $restrictions_parent;
5408 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5410 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5412 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5414 if (is_array($thumbnails))
5416 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5421 $thumbnails = $thumbnails_parent;
5425 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5427 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5431 $title = $title_parent;
5434 $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);
5439 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5441 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5454 $samplingrate = null;
5459 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5460 if (isset($link['attribs']['']['type']))
5462 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5464 if (isset($link['attribs']['']['length']))
5466 $length = ceil($link['attribs']['']['length']);
5469 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5470 $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);
5474 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5476 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5489 $samplingrate = null;
5494 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5495 if (isset($link['attribs']['']['type']))
5497 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5499 if (isset($link['attribs']['']['length']))
5501 $length = ceil($link['attribs']['']['length']);
5504 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5505 $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);
5509 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5511 if (isset($enclosure[0]['attribs']['']['url']))
5524 $samplingrate = null;
5529 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5530 if (isset($enclosure[0]['attribs']['']['type']))
5532 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5534 if (isset($enclosure[0]['attribs']['']['length']))
5536 $length = ceil($enclosure[0]['attribs']['']['length']);
5539 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5540 $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);
5544 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))
5546 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5547 $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);
5550 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5552 if (!empty($this->data['enclosures']))
5554 return $this->data['enclosures'];
5562 function get_latitude()
5564 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5566 return (float) $return[0]['data'];
5568 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5570 return (float) $match[1];
5578 function get_longitude()
5580 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5582 return (float) $return[0]['data'];
5584 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5586 return (float) $return[0]['data'];
5588 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5590 return (float) $match[2];
5598 function get_source()
5600 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5602 return new $this->feed->source_class($this, $return[0]);
5611 * Creates the add_to_* methods' return data
5614 * @param string $item_url String to prefix to the item permalink
5615 * @param string $title_url String to prefix to the item title
5616 * (and suffix to the item permalink)
5617 * @return mixed URL if feed exists, false otherwise
5619 function add_to_service($item_url, $title_url = null, $summary_url = null)
5621 if ($this->get_permalink() !== null)
5623 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5624 if ($title_url !== null && $this->get_title() !== null)
5626 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5628 if ($summary_url !== null && $this->get_description() !== null)
5630 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5640 function add_to_blinklist()
5642 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5645 function add_to_blogmarks()
5647 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5650 function add_to_delicious()
5652 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5655 function add_to_digg()
5657 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5660 function add_to_furl()
5662 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5665 function add_to_magnolia()
5667 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5670 function add_to_myweb20()
5672 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5675 function add_to_newsvine()
5677 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5680 function add_to_reddit()
5682 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5685 function add_to_segnalo()
5687 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5690 function add_to_simpy()
5692 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5695 function add_to_spurl()
5697 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5700 function add_to_wists()
5702 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5705 function search_technorati()
5707 return $this->add_to_service('http://www.technorati.com/search/');
5711 class SimplePie_Source
5714 var $data = array();
5716 function SimplePie_Source($item, $data)
5718 $this->item = $item;
5719 $this->data = $data;
5722 function __toString()
5724 return md5(serialize($this->data));
5728 * Remove items that link back to this before destroying this object
5730 function __destruct()
5735 function get_source_tags($namespace, $tag)
5737 if (isset($this->data['child'][$namespace][$tag]))
5739 return $this->data['child'][$namespace][$tag];
5747 function get_base($element = array())
5749 return $this->item->get_base($element);
5752 function sanitize($data, $type, $base = '')
5754 return $this->item->sanitize($data, $type, $base);
5762 function get_title()
5764 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5766 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5768 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5770 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5772 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5774 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5776 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5778 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5780 elseif ($return = $this->get_source_tags('', 'title'))
5782 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5784 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5786 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5788 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5790 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5798 function get_category($key = 0)
5800 $categories = $this->get_categories();
5801 if (isset($categories[$key]))
5803 return $categories[$key];
5811 function get_categories()
5813 $categories = array();
5815 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5820 if (isset($category['attribs']['']['term']))
5822 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5824 if (isset($category['attribs']['']['scheme']))
5826 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5828 if (isset($category['attribs']['']['label']))
5830 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5832 $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
5834 foreach ((array) $this->get_source_tags('', 'category') as $category)
5836 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5838 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5840 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5842 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5844 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5847 if (!empty($categories))
5849 return SimplePie_Misc::array_unique($categories);
5857 function get_author($key = 0)
5859 $authors = $this->get_authors();
5860 if (isset($authors[$key]))
5862 return $authors[$key];
5870 function get_authors()
5873 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5878 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5880 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5882 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5884 $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]));
5886 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5888 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5890 if ($name !== null || $email !== null || $uri !== null)
5892 $authors[] = new $this->item->feed->author_class($name, $uri, $email);
5895 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5900 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5902 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5904 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5906 $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]));
5908 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5910 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5912 if ($name !== null || $email !== null || $url !== null)
5914 $authors[] = new $this->item->feed->author_class($name, $url, $email);
5917 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5919 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5921 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5923 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5925 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5927 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5930 if (!empty($authors))
5932 return SimplePie_Misc::array_unique($authors);
5940 function get_contributor($key = 0)
5942 $contributors = $this->get_contributors();
5943 if (isset($contributors[$key]))
5945 return $contributors[$key];
5953 function get_contributors()
5955 $contributors = array();
5956 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5961 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5963 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5965 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5967 $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]));
5969 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5971 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5973 if ($name !== null || $email !== null || $uri !== null)
5975 $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
5978 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5983 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5985 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5987 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5989 $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]));
5991 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5993 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5995 if ($name !== null || $email !== null || $url !== null)
5997 $contributors[] = new $this->item->feed->author_class($name, $url, $email);
6001 if (!empty($contributors))
6003 return SimplePie_Misc::array_unique($contributors);
6011 function get_link($key = 0, $rel = 'alternate')
6013 $links = $this->get_links($rel);
6014 if (isset($links[$key]))
6016 return $links[$key];
6025 * Added for parity between the parent-level and the item/entry-level.
6027 function get_permalink()
6029 return $this->get_link(0);
6032 function get_links($rel = 'alternate')
6034 if (!isset($this->data['links']))
6036 $this->data['links'] = array();
6037 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6039 foreach ($links as $link)
6041 if (isset($link['attribs']['']['href']))
6043 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6044 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6048 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6050 foreach ($links as $link)
6052 if (isset($link['attribs']['']['href']))
6054 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6055 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6060 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6062 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6064 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6066 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6068 if ($links = $this->get_source_tags('', 'link'))
6070 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6073 $keys = array_keys($this->data['links']);
6074 foreach ($keys as $key)
6076 if (SimplePie_Misc::is_isegment_nz_nc($key))
6078 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6080 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6081 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6085 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6088 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6090 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6092 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6096 if (isset($this->data['links'][$rel]))
6098 return $this->data['links'][$rel];
6106 function get_description()
6108 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6110 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6112 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6114 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6116 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6118 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6120 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6122 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6124 elseif ($return = $this->get_source_tags('', 'description'))
6126 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6128 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6130 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6132 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6134 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6136 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6138 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6140 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6142 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6150 function get_copyright()
6152 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6154 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6156 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6158 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6160 elseif ($return = $this->get_source_tags('', 'copyright'))
6162 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6164 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6166 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6168 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6170 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6178 function get_language()
6180 if ($return = $this->get_source_tags('', 'language'))
6182 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6184 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6186 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6188 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6190 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6192 elseif (isset($this->data['xml_lang']))
6194 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6202 function get_latitude()
6204 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6206 return (float) $return[0]['data'];
6208 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6210 return (float) $match[1];
6218 function get_longitude()
6220 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6222 return (float) $return[0]['data'];
6224 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6226 return (float) $return[0]['data'];
6228 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6230 return (float) $match[2];
6238 function get_image_url()
6240 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6242 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6244 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6246 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6248 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6250 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6259 class SimplePie_Author
6265 // Constructor, used to input the data
6266 function SimplePie_Author($name = null, $link = null, $email = null)
6268 $this->name = $name;
6269 $this->link = $link;
6270 $this->email = $email;
6273 function __toString()
6275 // There is no $this->data here
6276 return md5(serialize($this));
6281 if ($this->name !== null)
6293 if ($this->link !== null)
6303 function get_email()
6305 if ($this->email !== null)
6307 return $this->email;
6316 class SimplePie_Category
6322 // Constructor, used to input the data
6323 function SimplePie_Category($term = null, $scheme = null, $label = null)
6325 $this->term = $term;
6326 $this->scheme = $scheme;
6327 $this->label = $label;
6330 function __toString()
6332 // There is no $this->data here
6333 return md5(serialize($this));
6338 if ($this->term !== null)
6348 function get_scheme()
6350 if ($this->scheme !== null)
6352 return $this->scheme;
6360 function get_label()
6362 if ($this->label !== null)
6364 return $this->label;
6368 return $this->get_term();
6373 class SimplePie_Enclosure
6403 // Constructor, used to input the data
6404 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)
6406 $this->bitrate = $bitrate;
6407 $this->captions = $captions;
6408 $this->categories = $categories;
6409 $this->channels = $channels;
6410 $this->copyright = $copyright;
6411 $this->credits = $credits;
6412 $this->description = $description;
6413 $this->duration = $duration;
6414 $this->expression = $expression;
6415 $this->framerate = $framerate;
6416 $this->hashes = $hashes;
6417 $this->height = $height;
6418 $this->javascript = $javascript;
6419 $this->keywords = $keywords;
6420 $this->lang = $lang;
6421 $this->length = $length;
6422 $this->link = $link;
6423 $this->medium = $medium;
6424 $this->player = $player;
6425 $this->ratings = $ratings;
6426 $this->restrictions = $restrictions;
6427 $this->samplingrate = $samplingrate;
6428 $this->thumbnails = $thumbnails;
6429 $this->title = $title;
6430 $this->type = $type;
6431 $this->width = $width;
6432 if (class_exists('idna_convert'))
6434 $idn = new idna_convert;
6435 $parsed = SimplePie_Misc::parse_url($link);
6436 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6438 $this->handler = $this->get_handler(); // Needs to load last
6441 function __toString()
6443 // There is no $this->data here
6444 return md5(serialize($this));
6447 function get_bitrate()
6449 if ($this->bitrate !== null)
6451 return $this->bitrate;
6459 function get_caption($key = 0)
6461 $captions = $this->get_captions();
6462 if (isset($captions[$key]))
6464 return $captions[$key];
6472 function get_captions()
6474 if ($this->captions !== null)
6476 return $this->captions;
6484 function get_category($key = 0)
6486 $categories = $this->get_categories();
6487 if (isset($categories[$key]))
6489 return $categories[$key];
6497 function get_categories()
6499 if ($this->categories !== null)
6501 return $this->categories;
6509 function get_channels()
6511 if ($this->channels !== null)
6513 return $this->channels;
6521 function get_copyright()
6523 if ($this->copyright !== null)
6525 return $this->copyright;
6533 function get_credit($key = 0)
6535 $credits = $this->get_credits();
6536 if (isset($credits[$key]))
6538 return $credits[$key];
6546 function get_credits()
6548 if ($this->credits !== null)
6550 return $this->credits;
6558 function get_description()
6560 if ($this->description !== null)
6562 return $this->description;
6570 function get_duration($convert = false)
6572 if ($this->duration !== null)
6576 $time = SimplePie_Misc::time_hms($this->duration);
6581 return $this->duration;
6590 function get_expression()
6592 if ($this->expression !== null)
6594 return $this->expression;
6602 function get_extension()
6604 if ($this->link !== null)
6606 $url = SimplePie_Misc::parse_url($this->link);
6607 if ($url['path'] !== '')
6609 return pathinfo($url['path'], PATHINFO_EXTENSION);
6615 function get_framerate()
6617 if ($this->framerate !== null)
6619 return $this->framerate;
6627 function get_handler()
6629 return $this->get_real_type(true);
6632 function get_hash($key = 0)
6634 $hashes = $this->get_hashes();
6635 if (isset($hashes[$key]))
6637 return $hashes[$key];
6645 function get_hashes()
6647 if ($this->hashes !== null)
6649 return $this->hashes;
6657 function get_height()
6659 if ($this->height !== null)
6661 return $this->height;
6669 function get_language()
6671 if ($this->lang !== null)
6681 function get_keyword($key = 0)
6683 $keywords = $this->get_keywords();
6684 if (isset($keywords[$key]))
6686 return $keywords[$key];
6694 function get_keywords()
6696 if ($this->keywords !== null)
6698 return $this->keywords;
6706 function get_length()
6708 if ($this->length !== null)
6710 return $this->length;
6720 if ($this->link !== null)
6722 return urldecode($this->link);
6730 function get_medium()
6732 if ($this->medium !== null)
6734 return $this->medium;
6742 function get_player()
6744 if ($this->player !== null)
6746 return $this->player;
6754 function get_rating($key = 0)
6756 $ratings = $this->get_ratings();
6757 if (isset($ratings[$key]))
6759 return $ratings[$key];
6767 function get_ratings()
6769 if ($this->ratings !== null)
6771 return $this->ratings;
6779 function get_restriction($key = 0)
6781 $restrictions = $this->get_restrictions();
6782 if (isset($restrictions[$key]))
6784 return $restrictions[$key];
6792 function get_restrictions()
6794 if ($this->restrictions !== null)
6796 return $this->restrictions;
6804 function get_sampling_rate()
6806 if ($this->samplingrate !== null)
6808 return $this->samplingrate;
6818 $length = $this->get_length();
6819 if ($length !== null)
6821 return round($length/1048576, 2);
6829 function get_thumbnail($key = 0)
6831 $thumbnails = $this->get_thumbnails();
6832 if (isset($thumbnails[$key]))
6834 return $thumbnails[$key];
6842 function get_thumbnails()
6844 if ($this->thumbnails !== null)
6846 return $this->thumbnails;
6854 function get_title()
6856 if ($this->title !== null)
6858 return $this->title;
6868 if ($this->type !== null)
6878 function get_width()
6880 if ($this->width !== null)
6882 return $this->width;
6890 function native_embed($options='')
6892 return $this->embed($options, true);
6896 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6898 function embed($options = '', $native = false)
6908 $bgcolor = '#ffffff';
6910 $widescreen = false;
6911 $handler = $this->get_handler();
6912 $type = $this->get_real_type();
6914 // Process options and reassign values as necessary
6915 if (is_array($options))
6921 $options = explode(',', $options);
6922 foreach($options as $option)
6924 $opt = explode(':', $option, 2);
6925 if (isset($opt[0], $opt[1]))
6927 $opt[0] = trim($opt[0]);
6928 $opt[1] = trim($opt[1]);
6944 $altclass = $opt[1];
6964 $mediaplayer = $opt[1];
6968 $widescreen = $opt[1];
6975 $mime = explode('/', $type, 2);
6978 // Process values for 'auto'
6979 if ($width == 'auto')
6981 if ($mime == 'video')
6983 if ($height == 'auto')
6987 elseif ($widescreen)
6989 $width = round((intval($height)/9)*16);
6993 $width = round((intval($height)/3)*4);
7002 if ($height == 'auto')
7004 if ($mime == 'audio')
7008 elseif ($mime == 'video')
7010 if ($width == 'auto')
7021 elseif ($widescreen)
7023 $height = round((intval($width)/16)*9);
7027 $height = round((intval($width)/4)*3);
7035 elseif ($mime == 'audio')
7040 // Set proper placeholder value
7041 if ($mime == 'audio')
7043 $placeholder = $audio;
7045 elseif ($mime == 'video')
7047 $placeholder = $video;
7052 // Make sure the JS library is included
7055 static $javascript_outputted = null;
7056 if (!$javascript_outputted && $this->javascript)
7058 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7059 $javascript_outputted = true;
7064 if ($handler == 'odeo')
7068 $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>';
7072 $embed .= '<script type="text/javascript">/* <![CDATA[ */embed_odeo("' . $this->get_link() . '");/* ]]> */</script>';
7077 elseif ($handler == 'flash')
7081 $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>";
7085 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7086 "embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');/* ]]> */</script>";
7090 // Flash Media Player file types.
7091 // Preferred handler for MP3 file types.
7092 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7097 $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>";
7101 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7102 "embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');/* ]]> */</script>";
7106 // QuickTime 7 file types. Need to test with QuickTime 6.
7107 // Only handle MP3's if the Flash Media Player is not present.
7108 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7113 if ($placeholder != ""){
7114 $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>";
7117 $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>";
7122 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7123 "embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');/* ]]> */</script>";
7128 elseif ($handler == 'wmedia')
7133 $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>";
7137 $embed .= '<script type="text/javascript">/* <![CDATA[ */' .
7138 "embed_wmedia('$width', '$height', '" . $this->get_link() . "');/* ]]> */</script>";
7143 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7148 function get_real_type($find_handler = false)
7150 // If it's Odeo, let's get it out of the way.
7151 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7156 // Mime-types by handler.
7157 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7158 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7159 $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
7160 $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
7161 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7163 if ($this->get_type() !== null)
7165 $type = strtolower($this->type);
7172 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7173 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7175 switch (strtolower($this->get_extension()))
7180 $type = 'audio/acc';
7187 $type = 'audio/aiff';
7191 $type = 'audio/wav';
7198 $type = 'audio/midi';
7202 $type = 'audio/x-m4a';
7207 $type = 'audio/mp3';
7211 $type = 'audio/wav';
7215 $type = 'audio/x-ms-wax';
7219 $type = 'audio/x-ms-wma';
7225 $type = 'video/3gpp';
7230 $type = 'video/3gpp2';
7234 $type = 'video/x-ms-asf';
7238 $type = 'video/x-flv';
7252 $type = 'video/mpeg';
7256 $type = 'video/x-m4v';
7261 $type = 'video/quicktime';
7266 $type = 'video/mp4';
7270 $type = 'video/sd-video';
7274 $type = 'video/x-ms-wm';
7278 $type = 'video/x-ms-wmv';
7282 $type = 'video/x-ms-wvx';
7287 $type = 'application/futuresplash';
7291 $type = 'application/x-shockwave-flash';
7298 if (in_array($type, $types_flash))
7302 elseif (in_array($type, $types_fmedia))
7306 elseif (in_array($type, $types_quicktime))
7310 elseif (in_array($type, $types_wmedia))
7314 elseif (in_array($type, $types_mp3))
7330 class SimplePie_Caption
7338 // Constructor, used to input the data
7339 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7341 $this->type = $type;
7342 $this->lang = $lang;
7343 $this->startTime = $startTime;
7344 $this->endTime = $endTime;
7345 $this->text = $text;
7348 function __toString()
7350 // There is no $this->data here
7351 return md5(serialize($this));
7354 function get_endtime()
7356 if ($this->endTime !== null)
7358 return $this->endTime;
7366 function get_language()
7368 if ($this->lang !== null)
7378 function get_starttime()
7380 if ($this->startTime !== null)
7382 return $this->startTime;
7392 if ($this->text !== null)
7404 if ($this->type !== null)
7415 class SimplePie_Credit
7421 // Constructor, used to input the data
7422 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7424 $this->role = $role;
7425 $this->scheme = $scheme;
7426 $this->name = $name;
7429 function __toString()
7431 // There is no $this->data here
7432 return md5(serialize($this));
7437 if ($this->role !== null)
7447 function get_scheme()
7449 if ($this->scheme !== null)
7451 return $this->scheme;
7461 if ($this->name !== null)
7472 class SimplePie_Copyright
7477 // Constructor, used to input the data
7478 function SimplePie_Copyright($url = null, $label = null)
7481 $this->label = $label;
7484 function __toString()
7486 // There is no $this->data here
7487 return md5(serialize($this));
7492 if ($this->url !== null)
7502 function get_attribution()
7504 if ($this->label !== null)
7506 return $this->label;
7515 class SimplePie_Rating
7520 // Constructor, used to input the data
7521 function SimplePie_Rating($scheme = null, $value = null)
7523 $this->scheme = $scheme;
7524 $this->value = $value;
7527 function __toString()
7529 // There is no $this->data here
7530 return md5(serialize($this));
7533 function get_scheme()
7535 if ($this->scheme !== null)
7537 return $this->scheme;
7545 function get_value()
7547 if ($this->value !== null)
7549 return $this->value;
7558 class SimplePie_Restriction
7564 // Constructor, used to input the data
7565 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7567 $this->relationship = $relationship;
7568 $this->type = $type;
7569 $this->value = $value;
7572 function __toString()
7574 // There is no $this->data here
7575 return md5(serialize($this));
7578 function get_relationship()
7580 if ($this->relationship !== null)
7582 return $this->relationship;
7592 if ($this->type !== null)
7602 function get_value()
7604 if ($this->value !== null)
7606 return $this->value;
7616 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7618 class SimplePie_File
7622 var $success = true;
7623 var $headers = array();
7628 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7630 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $proxy = "")
7632 if (class_exists('idna_convert'))
7634 $idn = new idna_convert;
7635 $parsed = SimplePie_Misc::parse_url($url);
7636 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7639 $this->useragent = $useragent;
7640 if (preg_match('/^http(s)?:\/\//i', $url))
7642 if ($useragent === null)
7644 $useragent = ini_get('user_agent');
7645 $this->useragent = $useragent;
7647 if (!is_array($headers))
7651 if (!$force_fsockopen && function_exists('curl_exec'))
7653 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7655 $headers2 = array();
7656 foreach ($headers as $key => $value)
7658 $headers2[] = "$key: $value";
7660 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7662 curl_setopt($fp, CURLOPT_ENCODING, '');
7664 curl_setopt($fp, CURLOPT_URL, $url);
7665 curl_setopt($fp, CURLOPT_HEADER, 1);
7666 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7667 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7668 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7669 curl_setopt($fp, CURLOPT_REFERER, $url);
7670 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7671 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7672 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7674 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7675 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7679 curl_setopt($fp, CURLOPT_PROXY, $proxy);
7682 $this->headers = curl_exec($fp);
7683 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7685 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7686 $this->headers = curl_exec($fp);
7688 if (curl_errno($fp))
7690 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7691 $this->success = false;
7695 $info = curl_getinfo($fp);
7697 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7698 $this->headers = array_pop($this->headers);
7699 $parser = new SimplePie_HTTP_Parser($this->headers);
7700 if ($parser->parse())
7702 $this->headers = $parser->headers;
7703 $this->body = $parser->body;
7704 $this->status_code = $parser->status_code;
7705 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)
7708 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7709 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7716 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7717 $url_parts = parse_url($url);
7718 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7720 $url_parts['host'] = "ssl://$url_parts[host]";
7721 $url_parts['port'] = 443;
7723 if (!isset($url_parts['port']))
7725 $url_parts['port'] = 80;
7728 $proxy_parts = explode(':', $proxy);
7729 if (!isset($proxy_parts[1])) {
7730 $proxy_parts[1] = 80;
7732 $host = $proxy_parts[0];
7733 $port = $proxy_parts[1];
7735 $host = $url_parts['host'];
7736 $port = $url_parts['port'];
7738 $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
7741 $this->error = 'fsockopen error: ' . $errstr;
7742 $this->success = false;
7746 stream_set_timeout($fp, $timeout);
7750 if (isset($url_parts['path']))
7752 if (isset($url_parts['query']))
7754 $get = "$url_parts[path]?$url_parts[query]";
7758 $get = $url_parts['path'];
7766 $out = "GET $get HTTP/1.0\r\n";
7767 $out .= "Host: $url_parts[host]\r\n";
7768 $out .= "User-Agent: $useragent\r\n";
7769 if (extension_loaded('zlib'))
7771 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7774 if (isset($url_parts['user']) && isset($url_parts['pass']))
7776 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7778 foreach ($headers as $key => $value)
7780 $out .= "$key: $value\r\n";
7782 $out .= "Connection: Close\r\n\r\n";
7785 $info = stream_get_meta_data($fp);
7787 $this->headers = '';
7788 while (!$info['eof'] && !$info['timed_out'])
7790 $this->headers .= fread($fp, 1160);
7791 $info = stream_get_meta_data($fp);
7793 if (!$info['timed_out'])
7795 $parser = new SimplePie_HTTP_Parser($this->headers);
7796 if ($parser->parse())
7798 $this->headers = $parser->headers;
7799 $this->body = $parser->body;
7800 $this->status_code = $parser->status_code;
7801 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)
7804 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7805 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7807 if (isset($this->headers['content-encoding']))
7809 // Hey, we act dumb elsewhere, so let's do that here too
7810 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7814 $decoder = new SimplePie_gzdecode($this->body);
7815 if (!$decoder->parse())
7817 $this->error = 'Unable to decode HTTP "gzip" stream';
7818 $this->success = false;
7822 $this->body = $decoder->data;
7827 if (($body = gzuncompress($this->body)) === false)
7829 if (($body = gzinflate($this->body)) === false)
7831 $this->error = 'Unable to decode HTTP "deflate" stream';
7832 $this->success = false;
7835 $this->body = $body;
7839 $this->error = 'Unknown content coding';
7840 $this->success = false;
7847 $this->error = 'fsocket timed out';
7848 $this->success = false;
7856 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7857 if (!$this->body = file_get_contents($url))
7859 $this->error = 'file_get_contents could not read the file';
7860 $this->success = false;
7867 * HTTP Response Parser
7869 * @package SimplePie
7871 class SimplePie_HTTP_Parser
7879 var $http_version = 0.0;
7887 var $status_code = 0;
7898 * Key/value pairs of the headers
7903 var $headers = array();
7906 * Body of the response
7914 * Current state of the state machine
7919 var $state = 'http_version';
7930 * Input data length (to avoid calling strlen() everytime this is needed)
7935 var $data_length = 0;
7938 * Current position of the pointer
7946 * Name of the hedaer currently being parsed
7954 * Value of the hedaer currently being parsed
7962 * Create an instance of the class with the input data
7965 * @param string $data Input data
7967 function SimplePie_HTTP_Parser($data)
7969 $this->data = $data;
7970 $this->data_length = strlen($this->data);
7974 * Parse the input data
7977 * @return bool true on success, false on failure
7981 while ($this->state && $this->state !== 'emit' && $this->has_data())
7983 $state = $this->state;
7987 if ($this->state === 'emit' || $this->state === 'body')
7993 $this->http_version = '';
7994 $this->status_code = '';
7996 $this->headers = array();
8003 * Check whether there is data beyond the pointer
8006 * @return bool true if there is further data, false if not
8010 return (bool) ($this->position < $this->data_length);
8014 * See if the next character is LWS
8017 * @return bool true if the next character is LWS, false if not
8019 function is_linear_whitespace()
8021 return (bool) ($this->data[$this->position] === "\x09"
8022 || $this->data[$this->position] === "\x20"
8023 || ($this->data[$this->position] === "\x0A"
8024 && isset($this->data[$this->position + 1])
8025 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8029 * Parse the HTTP version
8033 function http_version()
8035 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8037 $len = strspn($this->data, '0123456789.', 5);
8038 $this->http_version = substr($this->data, 5, $len);
8039 $this->position += 5 + $len;
8040 if (substr_count($this->http_version, '.') <= 1)
8042 $this->http_version = (float) $this->http_version;
8043 $this->position += strspn($this->data, "\x09\x20", $this->position);
8044 $this->state = 'status';
8048 $this->state = false;
8053 $this->state = false;
8058 * Parse the status code
8064 if ($len = strspn($this->data, '0123456789', $this->position))
8066 $this->status_code = (int) substr($this->data, $this->position, $len);
8067 $this->position += $len;
8068 $this->state = 'reason';
8072 $this->state = false;
8077 * Parse the reason phrase
8083 $len = strcspn($this->data, "\x0A", $this->position);
8084 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8085 $this->position += $len + 1;
8086 $this->state = 'new_line';
8090 * Deal with a new line, shifting data around as needed
8096 $this->value = trim($this->value, "\x0D\x20");
8097 if ($this->name !== '' && $this->value !== '')
8099 $this->name = strtolower($this->name);
8100 if (isset($this->headers[$this->name]))
8102 $this->headers[$this->name] .= ', ' . $this->value;
8106 $this->headers[$this->name] = $this->value;
8111 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8113 $this->position += 2;
8114 $this->state = 'body';
8116 elseif ($this->data[$this->position] === "\x0A")
8119 $this->state = 'body';
8123 $this->state = 'name';
8128 * Parse a header name
8134 $len = strcspn($this->data, "\x0A:", $this->position);
8135 if (isset($this->data[$this->position + $len]))
8137 if ($this->data[$this->position + $len] === "\x0A")
8139 $this->position += $len;
8140 $this->state = 'new_line';
8144 $this->name = substr($this->data, $this->position, $len);
8145 $this->position += $len + 1;
8146 $this->state = 'value';
8151 $this->state = false;
8156 * Parse LWS, replacing consecutive LWS characters with a single space
8160 function linear_whitespace()
8164 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8166 $this->position += 2;
8168 elseif ($this->data[$this->position] === "\x0A")
8172 $this->position += strspn($this->data, "\x09\x20", $this->position);
8173 } while ($this->has_data() && $this->is_linear_whitespace());
8174 $this->value .= "\x20";
8178 * See what state to move to while within non-quoted header values
8184 if ($this->is_linear_whitespace())
8186 $this->linear_whitespace();
8190 switch ($this->data[$this->position])
8194 $this->state = 'quote';
8199 $this->state = 'new_line';
8203 $this->state = 'value_char';
8210 * Parse a header value while outside quotes
8214 function value_char()
8216 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8217 $this->value .= substr($this->data, $this->position, $len);
8218 $this->position += $len;
8219 $this->state = 'value';
8223 * See what state to move to while within quoted header values
8229 if ($this->is_linear_whitespace())
8231 $this->linear_whitespace();
8235 switch ($this->data[$this->position])
8239 $this->state = 'value';
8244 $this->state = 'new_line';
8249 $this->state = 'quote_escaped';
8253 $this->state = 'quote_char';
8260 * Parse a header value while within quotes
8264 function quote_char()
8266 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8267 $this->value .= substr($this->data, $this->position, $len);
8268 $this->position += $len;
8269 $this->state = 'value';
8273 * Parse an escaped character within quotes
8277 function quote_escaped()
8279 $this->value .= $this->data[$this->position];
8281 $this->state = 'quote';
8291 $this->body = substr($this->data, $this->position);
8292 $this->state = 'emit';
8299 * @package SimplePie
8301 class SimplePie_gzdecode
8307 * @see gzdecode::$data
8309 var $compressed_data;
8312 * Size of compressed data
8316 var $compressed_size;
8319 * Minimum size of a valid gzip string
8323 var $min_compressed_size = 18;
8326 * Current position of pointer
8343 * @see gzdecode::$compressed_data
8372 * @see gzdecode::$extra_field
8373 * @see gzdecode::$SI2
8381 * @see gzdecode::$extra_field
8382 * @see gzdecode::$SI1
8387 * Extra field content
8390 * @see gzdecode::$SI1
8391 * @see gzdecode::$SI2
8403 * Human readable comment
8410 * Don't allow anything to be set
8414 function __set($name, $value)
8416 trigger_error("Cannot write property $name", E_USER_ERROR);
8420 * Set the compressed string and related properties
8424 function SimplePie_gzdecode($data)
8426 $this->compressed_data = $data;
8427 $this->compressed_size = strlen($data);
8431 * Decode the GZIP stream
8437 if ($this->compressed_size >= $this->min_compressed_size)
8439 // Check ID1, ID2, and CM
8440 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8445 // Get the FLG (FLaGs)
8446 $this->flags = ord($this->compressed_data[3]);
8448 // FLG bits above (1 << 4) are reserved
8449 if ($this->flags > 0x1F)
8454 // Advance the pointer after the above
8455 $this->position += 4;
8458 $mtime = substr($this->compressed_data, $this->position, 4);
8459 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8460 if (current(unpack('S', "\x00\x01")) === 1)
8462 $mtime = strrev($mtime);
8464 $this->MTIME = current(unpack('l', $mtime));
8465 $this->position += 4;
8467 // Get the XFL (eXtra FLags)
8468 $this->XFL = ord($this->compressed_data[$this->position++]);
8470 // Get the OS (Operating System)
8471 $this->OS = ord($this->compressed_data[$this->position++]);
8474 if ($this->flags & 4)
8476 // Read subfield IDs
8477 $this->SI1 = $this->compressed_data[$this->position++];
8478 $this->SI2 = $this->compressed_data[$this->position++];
8480 // SI2 set to zero is reserved for future use
8481 if ($this->SI2 === "\x00")
8486 // Get the length of the extra field
8487 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8490 // Check the length of the string is still valid
8491 $this->min_compressed_size += $len + 4;
8492 if ($this->compressed_size >= $this->min_compressed_size)
8494 // Set the extra field to the given data
8495 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8496 $this->position += $len;
8505 if ($this->flags & 8)
8507 // Get the length of the filename
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 filename to the given string
8515 $this->filename = substr($this->compressed_data, $this->position, $len);
8516 $this->position += $len + 1;
8524 // Parse the FCOMMENT
8525 if ($this->flags & 16)
8527 // Get the length of the comment
8528 $len = strspn($this->compressed_data, "\x00", $this->position);
8530 // Check the length of the string is still valid
8531 $this->min_compressed_size += $len + 1;
8532 if ($this->compressed_size >= $this->min_compressed_size)
8534 // Set the original comment to the given string
8535 $this->comment = substr($this->compressed_data, $this->position, $len);
8536 $this->position += $len + 1;
8545 if ($this->flags & 2)
8547 // Check the length of the string is still valid
8548 $this->min_compressed_size += $len + 2;
8549 if ($this->compressed_size >= $this->min_compressed_size)
8552 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8554 // Check the CRC matches
8555 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8557 $this->position += 2;
8570 // Decompress the actual data
8571 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8577 $this->position = $this->compressed_size - 8;
8580 // Check CRC of data
8581 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8582 $this->position += 4;
8583 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8588 // Check ISIZE of data
8589 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8590 $this->position += 4;
8591 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8596 // Wow, against all odds, we've actually got a valid gzip string
8606 class SimplePie_Cache
8609 * Don't call the constructor. Please.
8613 function SimplePie_Cache()
8615 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8619 * Create a new SimplePie_Cache object
8624 static function create($location, $filename, $extension)
8626 return new SimplePie_Cache_File($location, $filename, $extension);
8630 class SimplePie_Cache_File
8637 function SimplePie_Cache_File($location, $filename, $extension)
8639 $this->location = $location;
8640 $this->filename = rawurlencode($filename);
8641 $this->extension = rawurlencode($extension);
8642 $this->name = "$location/$this->filename.$this->extension";
8645 function save($data)
8647 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8649 if (is_a($data, 'SimplePie'))
8651 $data = $data->data;
8654 $data = serialize($data);
8656 if (function_exists('file_put_contents'))
8658 return (bool) file_put_contents($this->name, $data);
8662 $fp = fopen($this->name, 'wb');
8676 if (file_exists($this->name) && is_readable($this->name))
8678 return unserialize(file_get_contents($this->name));
8685 if (file_exists($this->name))
8687 return filemtime($this->name);
8694 if (file_exists($this->name))
8696 return touch($this->name);
8703 if (file_exists($this->name))
8705 return unlink($this->name);
8711 class SimplePie_Misc
8713 function time_hms($seconds)
8717 $hours = floor($seconds / 3600);
8718 $remainder = $seconds % 3600;
8721 $time .= $hours.':';
8724 $minutes = floor($remainder / 60);
8725 $seconds = $remainder % 60;
8726 if ($minutes < 10 && $hours > 0)
8728 $minutes = '0' . $minutes;
8732 $seconds = '0' . $seconds;
8735 $time .= $minutes.':';
8741 static function absolutize_url($relative, $base)
8743 if ($relative !== '')
8745 $relative = SimplePie_Misc::parse_url($relative);
8746 if ($relative['scheme'] !== '')
8748 $target = $relative;
8750 elseif ($base !== '')
8752 $base = SimplePie_Misc::parse_url($base);
8753 $target = SimplePie_Misc::parse_url('');
8754 if ($relative['authority'] !== '')
8756 $target = $relative;
8757 $target['scheme'] = $base['scheme'];
8761 $target['scheme'] = $base['scheme'];
8762 $target['authority'] = $base['authority'];
8763 if ($relative['path'] !== '')
8765 if (strpos($relative['path'], '/') === 0)
8767 $target['path'] = $relative['path'];
8769 elseif ($base['authority'] !== '' && $base['path'] === '')
8771 $target['path'] = '/' . $relative['path'];
8773 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8775 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8779 $target['path'] = $relative['path'];
8781 $target['query'] = $relative['query'];
8785 $target['path'] = $base['path'];
8786 if ($relative['query'] !== '')
8788 $target['query'] = $relative['query'];
8790 elseif ($base['query'] !== '')
8792 $target['query'] = $base['query'];
8796 $target['fragment'] = $relative['fragment'];
8800 // No base URL, just return the relative URL
8801 $target = $relative;
8803 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8809 $return = SimplePie_Misc::normalize_url($return);
8813 static function remove_dot_segments($input)
8816 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8818 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8819 if (strpos($input, '../') === 0)
8821 $input = substr($input, 3);
8823 elseif (strpos($input, './') === 0)
8825 $input = substr($input, 2);
8827 // 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,
8828 elseif (strpos($input, '/./') === 0)
8830 $input = substr_replace($input, '/', 0, 3);
8832 elseif ($input == '/.')
8836 // 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,
8837 elseif (strpos($input, '/../') === 0)
8839 $input = substr_replace($input, '/', 0, 4);
8840 $output = substr_replace($output, '', strrpos($output, '/'));
8842 elseif ($input == '/..')
8845 $output = substr_replace($output, '', strrpos($output, '/'));
8847 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8848 elseif ($input == '.' || $input == '..')
8852 // 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
8853 elseif (($pos = strpos($input, '/', 1)) !== false)
8855 $output .= substr($input, 0, $pos);
8856 $input = substr_replace($input, '', 0, $pos);
8864 return $output . $input;
8867 static function get_element($realname, $string)
8870 $name = preg_quote($realname, '/');
8871 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8873 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8875 $return[$i]['tag'] = $realname;
8876 $return[$i]['full'] = $matches[$i][0][0];
8877 $return[$i]['offset'] = $matches[$i][0][1];
8878 if (strlen($matches[$i][3][0]) <= 2)
8880 $return[$i]['self_closing'] = true;
8884 $return[$i]['self_closing'] = false;
8885 $return[$i]['content'] = $matches[$i][4][0];
8887 $return[$i]['attribs'] = array();
8888 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))
8890 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8892 if (count($attribs[$j]) == 2)
8894 $attribs[$j][2] = $attribs[$j][1];
8896 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8904 function element_implode($element)
8906 $full = "<$element[tag]";
8907 foreach ($element['attribs'] as $key => $value)
8909 $key = strtolower($key);
8910 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8912 if ($element['self_closing'])
8918 $full .= ">$element[content]</$element[tag]>";
8923 static function error($message, $level, $file, $line)
8928 $note = 'PHP Error';
8930 case E_USER_WARNING:
8931 $note = 'PHP Warning';
8934 $note = 'PHP Notice';
8937 $note = 'Unknown Error';
8940 error_log("$note: $message in $file on line $line", 0);
8945 * If a file has been cached, retrieve and display it.
8947 * This is most useful for caching images (get_favicon(), etc.),
8948 * however it works for all cached files. This WILL NOT display ANY
8949 * file/image/page/whatever, but rather only display what has already
8950 * been cached by SimplePie.
8953 * @see SimplePie::get_favicon()
8954 * @param str $identifier_url URL that is used to identify the content.
8955 * This may or may not be the actual URL of the live content.
8956 * @param str $cache_location Location of SimplePie's cache. Defaults
8958 * @param str $cache_extension The file extension that the file was
8959 * cached with. Defaults to 'spc'.
8960 * @param str $cache_class Name of the cache-handling class being used
8961 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8962 * as-is unless you've overloaded the class.
8963 * @param str $cache_name_function Obsolete. Exists for backwards
8964 * compatibility reasons only.
8966 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8968 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8970 if ($file = $cache->load())
8972 if (isset($file['headers']['content-type']))
8974 header('Content-type:' . $file['headers']['content-type']);
8978 header('Content-type: application/octet-stream');
8980 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8985 die('Cached file for ' . $identifier_url . ' cannot be found.');
8988 static function fix_protocol($url, $http = 1)
8990 $url = SimplePie_Misc::normalize_url($url);
8991 $parsed = SimplePie_Misc::parse_url($url);
8992 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8994 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8997 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8999 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9002 if ($http == 2 && $parsed['scheme'] !== '')
9006 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
9008 return substr_replace($url, 'podcast', 0, 4);
9010 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
9012 return substr_replace($url, 'itpc', 0, 4);
9020 static function parse_url($url)
9022 static $cache = array();
9023 if (isset($cache[$url]))
9025 return $cache[$url];
9027 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
9029 for ($i = count($match); $i <= 9; $i++)
9033 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
9037 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
9041 static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9046 $return .= "$scheme:";
9048 if ($authority !== '')
9050 $return .= "//$authority";
9058 $return .= "?$query";
9060 if ($fragment !== '')
9062 $return .= "#$fragment";
9067 static function normalize_url($url)
9069 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9070 $url = SimplePie_Misc::parse_url($url);
9071 $url['scheme'] = strtolower($url['scheme']);
9072 if ($url['authority'] !== '')
9074 $url['authority'] = strtolower($url['authority']);
9075 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9077 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9080 static function percent_encoding_normalization($match)
9082 $integer = hexdec($match[1]);
9083 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9085 return chr($integer);
9089 return strtoupper($match[0]);
9094 * Remove bad UTF-8 bytes
9096 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9097 * FAQ: Multilingual Forms (modified to include full ASCII range)
9099 * @author Geoffrey Sneddon
9100 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9101 * @param string $str String to remove bad UTF-8 bytes from
9102 * @return string UTF-8 string
9104 function utf8_bad_replace($str)
9106 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9110 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9114 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))
9116 return implode("\xEF\xBF\xBD", $matches[0]);
9118 elseif ($str !== '')
9120 return "\xEF\xBF\xBD";
9129 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9133 * @param string $string Windows-1252 encoded string
9134 * @return string UTF-8 encoded string
9136 static function windows_1252_to_utf8($string)
9138 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");
9140 return strtr($string, $convert_table);
9143 static function change_encoding($data, $input, $output)
9145 $input = SimplePie_Misc::encoding($input);
9146 $output = SimplePie_Misc::encoding($output);
9148 // We fail to fail on non US-ASCII bytes
9149 if ($input === 'US-ASCII')
9151 static $non_ascii_octects = '';
9152 if (!$non_ascii_octects)
9154 for ($i = 0x80; $i <= 0xFF; $i++)
9156 $non_ascii_octects .= chr($i);
9159 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9162 // This is first, as behaviour of this is completely predictable
9163 if ($input === 'Windows-1252' && $output === 'UTF-8')
9165 return SimplePie_Misc::windows_1252_to_utf8($data);
9167 // This is second, as behaviour of this varies only with PHP version
9168 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9172 // This is last, as behaviour of this varies with OS userland and PHP version
9173 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9177 // If we can't do anything, just fail
9184 static function encoding($charset)
9186 /* Character sets are case-insensitive, and also need some further
9187 normalization in the real world (though we'll return them in the form given
9188 in their registration). */
9189 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9191 case 'adobestandardencoding':
9192 case 'csadobestandardencoding':
9193 return 'Adobe-Standard-Encoding';
9195 case 'adobesymbolencoding':
9197 return 'Adobe-Symbol-Encoding';
9201 return 'Amiga-1251';
9203 case 'ansix31101983':
9205 case 'csiso99naplps':
9208 return 'ANSI_X3.110-1983';
9212 case 'csiso89asmo449':
9223 return 'Big5-HKSCS';
9234 case 'csiso4unitedkingdom':
9242 case 'csiso47bsviewdata':
9244 return 'BS_viewdata';
9252 case 'csaz243419851':
9253 case 'csiso121canadian1':
9256 return 'CSA_Z243.4-1985-1';
9259 case 'csaz243419852':
9260 case 'csiso122canadian2':
9263 return 'CSA_Z243.4-1985-2';
9265 case 'csaz24341985gr':
9266 case 'csiso123csaz24341985gr':
9268 return 'CSA_Z243.4-1985-gr';
9270 case 'csiso139csn369103':
9273 return 'CSN_369103';
9280 case 'csiso21german':
9291 case 'csiso646danish':
9297 case 'csibmebcdicatde':
9299 return 'EBCDIC-AT-DE';
9301 case 'csebcdicatdea':
9303 return 'EBCDIC-AT-DE-A';
9305 case 'csebcdiccafr':
9307 return 'EBCDIC-CA-FR';
9309 case 'csebcdicdkno':
9311 return 'EBCDIC-DK-NO';
9313 case 'csebcdicdknoa':
9315 return 'EBCDIC-DK-NO-A';
9323 return 'EBCDIC-ES-A';
9327 return 'EBCDIC-ES-S';
9329 case 'csebcdicfise':
9331 return 'EBCDIC-FI-SE';
9333 case 'csebcdicfisea':
9335 return 'EBCDIC-FI-SE-A';
9357 case 'csiso111ecmacyrillic':
9358 case 'ecmacyrillic':
9361 return 'ECMA-cyrillic';
9363 case 'csiso17spanish':
9369 case 'csiso85spanish2':
9375 case 'cseucfixwidjapanese':
9376 case 'extendedunixcodefixedwidthforjapanese':
9377 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9379 case 'cseucpkdfmtjapanese':
9381 case 'extendedunixcodepackedformatforjapanese':
9382 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9394 case 'csiso58gb231280':
9400 case 'csiso57gb1988':
9404 return 'GB_1988-80';
9406 case 'csiso153gost1976874':
9410 return 'GOST_19768-74';
9413 case 'csiso150greekccitt':
9416 return 'greek-ccitt';
9418 case 'csiso88greek7':
9423 case 'csiso18greek7old':
9426 return 'greek7-old';
9430 return 'HP-DeskTop';
9442 return 'HP-Pi-font';
9451 return 'HZ-GB-2312';
9453 case 'csibmsymbols':
9455 return 'IBM-Symbols';
9464 case 'pcmultilingual850euro':
9469 case 'ebcdiclatin9euro':
9475 case 'ebcdicus37euro':
9481 case 'ebcdicde273euro':
9487 case 'ebcdicdk277euro':
9488 case 'ebcdicno277euro':
9494 case 'ebcdicfi278euro':
9495 case 'ebcdicse278euro':
9501 case 'ebcdicit280euro':
9507 case 'ebcdices284euro':
9513 case 'ebcdicgb285euro':
9519 case 'ebcdicfr297euro':
9525 case 'ebcdicinternational500euro':
9531 case 'ebcdicis871euro':
9606 case 'ebcdicjpkana':
9636 case 'cspc8codepage437':
9648 case 'cspc775baltic':
9654 case 'cspc850multilingual':
9697 case 'cspc862latinhebrew':
9739 case 'ebcdiccproece':
9752 case 'ebcdiccyrillic':
9792 case 'csiso143iecp271':
9802 case 'csiso50inis8':
9807 case 'csiso51iniscyrillic':
9808 case 'iniscyrillic':
9810 return 'INIS-cyrillic';
9817 return 'ISO-2022-CN';
9819 case 'iso2022cnext':
9820 return 'ISO-2022-CN-EXT';
9824 return 'ISO-2022-JP';
9826 case 'csiso2022jp2':
9828 return 'ISO-2022-JP-2';
9832 return 'ISO-2022-KR';
9834 case 'cswindows30latin1':
9835 case 'iso88591windows30latin1':
9836 return 'ISO-8859-1-Windows-3.0-Latin-1';
9838 case 'cswindows31latin1':
9839 case 'iso88591windows31latin1':
9840 return 'ISO-8859-1-Windows-3.1-Latin-1';
9845 case 'iso885921987':
9848 return 'ISO-8859-2';
9850 case 'cswindows31latin2':
9851 case 'iso88592windowslatin2':
9852 return 'ISO-8859-2-Windows-Latin-2';
9857 case 'iso885931988':
9860 return 'ISO-8859-3';
9865 case 'iso885941988':
9868 return 'ISO-8859-4';
9870 case 'csisolatincyrillic':
9874 case 'iso885951988':
9875 return 'ISO-8859-5';
9879 case 'csisolatinarabic':
9883 case 'iso885961987':
9884 return 'ISO-8859-6';
9888 return 'ISO-8859-6-E';
9892 return 'ISO-8859-6-I';
9894 case 'csisolatingreek':
9901 case 'iso885971987':
9902 return 'ISO-8859-7';
9904 case 'csisolatinhebrew':
9908 case 'iso885981988':
9909 return 'ISO-8859-8';
9913 return 'ISO-8859-8-E';
9917 return 'ISO-8859-8-I';
9919 case 'cswindows31latin5':
9920 case 'iso88599windowslatin5':
9921 return 'ISO-8859-9-Windows-Latin-5';
9926 case 'iso8859101992':
9929 return 'ISO-8859-10';
9932 return 'ISO-8859-13';
9937 case 'iso8859141998':
9940 return 'ISO-8859-14';
9944 return 'ISO-8859-15';
9948 case 'iso8859162001':
9951 return 'ISO-8859-16';
9954 return 'ISO-10646-J-1';
9957 case 'iso10646ucs2':
9958 return 'ISO-10646-UCS-2';
9961 case 'iso10646ucs4':
9962 return 'ISO-10646-UCS-4';
9964 case 'csunicodeascii':
9965 case 'iso10646ucsbasic':
9966 return 'ISO-10646-UCS-Basic';
9968 case 'csunicodelatin1':
9970 case 'iso10646unicodelatin1':
9971 return 'ISO-10646-Unicode-Latin1';
9973 case 'csiso10646utf1':
9974 case 'iso10646utf1':
9975 return 'ISO-10646-UTF-1';
9980 return 'ISO-11548-1';
9986 case 'csunicodeibm1261':
9987 case 'isounicodeibm1261':
9988 return 'ISO-Unicode-IBM-1261';
9990 case 'csunicodeibm1264':
9991 case 'isounicodeibm1264':
9992 return 'ISO-Unicode-IBM-1264';
9994 case 'csunicodeibm1265':
9995 case 'isounicodeibm1265':
9996 return 'ISO-Unicode-IBM-1265';
9998 case 'csunicodeibm1268':
9999 case 'isounicodeibm1268':
10000 return 'ISO-Unicode-IBM-1268';
10002 case 'csunicodeibm1276':
10003 case 'isounicodeibm1276':
10004 return 'ISO-Unicode-IBM-1276';
10006 case 'csiso646basic1983':
10007 case 'iso646basic1983':
10009 return 'ISO_646.basic:1983';
10011 case 'csiso2intlrefversion':
10014 case 'iso646irv1983':
10015 return 'ISO_646.irv:1983';
10020 case 'iso20331983':
10021 return 'ISO_2033-1983';
10023 case 'csiso5427cyrillic':
10029 case 'iso5427cyrillic1981':
10030 case 'iso54271981':
10031 return 'ISO_5427:1981';
10033 case 'csiso5428greek':
10035 case 'iso54281980':
10036 return 'ISO_5428:1980';
10038 case 'csiso6937add':
10041 return 'ISO_6937-2-25';
10043 case 'csisotextcomm':
10045 case 'iso69372add':
10046 return 'ISO_6937-2-add';
10048 case 'csiso8859supp':
10050 case 'iso8859supp':
10052 return 'ISO_8859-supp';
10054 case 'csiso10367box':
10056 case 'iso10367box':
10057 return 'ISO_10367-box';
10059 case 'csiso15italian':
10065 case 'csiso13jisc6220jp':
10067 case 'jisc62201969':
10068 case 'jisc62201969jp':
10071 return 'JIS_C6220-1969-jp';
10073 case 'csiso14jisc6220ro':
10076 case 'jisc62201969ro':
10078 return 'JIS_C6220-1969-ro';
10080 case 'csiso42jisc62261978':
10082 case 'jisc62261978':
10083 return 'JIS_C6226-1978';
10085 case 'csiso87jisx0208':
10087 case 'jisc62261983':
10088 case 'jisx02081983':
10090 return 'JIS_C6226-1983';
10092 case 'csiso91jisc62291984a':
10094 case 'jisc62291984a':
10096 return 'JIS_C6229-1984-a';
10098 case 'csiso92jisc62991984b':
10100 case 'iso646jpocrb':
10101 case 'jisc62291984b':
10103 return 'JIS_C6229-1984-b';
10105 case 'csiso93jis62291984badd':
10107 case 'jisc62291984badd':
10109 return 'JIS_C6229-1984-b-add';
10111 case 'csiso94jis62291984hand':
10113 case 'jisc62291984hand':
10115 return 'JIS_C6229-1984-hand';
10117 case 'csiso95jis62291984handadd':
10119 case 'jisc62291984handadd':
10120 case 'jpocrhandadd':
10121 return 'JIS_C6229-1984-hand-add';
10123 case 'csiso96jisc62291984kana':
10125 case 'jisc62291984kana':
10126 return 'JIS_C6229-1984-kana';
10128 case 'csjisencoding':
10129 case 'jisencoding':
10130 return 'JIS_Encoding';
10132 case 'cshalfwidthkatakana':
10135 return 'JIS_X0201';
10137 case 'csiso159jisx02121990':
10139 case 'jisx02121990':
10141 return 'JIS_X0212-1990';
10143 case 'csiso141jusib1002':
10149 return 'JUS_I.B1.002';
10151 case 'csiso147macedonian':
10153 case 'jusib1003mac':
10155 return 'JUS_I.B1.003-mac';
10157 case 'csiso146serbian':
10159 case 'jusib1003serb':
10161 return 'JUS_I.B1.003-serb';
10163 case 'koi7switched':
10164 return 'KOI7-switched';
10181 case 'strk10482002':
10184 case 'csiso19latingreek':
10187 return 'latin-greek';
10189 case 'csiso27latingreek1':
10191 case 'latingreek1':
10192 return 'Latin-greek-1';
10194 case 'csiso158lap':
10198 return 'latin-lap';
10200 case 'csmacintosh':
10203 return 'macintosh';
10205 case 'csmicrosoftpublishing':
10206 case 'microsoftpublishing':
10207 return 'Microsoft-Publishing';
10217 case 'csiso86hungarian':
10222 return 'MSZ_7795.3';
10226 return 'NATS-DANO';
10228 case 'csnatsdanoadd':
10229 case 'natsdanoadd':
10230 return 'NATS-DANO-ADD';
10235 return 'NATS-SEFI';
10237 case 'csnatssefiadd':
10239 case 'natssefiadd':
10240 return 'NATS-SEFI-ADD';
10242 case 'csiso151cuba':
10247 return 'NC_NC00-10:81';
10249 case 'csiso69french':
10254 return 'NF_Z_62-010';
10256 case 'csiso25french':
10259 case 'nfz620101973':
10260 return 'NF_Z_62-010_(1973)';
10262 case 'csiso60danishnorwegian':
10263 case 'csiso60norwegian1':
10268 return 'NS_4551-1';
10270 case 'csiso61norwegian2':
10275 return 'NS_4551-2';
10277 case 'osdebcdicdf03irv':
10278 return 'OSD_EBCDIC_DF03_IRV';
10280 case 'osdebcdicdf041':
10281 return 'OSD_EBCDIC_DF04_1';
10283 case 'osdebcdicdf0415':
10284 return 'OSD_EBCDIC_DF04_15';
10286 case 'cspc8danishnorwegian':
10287 case 'pc8danishnorwegian':
10288 return 'PC8-Danish-Norwegian';
10290 case 'cspc8turkish':
10292 return 'PC8-Turkish';
10294 case 'csiso16portuguese':
10300 case 'csiso84portuguese2':
10308 case 'cyrillicasian':
10316 case 'csiso10swedish':
10323 return 'SEN_850200_B';
10325 case 'csiso11swedishfornames':
10330 return 'SEN_850200_C';
10335 return 'Shift_JIS';
10337 case 'csiso102t617bit':
10340 return 'T.61-7bit';
10342 case 'csiso103t618bit':
10346 return 'T.61-8bit';
10348 case 'csiso128t101g2':
10357 case 'csunicode11':
10359 return 'UNICODE-1-1';
10361 case 'csunicode11utf7':
10362 case 'unicode11utf7':
10363 return 'UNICODE-1-1-UTF-7';
10365 case 'csunknown8bit':
10366 case 'unknown8bit':
10367 return 'UNKNOWN-8BIT';
10369 case 'ansix341968':
10370 case 'ansix341986':
10377 case 'iso646irv1991':
10410 case 'csventurainternational':
10411 case 'venturainternational':
10412 return 'Ventura-International';
10414 case 'csventuramath':
10415 case 'venturamath':
10416 return 'Ventura-Math';
10418 case 'csventuraus':
10420 return 'Ventura-US';
10422 case 'csiso70videotexsupp1':
10424 case 'videotexsuppl':
10425 return 'videotex-suppl';
10435 case 'cswindows31j':
10437 return 'Windows-31J';
10441 return 'Windows-874';
10446 case 'csksc56011987':
10450 case 'ksc56011987':
10451 case 'ksc56011989':
10452 return 'Windows-949';
10454 case 'windows1250':
10455 return 'windows-1250';
10457 case 'windows1251':
10458 return 'windows-1251';
10461 case 'csisolatin1':
10465 case 'iso885911987':
10468 case 'windows1252':
10469 return 'Windows-1252';
10471 case 'windows1253':
10472 return 'windows-1253';
10474 case 'csisolatin5':
10477 case 'iso885991989':
10480 case 'windows1254':
10481 return 'Windows-1254';
10483 case 'windows1255':
10484 return 'windows-1255';
10486 case 'windows1256':
10487 return 'windows-1256';
10489 case 'windows1257':
10490 return 'windows-1257';
10492 case 'windows1258':
10493 return 'windows-1258';
10500 function get_curl_version()
10502 if (is_array($curl = curl_version()))
10504 $curl = $curl['version'];
10506 elseif (substr($curl, 0, 5) == 'curl/')
10508 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10510 elseif (substr($curl, 0, 8) == 'libcurl/')
10512 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10521 function is_subclass_of($class1, $class2)
10523 if (func_num_args() != 2)
10525 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10527 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10529 return is_subclass_of($class1, $class2);
10531 elseif (is_string($class1) && is_string($class2))
10533 if (class_exists($class1))
10535 if (class_exists($class2))
10537 $class2 = strtolower($class2);
10538 while ($class1 = strtolower(get_parent_class($class1)))
10540 if ($class1 == $class2)
10549 trigger_error('Unknown class passed as parameter', E_USER_WARNING);
10556 * Strip HTML comments
10559 * @param string $data Data to strip comments from
10560 * @return string Comment stripped string
10562 function strip_comments($data)
10565 while (($start = strpos($data, '<!--')) !== false)
10567 $output .= substr($data, 0, $start);
10568 if (($end = strpos($data, '-->', $start)) !== false)
10570 $data = substr_replace($data, '', 0, $end + 3);
10577 return $output . $data;
10580 function parse_date($dt)
10582 $parser = SimplePie_Parse_Date::get();
10583 return $parser->parse($dt);
10587 * Decode HTML entities
10591 * @param string $data Input data
10592 * @return string Output data
10594 function entities_decode($data)
10596 $decoder = new SimplePie_Decode_HTML_Entities($data);
10597 return $decoder->parse();
10601 * Remove RFC822 comments
10604 * @param string $data Data to strip comments from
10605 * @return string Comment stripped string
10607 function uncomment_rfc822($string)
10609 $string = (string) $string;
10611 $length = strlen($string);
10616 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10618 $output .= substr($string, $position, $pos - $position);
10619 $position = $pos + 1;
10620 if ($string[$pos - 1] !== '\\')
10623 while ($depth && $position < $length)
10625 $position += strcspn($string, '()', $position);
10626 if ($string[$position - 1] === '\\')
10631 elseif (isset($string[$position]))
10633 switch ($string[$position])
10656 $output .= substr($string, $position);
10661 function parse_mime($mime)
10663 if (($pos = strpos($mime, ';')) === false)
10665 return trim($mime);
10669 return trim(substr($mime, 0, $pos));
10673 function htmlspecialchars_decode($string, $quote_style)
10675 if (function_exists('htmlspecialchars_decode'))
10677 return htmlspecialchars_decode($string, $quote_style);
10681 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10685 function atom_03_construct_type($attribs)
10687 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10689 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10693 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10695 if (isset($attribs['']['type']))
10697 switch (strtolower(trim($attribs['']['type'])))
10701 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10705 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10708 case 'application/xhtml+xml':
10709 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10712 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10717 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10721 static function atom_10_construct_type($attribs)
10723 if (isset($attribs['']['type']))
10725 switch (strtolower(trim($attribs['']['type'])))
10728 return SIMPLEPIE_CONSTRUCT_TEXT;
10731 return SIMPLEPIE_CONSTRUCT_HTML;
10734 return SIMPLEPIE_CONSTRUCT_XHTML;
10737 return SIMPLEPIE_CONSTRUCT_NONE;
10740 return SIMPLEPIE_CONSTRUCT_TEXT;
10743 function atom_10_content_construct_type($attribs)
10745 if (isset($attribs['']['type']))
10747 $type = strtolower(trim($attribs['']['type']));
10751 return SIMPLEPIE_CONSTRUCT_TEXT;
10754 return SIMPLEPIE_CONSTRUCT_HTML;
10757 return SIMPLEPIE_CONSTRUCT_XHTML;
10759 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10761 return SIMPLEPIE_CONSTRUCT_NONE;
10765 return SIMPLEPIE_CONSTRUCT_BASE64;
10770 return SIMPLEPIE_CONSTRUCT_TEXT;
10774 static function is_isegment_nz_nc($string)
10776 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);
10779 function space_seperated_tokens($string)
10781 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10782 $string_length = strlen($string);
10784 $position = strspn($string, $space_characters);
10787 while ($position < $string_length)
10789 $len = strcspn($string, $space_characters, $position);
10790 $tokens[] = substr($string, $position, $len);
10792 $position += strspn($string, $space_characters, $position);
10798 function array_unique($array)
10800 if (version_compare(PHP_VERSION, '5.2', '>='))
10802 return array_unique($array);
10806 $array = (array) $array;
10807 $new_array = array();
10808 $new_array_strings = array();
10809 foreach ($array as $key => $value)
10811 if (is_object($value))
10813 if (method_exists($value, '__toString'))
10815 $cmp = $value->__toString();
10819 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10822 elseif (is_array($value))
10824 $cmp = (string) reset($value);
10828 $cmp = (string) $value;
10830 if (!in_array($cmp, $new_array_strings))
10832 $new_array[$key] = $value;
10833 $new_array_strings[] = $cmp;
10841 * Converts a unicode codepoint to a UTF-8 character
10845 * @param int $codepoint Unicode codepoint
10846 * @return string UTF-8 character
10848 function codepoint_to_utf8($codepoint)
10850 static $cache = array();
10851 $codepoint = (int) $codepoint;
10852 if (isset($cache[$codepoint]))
10854 return $cache[$codepoint];
10856 elseif ($codepoint < 0)
10858 return $cache[$codepoint] = false;
10860 else if ($codepoint <= 0x7f)
10862 return $cache[$codepoint] = chr($codepoint);
10864 else if ($codepoint <= 0x7ff)
10866 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10868 else if ($codepoint <= 0xffff)
10870 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10872 else if ($codepoint <= 0x10ffff)
10874 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10878 // U+FFFD REPLACEMENT CHARACTER
10879 return $cache[$codepoint] = "\xEF\xBF\xBD";
10884 * Re-implementation of PHP 5's stripos()
10886 * Returns the numeric position of the first occurrence of needle in the
10891 * @param object $haystack
10892 * @param string $needle Note that the needle may be a string of one or more
10893 * characters. If needle is not a string, it is converted to an integer
10894 * and applied as the ordinal value of a character.
10895 * @param int $offset The optional offset parameter allows you to specify which
10896 * character in haystack to start searching. The position returned is still
10897 * relative to the beginning of haystack.
10898 * @return bool If needle is not found, stripos() will return boolean false.
10900 function stripos($haystack, $needle, $offset = 0)
10902 if (function_exists('stripos'))
10904 return stripos($haystack, $needle, $offset);
10908 if (is_string($needle))
10910 $needle = strtolower($needle);
10912 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10914 $needle = strtolower(chr($needle));
10918 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10922 return strpos(strtolower($haystack), $needle, $offset);
10927 * Similar to parse_str()
10929 * Returns an associative array of name/value pairs, where the value is an
10930 * array of values that have used the same name
10934 * @param string $str The input string.
10937 function parse_str($str)
10940 $str = explode('&', $str);
10942 foreach ($str as $section)
10944 if (strpos($section, '=') !== false)
10946 list($name, $value) = explode('=', $section, 2);
10947 $return[urldecode($name)][] = urldecode($value);
10951 $return[urldecode($section)][] = null;
10959 * Detect XML encoding, as per XML 1.0 Appendix F.1
10961 * @todo Add support for EBCDIC
10962 * @param string $data XML data
10963 * @return array Possible encodings
10965 static function xml_encoding($data)
10967 // UTF-32 Big Endian BOM
10968 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10970 $encoding[] = 'UTF-32BE';
10972 // UTF-32 Little Endian BOM
10973 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10975 $encoding[] = 'UTF-32LE';
10977 // UTF-16 Big Endian BOM
10978 elseif (substr($data, 0, 2) === "\xFE\xFF")
10980 $encoding[] = 'UTF-16BE';
10982 // UTF-16 Little Endian BOM
10983 elseif (substr($data, 0, 2) === "\xFF\xFE")
10985 $encoding[] = 'UTF-16LE';
10988 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10990 $encoding[] = 'UTF-8';
10992 // UTF-32 Big Endian Without BOM
10993 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")
10995 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10997 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10998 if ($parser->parse())
11000 $encoding[] = $parser->encoding;
11003 $encoding[] = 'UTF-32BE';
11005 // UTF-32 Little Endian Without BOM
11006 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")
11008 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11010 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11011 if ($parser->parse())
11013 $encoding[] = $parser->encoding;
11016 $encoding[] = 'UTF-32LE';
11018 // UTF-16 Big Endian Without BOM
11019 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11021 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11023 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11024 if ($parser->parse())
11026 $encoding[] = $parser->encoding;
11029 $encoding[] = 'UTF-16BE';
11031 // UTF-16 Little Endian Without BOM
11032 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11034 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11036 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11037 if ($parser->parse())
11039 $encoding[] = $parser->encoding;
11042 $encoding[] = 'UTF-16LE';
11044 // US-ASCII (or superset)
11045 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11047 if ($pos = strpos($data, "\x3F\x3E"))
11049 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11050 if ($parser->parse())
11052 $encoding[] = $parser->encoding;
11055 $encoding[] = 'UTF-8';
11057 // Fallback to UTF-8
11060 $encoding[] = 'UTF-8';
11067 * Decode HTML Entities
11069 * This implements HTML5 as of revision 967 (2007-06-28)
11071 * @package SimplePie
11073 class SimplePie_Decode_HTML_Entities
11076 * Data to be parsed
11084 * Currently consumed bytes
11089 var $consumed = '';
11092 * Position of the current byte being parsed
11100 * Create an instance of the class with the input data
11103 * @param string $data Input data
11105 function SimplePie_Decode_HTML_Entities($data)
11107 $this->data = $data;
11111 * Parse the input data
11114 * @return string Output data
11118 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11122 $this->consumed = '';
11124 return $this->data;
11128 * Consume the next byte
11131 * @return mixed The next byte, or false, if there is no more data
11135 if (isset($this->data[$this->position]))
11137 $this->consumed .= $this->data[$this->position];
11138 return $this->data[$this->position++];
11142 $this->consumed = false;
11148 * Consume a range of characters
11151 * @param string $chars Characters to consume
11152 * @return mixed A series of characters that match the range, or false
11154 function consume_range($chars)
11156 if ($len = strspn($this->data, $chars, $this->position))
11158 $data = substr($this->data, $this->position, $len);
11159 $this->consumed .= $data;
11160 $this->position += $len;
11165 $this->consumed = false;
11171 * Unconsume one byte
11175 function unconsume()
11177 $this->consumed = substr($this->consumed, 0, -1);
11188 switch ($this->consume())
11201 switch ($this->consume())
11205 $range = '0123456789ABCDEFabcdef';
11210 $range = '0123456789';
11212 $this->unconsume();
11216 if ($codepoint = $this->consume_range($range))
11218 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");
11222 $codepoint = hexdec($codepoint);
11226 $codepoint = intval($codepoint);
11229 if (isset($windows_1252_specials[$codepoint]))
11231 $replacement = $windows_1252_specials[$codepoint];
11235 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11238 if ($this->consume() != ';')
11240 $this->unconsume();
11243 $consumed_length = strlen($this->consumed);
11244 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11245 $this->position += strlen($replacement) - $consumed_length;
11250 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");
11252 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11254 $consumed = substr($this->consumed, 1);
11255 if (isset($entities[$consumed]))
11257 $match = $consumed;
11261 if ($match !== null)
11263 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11264 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11274 * @package SimplePie
11276 class SimplePie_Parse_Date
11281 * @access protected
11287 * List of days, calendar day name => ordinal day number in the week
11289 * @access protected
11352 'keskiviikko' => 3,
11376 * List of months, calendar month name => calendar month number
11378 * @access protected
11381 var $month = array(
11392 // No long form of May
11416 // 'september' => 9,
11418 // 'november' => 11,
11419 // 'december' => 12,
11442 // 'september' => 9,
11443 // 'oktober' => 10,
11444 // 'november' => 11,
11457 // 'novembre' => 11,
11497 // 'november' => 11,
11498 // 'december' => 12,
11521 * List of timezones, abbreviation => offset from UTC
11523 * @access protected
11526 var $timezone = array(
11729 * Cached PCRE for SimplePie_Parse_Date::$day
11731 * @access protected
11737 * Cached PCRE for SimplePie_Parse_Date::$month
11739 * @access protected
11745 * Array of user-added callback methods
11750 var $built_in = array();
11753 * Array of user-added callback methods
11758 var $user = array();
11761 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11762 * self::month_pcre, and self::built_in
11766 function SimplePie_Parse_Date()
11768 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11769 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11772 if (!isset($cache[get_class($this)]))
11774 if (extension_loaded('Reflection'))
11776 $class = new ReflectionClass(get_class($this));
11777 $methods = $class->getMethods();
11778 $all_methods = array();
11779 foreach ($methods as $method)
11781 $all_methods[] = $method->getName();
11786 $all_methods = get_class_methods($this);
11789 foreach ($all_methods as $method)
11791 if (strtolower(substr($method, 0, 5)) === 'date_')
11793 $cache[get_class($this)][] = $method;
11798 foreach ($cache[get_class($this)] as $method)
11800 $this->built_in[] = $method;
11809 static function get()
11814 $object = new SimplePie_Parse_Date;
11824 * @param string $date Date to parse
11825 * @return int Timestamp corresponding to date string, or false on failure
11827 function parse($date)
11829 foreach ($this->user as $method)
11831 if (($returned = call_user_func($method, $date)) !== false)
11837 foreach ($this->built_in as $method)
11839 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11849 * Add a callback method to parse a date
11853 * @param callback $callback
11855 function add_callback($callback)
11857 if (is_callable($callback))
11859 $this->user[] = $callback;
11863 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11868 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11869 * well as allowing any of upper or lower case "T", horizontal tabs, or
11870 * spaces to be used as the time seperator (including more than one))
11872 * @access protected
11873 * @return int Timestamp
11875 function date_w3cdtf($date)
11880 $year = '([0-9]{4})';
11881 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11882 $decimal = '([0-9]*)';
11883 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11884 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11886 if (preg_match($pcre, $date, $match))
11889 Capturing subpatterns:
11896 7: Decimal fraction of a second
11900 11: Timezone minutes
11903 // Fill in empty matches
11904 for ($i = count($match); $i <= 3; $i++)
11909 for ($i = count($match); $i <= 7; $i++)
11914 // Numeric timezone
11915 if (isset($match[9]) && $match[9] !== '')
11917 $timezone = $match[10] * 3600;
11918 $timezone += $match[11] * 60;
11919 if ($match[9] === '-')
11921 $timezone = 0 - $timezone;
11929 // Convert the number of seconds to an integer, taking decimals into account
11930 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11932 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11941 * Remove RFC822 comments
11943 * @access protected
11944 * @param string $data Data to strip comments from
11945 * @return string Comment stripped string
11947 function remove_rfc2822_comments($string)
11949 $string = (string) $string;
11951 $length = strlen($string);
11956 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11958 $output .= substr($string, $position, $pos - $position);
11959 $position = $pos + 1;
11960 if ($string[$pos - 1] !== '\\')
11963 while ($depth && $position < $length)
11965 $position += strcspn($string, '()', $position);
11966 if ($string[$position - 1] === '\\')
11971 elseif (isset($string[$position]))
11973 switch ($string[$position])
11996 $output .= substr($string, $position);
12002 * Parse RFC2822's date format
12004 * @access protected
12005 * @return int Timestamp
12007 function date_rfc2822($date)
12012 $wsp = '[\x09\x20]';
12013 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
12014 $optional_fws = $fws . '?';
12015 $day_name = $this->day_pcre;
12016 $month = $this->month_pcre;
12017 $day = '([0-9]{1,2})';
12018 $hour = $minute = $second = '([0-9]{2})';
12019 $year = '([0-9]{2,4})';
12020 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
12021 $character_zone = '([A-Z]{1,5})';
12022 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
12023 $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';
12025 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
12028 Capturing subpatterns:
12038 10: Timezone minutes
12039 11: Alphabetic timezone
12042 // Find the month number
12043 $month = $this->month[strtolower($match[3])];
12045 // Numeric timezone
12046 if ($match[8] !== '')
12048 $timezone = $match[9] * 3600;
12049 $timezone += $match[10] * 60;
12050 if ($match[8] === '-')
12052 $timezone = 0 - $timezone;
12055 // Character timezone
12056 elseif (isset($this->timezone[strtoupper($match[11])]))
12058 $timezone = $this->timezone[strtoupper($match[11])];
12060 // Assume everything else to be -0000
12066 // Deal with 2/3 digit years
12067 if ($match[4] < 50)
12071 elseif ($match[4] < 1000)
12076 // Second is optional, if it is empty set it to zero
12077 if ($match[7] !== '')
12079 $second = $match[7];
12086 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12095 * Parse RFC850's date format
12097 * @access protected
12098 * @return int Timestamp
12100 function date_rfc850($date)
12105 $space = '[\x09\x20]+';
12106 $day_name = $this->day_pcre;
12107 $month = $this->month_pcre;
12108 $day = '([0-9]{1,2})';
12109 $year = $hour = $minute = $second = '([0-9]{2})';
12110 $zone = '([A-Z]{1,5})';
12111 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12113 if (preg_match($pcre, $date, $match))
12116 Capturing subpatterns:
12128 $month = $this->month[strtolower($match[3])];
12130 // Character timezone
12131 if (isset($this->timezone[strtoupper($match[8])]))
12133 $timezone = $this->timezone[strtoupper($match[8])];
12135 // Assume everything else to be -0000
12141 // Deal with 2 digit year
12142 if ($match[4] < 50)
12151 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12160 * Parse C99's asctime()'s date format
12162 * @access protected
12163 * @return int Timestamp
12165 function date_asctime($date)
12170 $space = '[\x09\x20]+';
12171 $wday_name = $this->day_pcre;
12172 $mon_name = $this->month_pcre;
12173 $day = '([0-9]{1,2})';
12174 $hour = $sec = $min = '([0-9]{2})';
12175 $year = '([0-9]{4})';
12176 $terminator = '\x0A?\x00?';
12177 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12179 if (preg_match($pcre, $date, $match))
12182 Capturing subpatterns:
12192 $month = $this->month[strtolower($match[2])];
12193 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12202 * Parse dates using strtotime()
12204 * @access protected
12205 * @return int Timestamp
12207 function date_strtotime($date)
12209 $strtotime = strtotime($date);
12210 if ($strtotime === -1 || $strtotime === false)
12222 * Content-type sniffing
12224 * @package SimplePie
12226 class SimplePie_Content_Type_Sniffer
12231 * @var SimplePie_File
12237 * Create an instance of the class with the input file
12240 * @param SimplePie_Content_Type_Sniffer $file Input file
12242 function SimplePie_Content_Type_Sniffer($file)
12244 $this->file = $file;
12248 * Get the Content-Type of the specified file
12251 * @return string Actual Content-Type
12253 function get_type()
12255 if (isset($this->file->headers['content-type']))
12257 if (!isset($this->file->headers['content-encoding'])
12258 && ($this->file->headers['content-type'] === 'text/plain'
12259 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12260 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12262 return $this->text_or_binary();
12265 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12267 $official = substr($this->file->headers['content-type'], 0, $pos);
12271 $official = $this->file->headers['content-type'];
12273 $official = strtolower($official);
12275 if ($official === 'unknown/unknown'
12276 || $official === 'application/unknown')
12278 return $this->unknown();
12280 elseif (substr($official, -4) === '+xml'
12281 || $official === 'text/xml'
12282 || $official === 'application/xml')
12286 elseif (substr($official, 0, 6) === 'image/')
12288 if ($return = $this->image())
12297 elseif ($official === 'text/html')
12299 return $this->feed_or_html();
12308 return $this->unknown();
12313 * Sniff text or binary
12316 * @return string Actual Content-Type
12318 function text_or_binary()
12320 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12321 || substr($this->file->body, 0, 2) === "\xFF\xFE"
12322 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12323 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12325 return 'text/plain';
12327 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12329 return 'application/octect-stream';
12333 return 'text/plain';
12341 * @return string Actual Content-Type
12345 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12346 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12347 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12348 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12350 return 'text/html';
12352 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12354 return 'application/pdf';
12356 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12358 return 'application/postscript';
12360 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12361 || substr($this->file->body, 0, 6) === 'GIF89a')
12363 return 'image/gif';
12365 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12367 return 'image/png';
12369 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12371 return 'image/jpeg';
12373 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12375 return 'image/bmp';
12379 return $this->text_or_binary();
12387 * @return string Actual Content-Type
12391 if (substr($this->file->body, 0, 6) === 'GIF87a'
12392 || substr($this->file->body, 0, 6) === 'GIF89a')
12394 return 'image/gif';
12396 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12398 return 'image/png';
12400 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12402 return 'image/jpeg';
12404 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12406 return 'image/bmp';
12418 * @return string Actual Content-Type
12420 function feed_or_html()
12422 $len = strlen($this->file->body);
12423 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12425 while ($pos < $len)
12427 switch ($this->file->body[$pos])
12433 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12441 return 'text/html';
12444 if (substr($this->file->body, $pos, 3) === '!--')
12447 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12453 return 'text/html';
12456 elseif (substr($this->file->body, $pos, 1) === '!')
12458 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12464 return 'text/html';
12467 elseif (substr($this->file->body, $pos, 1) === '?')
12469 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12475 return 'text/html';
12478 elseif (substr($this->file->body, $pos, 3) === 'rss'
12479 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12481 return 'application/rss+xml';
12483 elseif (substr($this->file->body, $pos, 4) === 'feed')
12485 return 'application/atom+xml';
12489 return 'text/html';
12493 return 'text/html';
12498 * Parses the XML Declaration
12500 * @package SimplePie
12502 class SimplePie_XML_Declaration_Parser
12510 var $version = '1.0';
12518 var $encoding = 'UTF-8';
12526 var $standalone = false;
12529 * Current state of the state machine
12534 var $state = 'before_version_name';
12545 * Input data length (to avoid calling strlen() everytime this is needed)
12550 var $data_length = 0;
12553 * Current position of the pointer
12561 * Create an instance of the class with the input data
12564 * @param string $data Input data
12566 function SimplePie_XML_Declaration_Parser($data)
12568 $this->data = $data;
12569 $this->data_length = strlen($this->data);
12573 * Parse the input data
12576 * @return bool true on success, false on failure
12580 while ($this->state && $this->state !== 'emit' && $this->has_data())
12582 $state = $this->state;
12586 if ($this->state === 'emit')
12592 $this->version = '';
12593 $this->encoding = '';
12594 $this->standalone = '';
12600 * Check whether there is data beyond the pointer
12603 * @return bool true if there is further data, false if not
12605 function has_data()
12607 return (bool) ($this->position < $this->data_length);
12611 * Advance past any whitespace
12613 * @return int Number of whitespace characters passed
12615 function skip_whitespace()
12617 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12618 $this->position += $whitespace;
12619 return $whitespace;
12625 function get_value()
12627 $quote = substr($this->data, $this->position, 1);
12628 if ($quote === '"' || $quote === "'")
12631 $len = strcspn($this->data, $quote, $this->position);
12632 if ($this->has_data())
12634 $value = substr($this->data, $this->position, $len);
12635 $this->position += $len + 1;
12642 function before_version_name()
12644 if ($this->skip_whitespace())
12646 $this->state = 'version_name';
12650 $this->state = false;
12654 function version_name()
12656 if (substr($this->data, $this->position, 7) === 'version')
12658 $this->position += 7;
12659 $this->skip_whitespace();
12660 $this->state = 'version_equals';
12664 $this->state = false;
12668 function version_equals()
12670 if (substr($this->data, $this->position, 1) === '=')
12673 $this->skip_whitespace();
12674 $this->state = 'version_value';
12678 $this->state = false;
12682 function version_value()
12684 if ($this->version = $this->get_value())
12686 $this->skip_whitespace();
12687 if ($this->has_data())
12689 $this->state = 'encoding_name';
12693 $this->state = 'emit';
12698 $this->state = 'standalone_name';
12702 function encoding_name()
12704 if (substr($this->data, $this->position, 8) === 'encoding')
12706 $this->position += 8;
12707 $this->skip_whitespace();
12708 $this->state = 'encoding_equals';
12712 $this->state = false;
12716 function encoding_equals()
12718 if (substr($this->data, $this->position, 1) === '=')
12721 $this->skip_whitespace();
12722 $this->state = 'encoding_value';
12726 $this->state = false;
12730 function encoding_value()
12732 if ($this->encoding = $this->get_value())
12734 $this->skip_whitespace();
12735 if ($this->has_data())
12737 $this->state = 'standalone_name';
12741 $this->state = 'emit';
12746 $this->state = false;
12750 function standalone_name()
12752 if (substr($this->data, $this->position, 10) === 'standalone')
12754 $this->position += 10;
12755 $this->skip_whitespace();
12756 $this->state = 'standalone_equals';
12760 $this->state = false;
12764 function standalone_equals()
12766 if (substr($this->data, $this->position, 1) === '=')
12769 $this->skip_whitespace();
12770 $this->state = 'standalone_value';
12774 $this->state = false;
12778 function standalone_value()
12780 if ($standalone = $this->get_value())
12782 switch ($standalone)
12785 $this->standalone = true;
12789 $this->standalone = false;
12793 $this->state = false;
12797 $this->skip_whitespace();
12798 if ($this->has_data())
12800 $this->state = false;
12804 $this->state = 'emit';
12809 $this->state = false;
12814 class SimplePie_Locator
12819 var $local = array();
12820 var $elsewhere = array();
12821 var $file_class = 'SimplePie_File';
12822 var $cached_entities = array();
12825 var $base_location = 0;
12826 var $checked_feeds = 0;
12827 var $max_checked_feeds = 10;
12828 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12831 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 = "")
12833 $this->file =& $file;
12834 $this->file_class = $file_class;
12835 $this->useragent = $useragent;
12836 $this->timeout = $timeout;
12837 $this->max_checked_feeds = $max_checked_feeds;
12838 $this->content_type_sniffer_class = $content_type_sniffer_class;
12839 $this->proxy = $proxy;
12842 function find($type = SIMPLEPIE_LOCATOR_ALL)
12844 if ($this->is_feed($this->file))
12846 return $this->file;
12849 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12851 $sniffer = new $this->content_type_sniffer_class($this->file);
12852 if ($sniffer->get_type() !== 'text/html')
12858 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12863 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12868 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12870 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12875 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12880 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12885 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12893 function is_feed(&$file)
12895 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12897 $sniffer = new $this->content_type_sniffer_class($file);
12898 $sniffed = $sniffer->get_type();
12899 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12908 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12918 function get_base()
12920 $this->http_base = $this->file->url;
12921 $this->base = $this->http_base;
12922 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12923 foreach ($elements as $element)
12925 if ($element['attribs']['href']['data'] !== '')
12927 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12928 $this->base_location = $element['offset'];
12934 function autodiscovery()
12936 $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));
12938 foreach ($links as $link)
12940 if ($this->checked_feeds == $this->max_checked_feeds)
12944 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12946 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12948 if ($this->base_location < $link['offset'])
12950 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12954 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12957 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'))))
12959 $this->checked_feeds++;
12960 $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
12961 if ($this->is_feed($feed))
12972 function get_links()
12974 $links = SimplePie_Misc::get_element('a', $this->file->body);
12975 foreach ($links as $link)
12977 if (isset($link['attribs']['href']['data']))
12979 $href = trim($link['attribs']['href']['data']);
12980 $parsed = SimplePie_Misc::parse_url($href);
12981 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12983 if ($this->base_location < $link['offset'])
12985 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12989 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12992 $current = SimplePie_Misc::parse_url($this->file->url);
12994 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12996 $this->local[] = $href;
13000 $this->elsewhere[] = $href;
13005 $this->local = array_unique($this->local);
13006 $this->elsewhere = array_unique($this->elsewhere);
13007 if (!empty($this->local) || !empty($this->elsewhere))
13014 function extension(&$array)
13016 foreach ($array as $key => $value)
13018 if ($this->checked_feeds == $this->max_checked_feeds)
13022 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
13024 $this->checked_feeds++;
13025 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13026 if ($this->is_feed($feed))
13032 unset($array[$key]);
13039 function body(&$array)
13041 foreach ($array as $key => $value)
13043 if ($this->checked_feeds == $this->max_checked_feeds)
13047 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13049 $this->checked_feeds++;
13050 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent, false, $this->proxy);
13051 if ($this->is_feed($feed))
13057 unset($array[$key]);
13065 class SimplePie_Parser
13070 var $current_column;
13072 var $separator = ' ';
13074 var $namespace = array('');
13075 var $element = array('');
13076 var $xml_base = array('');
13077 var $xml_base_explicit = array(false);
13078 var $xml_lang = array('');
13079 var $data = array();
13080 var $datas = array(array());
13081 var $current_xhtml_construct = -1;
13084 function parse(&$data, $encoding)
13086 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13087 if (strtoupper($encoding) == 'US-ASCII')
13089 $this->encoding = 'UTF-8';
13093 $this->encoding = $encoding;
13097 // UTF-32 Big Endian BOM
13098 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13100 $data = substr($data, 4);
13102 // UTF-32 Little Endian BOM
13103 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13105 $data = substr($data, 4);
13107 // UTF-16 Big Endian BOM
13108 elseif (substr($data, 0, 2) === "\xFE\xFF")
13110 $data = substr($data, 2);
13112 // UTF-16 Little Endian BOM
13113 elseif (substr($data, 0, 2) === "\xFF\xFE")
13115 $data = substr($data, 2);
13118 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13120 $data = substr($data, 3);
13123 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13125 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13126 if ($declaration->parse())
13128 $data = substr($data, $pos + 2);
13129 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13133 $this->error_string = 'SimplePie bug! Please report this!';
13138 // Work around libxml bug
13139 $data = str_replace('<', '<', $data);
13140 $data = str_replace('>', '>', $data);
13141 $data = str_replace('&', '&', $data);
13142 $data = str_replace(''', ''', $data);
13143 $data = str_replace('"', '"', $data);
13147 // Create the parser
13148 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13149 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13150 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13151 xml_set_object($xml, $this);
13152 xml_set_character_data_handler($xml, 'cdata');
13153 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13156 if (!xml_parse($xml, $data, true))
13158 $this->error_code = xml_get_error_code($xml);
13159 $this->error_string = xml_error_string($this->error_code);
13162 $this->current_line = xml_get_current_line_number($xml);
13163 $this->current_column = xml_get_current_column_number($xml);
13164 $this->current_byte = xml_get_current_byte_index($xml);
13165 xml_parser_free($xml);
13169 function get_error_code()
13171 return $this->error_code;
13174 function get_error_string()
13176 return $this->error_string;
13179 function get_current_line()
13181 return $this->current_line;
13184 function get_current_column()
13186 return $this->current_column;
13189 function get_current_byte()
13191 return $this->current_byte;
13194 function get_data()
13196 return $this->data;
13199 function tag_open($parser, $tag, $attributes)
13201 if ($this->feed === 0)
13205 elseif ($this->feed == false)
13207 if (in_array($tag, array(
13208 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13209 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13211 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13222 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13224 $attribs = array();
13225 foreach ($attributes as $name => $value)
13227 list($attrib_namespace, $attribute) = $this->split_ns($name);
13228 $attribs[$attrib_namespace][$attribute] = $value;
13231 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13233 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13234 $this->xml_base_explicit[] = true;
13238 $this->xml_base[] = end($this->xml_base);
13239 $this->xml_base_explicit[] = end($this->xml_base_explicit);
13242 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13244 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13248 $this->xml_lang[] = end($this->xml_lang);
13251 if ($this->current_xhtml_construct >= 0)
13253 $this->current_xhtml_construct++;
13254 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13256 $this->data['data'] .= '<' . end($this->element);
13257 if (isset($attribs['']))
13259 foreach ($attribs[''] as $name => $value)
13261 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13264 $this->data['data'] .= '>';
13269 $this->datas[] =& $this->data;
13270 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13271 $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));
13272 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')
13273 || (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'))
13275 $this->current_xhtml_construct = 0;
13280 function cdata($parser, $cdata)
13282 if ($this->current_xhtml_construct >= 0)
13284 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13286 elseif ($this->feed > 1)
13288 $this->data['data'] .= $cdata;
13292 function tag_close($parser, $tag)
13299 if ($this->current_xhtml_construct >= 0)
13301 $this->current_xhtml_construct--;
13302 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')))
13304 $this->data['data'] .= '</' . end($this->element) . '>';
13307 if ($this->current_xhtml_construct == -1)
13309 $this->data =& $this->datas[$this->feed];
13310 array_pop($this->datas);
13313 array_pop($this->element);
13314 array_pop($this->namespace);
13315 array_pop($this->xml_base);
13316 array_pop($this->xml_base_explicit);
13317 array_pop($this->xml_lang);
13321 function split_ns($string)
13323 static $cache = array();
13324 if (!isset($cache[$string]))
13326 if ($pos = strpos($string, $this->separator))
13328 static $separator_length;
13329 if (!$separator_length)
13331 $separator_length = strlen($this->separator);
13333 $namespace = substr($string, 0, $pos);
13334 $local_name = substr($string, $pos + $separator_length);
13335 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13337 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13340 // Normalize the Media RSS namespaces
13341 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13343 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13345 $cache[$string] = array($namespace, $local_name);
13349 $cache[$string] = array('', $string);
13352 return $cache[$string];
13357 * @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
13359 class SimplePie_Sanitize
13365 var $remove_div = true;
13366 var $image_handler = '';
13367 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13368 var $encode_instead_of_strip = false;
13369 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13370 var $strip_comments = false;
13371 var $output_encoding = 'UTF-8';
13372 var $enable_cache = true;
13373 var $cache_location = './cache';
13374 var $cache_name_function = 'md5';
13375 var $cache_class = 'SimplePie_Cache';
13376 var $file_class = 'SimplePie_File';
13378 var $useragent = '';
13379 var $force_fsockopen = false;
13382 var $replace_url_attributes = array(
13385 'blockquote' => 'cite',
13387 'form' => 'action',
13388 'img' => array('longdesc', 'src'),
13394 function remove_div($enable = true)
13396 $this->remove_div = (bool) $enable;
13399 function set_image_handler($page = false)
13403 $this->image_handler = (string) $page;
13407 $this->image_handler = false;
13411 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13413 if (isset($enable_cache))
13415 $this->enable_cache = (bool) $enable_cache;
13418 if ($cache_location)
13420 $this->cache_location = (string) $cache_location;
13423 if ($cache_name_function)
13425 $this->cache_name_function = (string) $cache_name_function;
13430 $this->cache_class = (string) $cache_class;
13434 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13438 $this->file_class = (string) $file_class;
13443 $this->timeout = (string) $timeout;
13448 $this->useragent = (string) $useragent;
13451 if ($force_fsockopen)
13453 $this->force_fsockopen = (string) $force_fsockopen;
13457 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13461 if (is_array($tags))
13463 $this->strip_htmltags = $tags;
13467 $this->strip_htmltags = explode(',', $tags);
13472 $this->strip_htmltags = false;
13476 function encode_instead_of_strip($encode = false)
13478 $this->encode_instead_of_strip = (bool) $encode;
13481 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13485 if (is_array($attribs))
13487 $this->strip_attributes = $attribs;
13491 $this->strip_attributes = explode(',', $attribs);
13496 $this->strip_attributes = false;
13500 function strip_comments($strip = false)
13502 $this->strip_comments = (bool) $strip;
13505 function set_output_encoding($encoding = 'UTF-8')
13507 $this->output_encoding = (string) $encoding;
13511 * Set element/attribute key/value pairs of HTML attributes
13512 * containing URLs that need to be resolved relative to the feed
13516 * @param array $element_attribute Element/attribute key/value pairs
13518 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'))
13520 $this->replace_url_attributes = (array) $element_attribute;
13523 function sanitize($data, $type, $base = '')
13525 $data = trim($data);
13526 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13528 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13530 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))
13532 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13536 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13540 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13542 $data = base64_decode($data);
13545 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13547 if ($this->remove_div)
13549 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13550 $data = preg_replace('/<\/div>$/', '', $data);
13554 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13558 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13561 if ($this->strip_comments)
13563 $data = SimplePie_Misc::strip_comments($data);
13566 // Strip out HTML tags and attributes that might cause various security problems.
13567 // Based on recommendations by Mark Pilgrim at:
13568 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13569 if ($this->strip_htmltags)
13571 foreach ($this->strip_htmltags as $tag)
13573 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13574 while (preg_match($pcre, $data))
13576 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13581 if ($this->strip_attributes)
13583 foreach ($this->strip_attributes as $attrib)
13585 $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);
13589 // Replace relative URLs
13590 $this->base = $base;
13591 foreach ($this->replace_url_attributes as $element => $attributes)
13593 $data = $this->replace_urls($data, $element, $attributes);
13596 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13597 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13599 $images = SimplePie_Misc::get_element('img', $data);
13600 foreach ($images as $img)
13602 if (isset($img['attribs']['src']['data']))
13604 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13605 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13607 if ($cache->load())
13609 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13610 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13614 $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);
13615 $headers = $file->headers;
13617 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13619 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13621 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13622 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13626 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13634 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13635 $data = trim($data);
13638 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13640 $data = SimplePie_Misc::absolutize_url($data, $base);
13643 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13645 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13648 if ($this->output_encoding != 'UTF-8')
13650 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13656 function replace_urls($data, $tag, $attributes)
13658 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13660 $elements = SimplePie_Misc::get_element($tag, $data);
13661 foreach ($elements as $element)
13663 if (is_array($attributes))
13665 foreach ($attributes as $attribute)
13667 if (isset($element['attribs'][$attribute]['data']))
13669 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13670 $new_element = SimplePie_Misc::element_implode($element);
13671 $data = str_replace($element['full'], $new_element, $data);
13672 $element['full'] = $new_element;
13676 elseif (isset($element['attribs'][$attributes]['data']))
13678 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13679 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13686 function do_strip_htmltags($match)
13688 if ($this->encode_instead_of_strip)
13690 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13692 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13693 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13694 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13698 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13701 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))