5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 define('SIMPLEPIE_NAME', 'SimplePie');
54 define('SIMPLEPIE_VERSION', '1.1.3');
59 define('SIMPLEPIE_BUILD', 20081219);
62 * SimplePie Website URL
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
68 * @see SimplePie::set_useragent()
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
79 * @see SimplePie::set_autodiscovery_level()
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
122 define('SIMPLEPIE_TYPE_NONE', 0);
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
130 * RSS 0.91 (Netscape)
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
135 * RSS 0.91 (Userland)
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
140 * RSS 0.91 (both Netscape and Userland)
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
175 * Non-RDF-based RSS (truly intended as syndication format)
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
202 define('SIMPLEPIE_TYPE_ALL', 1023);
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
225 * base64-encoded construct
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
235 * A construct that might be HTML
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
245 * PCRE for HTML attributes
247 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
250 * PCRE for XML attributes
252 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
257 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
262 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
267 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
272 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
277 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
282 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
285 * RSS 1.0 Content Module Namespace
287 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
291 * (Stupid, I know, but I'm certain it will confuse people less with support.)
293 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
298 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
303 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
306 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
308 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
313 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
316 * Media RSS Namespace
318 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
321 * Wrong Media RSS Namespace
323 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
326 * iTunes RSS Namespace
328 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
333 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
336 * IANA Link Relations Registry
338 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
341 * Whether we're running on PHP5
343 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
348 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
353 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
358 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
361 * fsockopen() file source
363 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
368 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
371 * file_get_contents() file source
373 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
379 * @version "Razzleberry"
380 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
381 * @author Ryan Parman
382 * @author Geoffrey Sneddon
383 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
388 * @var array Raw data
394 * @var mixed Error string
400 * @var object Instance of SimplePie_Sanitize (or other class)
401 * @see SimplePie::set_sanitize_class()
407 * @var string SimplePie Useragent
408 * @see SimplePie::set_useragent()
411 var $useragent = SIMPLEPIE_USERAGENT;
414 * @var string Feed URL
415 * @see SimplePie::set_feed_url()
421 * @var object Instance of SimplePie_File to use as a feed
422 * @see SimplePie::set_file()
428 * @var string Raw feed data
429 * @see SimplePie::set_raw_data()
435 * @var int Timeout for fetching remote files
436 * @see SimplePie::set_timeout()
442 * @var bool Forces fsockopen() to be used for remote files instead
443 * of cURL, even if a new enough version is installed
444 * @see SimplePie::force_fsockopen()
447 var $force_fsockopen = false;
450 * @var bool Force the given data/URL to be treated as a feed no matter what
452 * @see SimplePie::force_feed()
455 var $force_feed = false;
458 * @var bool Enable/Disable XML dump
459 * @see SimplePie::enable_xml_dump()
462 var $xml_dump = false;
465 * @var bool Enable/Disable Caching
466 * @see SimplePie::enable_cache()
472 * @var int Cache duration (in seconds)
473 * @see SimplePie::set_cache_duration()
476 var $cache_duration = 3600;
479 * @var int Auto-discovery cache duration (in seconds)
480 * @see SimplePie::set_autodiscovery_cache_duration()
483 var $autodiscovery_cache_duration = 604800; // 7 Days.
486 * @var string Cache location (relative to executing script)
487 * @see SimplePie::set_cache_location()
490 var $cache_location = './cache';
493 * @var string Function that creates the cache filename
494 * @see SimplePie::set_cache_name_function()
497 var $cache_name_function = 'md5';
500 * @var bool Reorder feed by date descending
501 * @see SimplePie::enable_order_by_date()
504 var $order_by_date = true;
507 * @var mixed Force input encoding to be set to the follow value
508 * (false, or anything type-cast to false, disables this feature)
509 * @see SimplePie::set_input_encoding()
512 var $input_encoding = false;
515 * @var int Feed Autodiscovery Level
516 * @see SimplePie::set_autodiscovery_level()
519 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
522 * @var string Class used for caching feeds
523 * @see SimplePie::set_cache_class()
526 var $cache_class = 'SimplePie_Cache';
529 * @var string Class used for locating feeds
530 * @see SimplePie::set_locator_class()
533 var $locator_class = 'SimplePie_Locator';
536 * @var string Class used for parsing feeds
537 * @see SimplePie::set_parser_class()
540 var $parser_class = 'SimplePie_Parser';
543 * @var string Class used for fetching feeds
544 * @see SimplePie::set_file_class()
547 var $file_class = 'SimplePie_File';
550 * @var string Class used for items
551 * @see SimplePie::set_item_class()
554 var $item_class = 'SimplePie_Item';
557 * @var string Class used for authors
558 * @see SimplePie::set_author_class()
561 var $author_class = 'SimplePie_Author';
564 * @var string Class used for categories
565 * @see SimplePie::set_category_class()
568 var $category_class = 'SimplePie_Category';
571 * @var string Class used for enclosures
572 * @see SimplePie::set_enclosures_class()
575 var $enclosure_class = 'SimplePie_Enclosure';
578 * @var string Class used for Media RSS <media:text> captions
579 * @see SimplePie::set_caption_class()
582 var $caption_class = 'SimplePie_Caption';
585 * @var string Class used for Media RSS <media:copyright>
586 * @see SimplePie::set_copyright_class()
589 var $copyright_class = 'SimplePie_Copyright';
592 * @var string Class used for Media RSS <media:credit>
593 * @see SimplePie::set_credit_class()
596 var $credit_class = 'SimplePie_Credit';
599 * @var string Class used for Media RSS <media:rating>
600 * @see SimplePie::set_rating_class()
603 var $rating_class = 'SimplePie_Rating';
606 * @var string Class used for Media RSS <media:restriction>
607 * @see SimplePie::set_restriction_class()
610 var $restriction_class = 'SimplePie_Restriction';
613 * @var string Class used for content-type sniffing
614 * @see SimplePie::set_content_type_sniffer_class()
617 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
620 * @var string Class used for item sources.
621 * @see SimplePie::set_source_class()
624 var $source_class = 'SimplePie_Source';
627 * @var mixed Set javascript query string parameter (false, or
628 * anything type-cast to false, disables this feature)
629 * @see SimplePie::set_javascript()
632 var $javascript = 'js';
635 * @var int Maximum number of feeds to check with autodiscovery
636 * @see SimplePie::set_max_checked_feeds()
639 var $max_checked_feeds = 10;
642 * @var string Web-accessible path to the handler_favicon.php file.
643 * @see SimplePie::set_favicon_handler()
646 var $favicon_handler = '';
649 * @var string Web-accessible path to the handler_image.php file.
650 * @see SimplePie::set_image_handler()
653 var $image_handler = '';
656 * @var array Stores the URLs when multiple feeds are being initialized.
657 * @see SimplePie::set_feed_url()
660 var $multifeed_url = array();
663 * @var array Stores SimplePie objects when multiple feeds initialized.
666 var $multifeed_objects = array();
669 * @var array Stores the get_object_vars() array for use with multifeeds.
670 * @see SimplePie::set_feed_url()
673 var $config_settings = null;
676 * @var integer Stores the number of items to return per-feed with multifeeds.
677 * @see SimplePie::set_item_limit()
683 * @var array Stores the default attributes to be stripped by strip_attributes().
684 * @see SimplePie::strip_attributes()
687 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
690 * @var array Stores the default tags to be stripped by strip_htmltags().
691 * @see SimplePie::strip_htmltags()
694 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
697 * The SimplePie class contains feed level data and options
699 * There are two ways that you can create a new SimplePie object. The first
700 * is by passing a feed URL as a parameter to the SimplePie constructor
701 * (as well as optionally setting the cache location and cache expiry). This
702 * will initialise the whole feed with all of the default settings, and you
703 * can begin accessing methods and properties immediately.
705 * The second way is to create the SimplePie object with no parameters
706 * at all. This will enable you to set configuration options. After setting
707 * them, you must initialise the feed using $feed->init(). At that point the
708 * object's methods and properties will be available to you. This format is
709 * what is used throughout this documentation.
712 * @since 1.0 Preview Release
713 * @param string $feed_url This is the URL you want to parse.
714 * @param string $cache_location This is where you want the cache to be stored.
715 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
717 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
719 // Other objects, instances created here so we can set options on them
720 $this->sanitize =& new SimplePie_Sanitize;
722 // Set options if they're passed to the constructor
723 if ($cache_location !== null)
725 $this->set_cache_location($cache_location);
728 if ($cache_duration !== null)
730 $this->set_cache_duration($cache_duration);
733 // Only init the script if we're passed a feed URL
734 if ($feed_url !== null)
736 $this->set_feed_url($feed_url);
742 * Used for converting object to a string
744 function __toString()
746 return md5(serialize($this->data));
750 * Remove items that link back to this before destroying this object
752 function __destruct()
754 if (!empty($this->data['items']))
756 foreach ($this->data['items'] as $item)
760 unset($this->data['items']);
762 if (!empty($this->data['ordered_items']))
764 foreach ($this->data['ordered_items'] as $item)
768 unset($this->data['ordered_items']);
773 * Force the given data/URL to be treated as a feed no matter what it
778 * @param bool $enable Force the given data/URL to be treated as a feed
780 function force_feed($enable = false)
782 $this->force_feed = (bool) $enable;
786 * This is the URL of the feed you want to parse.
788 * This allows you to enter the URL of the feed you want to parse, or the
789 * website you want to try to use auto-discovery on. This takes priority
790 * over any set raw data.
792 * You can set multiple feeds to mash together by passing an array instead
793 * of a string for the $url. Remember that with each additional feed comes
794 * additional processing and resources.
797 * @since 1.0 Preview Release
798 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
799 * @see SimplePie::set_raw_data()
801 function set_feed_url($url)
805 $this->multifeed_url = array();
806 foreach ($url as $value)
808 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
813 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
818 * Provides an instance of SimplePie_File to use as a feed
821 * @param object &$file Instance of SimplePie_File (or subclass)
822 * @return bool True on success, false on failure
824 function set_file(&$file)
826 if (is_a($file, 'SimplePie_File'))
828 $this->feed_url = $file->url;
829 $this->file =& $file;
836 * Allows you to use a string of RSS/Atom data instead of a remote feed.
838 * If you have a feed available as a string in PHP, you can tell SimplePie
839 * to parse that data string instead of a remote feed. Any set feed URL
844 * @param string $data RSS or Atom data as a string.
845 * @see SimplePie::set_feed_url()
847 function set_raw_data($data)
849 $this->raw_data = $data;
853 * Allows you to override the default timeout for fetching remote feeds.
855 * This allows you to change the maximum time the feed's server to respond
856 * and send the feed back.
860 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
862 function set_timeout($timeout = 10)
864 $this->timeout = (int) $timeout;
868 * Forces SimplePie to use fsockopen() instead of the preferred cURL
873 * @param bool $enable Force fsockopen() to be used
875 function force_fsockopen($enable = false)
877 $this->force_fsockopen = (bool) $enable;
881 * Outputs the raw XML content of the feed, after it has gone through
882 * SimplePie's filters.
884 * Used only for debugging, this function will output the XML content as
885 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
886 * before trying to parse it. Many parts of the feed are re-written in
887 * memory, and in the end, you have a parsable feed. XML dump shows you the
888 * actual XML that SimplePie tries to parse, which may or may not be very
889 * different from the original feed.
892 * @since 1.0 Preview Release
893 * @param bool $enable Enable XML dump
895 function enable_xml_dump($enable = false)
897 $this->xml_dump = (bool) $enable;
901 * Enables/disables caching in SimplePie.
903 * This option allows you to disable caching all-together in SimplePie.
904 * However, disabling the cache can lead to longer load times.
907 * @since 1.0 Preview Release
908 * @param bool $enable Enable caching
910 function enable_cache($enable = true)
912 $this->cache = (bool) $enable;
916 * Set the length of time (in seconds) that the contents of a feed
920 * @param int $seconds The feed content cache duration.
922 function set_cache_duration($seconds = 3600)
924 $this->cache_duration = (int) $seconds;
928 * Set the length of time (in seconds) that the autodiscovered feed
929 * URL will be cached.
932 * @param int $seconds The autodiscovered feed URL cache duration.
934 function set_autodiscovery_cache_duration($seconds = 604800)
936 $this->autodiscovery_cache_duration = (int) $seconds;
940 * Set the file system location where the cached files should be stored.
943 * @param string $location The file system location.
945 function set_cache_location($location = './cache')
947 $this->cache_location = (string) $location;
951 * Determines whether feed items should be sorted into reverse chronological order.
954 * @param bool $enable Sort as reverse chronological order.
956 function enable_order_by_date($enable = true)
958 $this->order_by_date = (bool) $enable;
962 * Allows you to override the character encoding reported by the feed.
965 * @param string $encoding Character encoding.
967 function set_input_encoding($encoding = false)
971 $this->input_encoding = (string) $encoding;
975 $this->input_encoding = false;
980 * Set how much feed autodiscovery to do
983 * @see SIMPLEPIE_LOCATOR_NONE
984 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
985 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
986 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
987 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
988 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
989 * @see SIMPLEPIE_LOCATOR_ALL
990 * @param int $level Feed Autodiscovery Level (level can be a
991 * combination of the above constants, see bitwise OR operator)
993 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
995 $this->autodiscovery = (int) $level;
999 * Allows you to change which class SimplePie uses for caching.
1000 * Useful when you are overloading or extending SimplePie's default classes.
1003 * @param string $class Name of custom class.
1004 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1005 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1007 function set_cache_class($class = 'SimplePie_Cache')
1009 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1011 $this->cache_class = $class;
1018 * Allows you to change which class SimplePie uses for auto-discovery.
1019 * Useful when you are overloading or extending SimplePie's default classes.
1022 * @param string $class Name of custom class.
1023 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1024 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1026 function set_locator_class($class = 'SimplePie_Locator')
1028 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1030 $this->locator_class = $class;
1037 * Allows you to change which class SimplePie uses for XML parsing.
1038 * Useful when you are overloading or extending SimplePie's default classes.
1041 * @param string $class Name of custom class.
1042 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1043 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1045 function set_parser_class($class = 'SimplePie_Parser')
1047 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1049 $this->parser_class = $class;
1056 * Allows you to change which class SimplePie uses for remote file fetching.
1057 * Useful when you are overloading or extending SimplePie's default classes.
1060 * @param string $class Name of custom class.
1061 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1062 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1064 function set_file_class($class = 'SimplePie_File')
1066 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1068 $this->file_class = $class;
1075 * Allows you to change which class SimplePie uses for data sanitization.
1076 * Useful when you are overloading or extending SimplePie's default classes.
1079 * @param string $class Name of custom class.
1080 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1081 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1083 function set_sanitize_class($class = 'SimplePie_Sanitize')
1085 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1087 $this->sanitize =& new $class;
1094 * Allows you to change which class SimplePie uses for handling feed items.
1095 * Useful when you are overloading or extending SimplePie's default classes.
1098 * @param string $class Name of custom class.
1099 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1100 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1102 function set_item_class($class = 'SimplePie_Item')
1104 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1106 $this->item_class = $class;
1113 * Allows you to change which class SimplePie uses for handling author data.
1114 * Useful when you are overloading or extending SimplePie's default classes.
1117 * @param string $class Name of custom class.
1118 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1119 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1121 function set_author_class($class = 'SimplePie_Author')
1123 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1125 $this->author_class = $class;
1132 * Allows you to change which class SimplePie uses for handling category data.
1133 * Useful when you are overloading or extending SimplePie's default classes.
1136 * @param string $class Name of custom class.
1137 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1138 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1140 function set_category_class($class = 'SimplePie_Category')
1142 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1144 $this->category_class = $class;
1151 * Allows you to change which class SimplePie uses for feed enclosures.
1152 * Useful when you are overloading or extending SimplePie's default classes.
1155 * @param string $class Name of custom class.
1156 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1157 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1159 function set_enclosure_class($class = 'SimplePie_Enclosure')
1161 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1163 $this->enclosure_class = $class;
1170 * Allows you to change which class SimplePie uses for <media:text> captions
1171 * Useful when you are overloading or extending SimplePie's default classes.
1174 * @param string $class Name of custom class.
1175 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1176 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1178 function set_caption_class($class = 'SimplePie_Caption')
1180 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1182 $this->caption_class = $class;
1189 * Allows you to change which class SimplePie uses for <media:copyright>
1190 * Useful when you are overloading or extending SimplePie's default classes.
1193 * @param string $class Name of custom class.
1194 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1195 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1197 function set_copyright_class($class = 'SimplePie_Copyright')
1199 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1201 $this->copyright_class = $class;
1208 * Allows you to change which class SimplePie uses for <media:credit>
1209 * Useful when you are overloading or extending SimplePie's default classes.
1212 * @param string $class Name of custom class.
1213 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1214 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1216 function set_credit_class($class = 'SimplePie_Credit')
1218 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1220 $this->credit_class = $class;
1227 * Allows you to change which class SimplePie uses for <media:rating>
1228 * Useful when you are overloading or extending SimplePie's default classes.
1231 * @param string $class Name of custom class.
1232 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1233 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1235 function set_rating_class($class = 'SimplePie_Rating')
1237 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1239 $this->rating_class = $class;
1246 * Allows you to change which class SimplePie uses for <media:restriction>
1247 * Useful when you are overloading or extending SimplePie's default classes.
1250 * @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_restriction_class($class = 'SimplePie_Restriction')
1256 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1258 $this->restriction_class = $class;
1265 * Allows you to change which class SimplePie uses for content-type sniffing.
1266 * Useful when you are overloading or extending SimplePie's default classes.
1269 * @param string $class Name of custom class.
1270 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1271 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1273 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1275 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1277 $this->content_type_sniffer_class = $class;
1284 * Allows you to change which class SimplePie uses item sources.
1285 * Useful when you are overloading or extending SimplePie's default classes.
1288 * @param string $class Name of custom class.
1289 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1290 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1292 function set_source_class($class = 'SimplePie_Source')
1294 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1296 $this->source_class = $class;
1303 * Allows you to override the default user agent string.
1306 * @param string $ua New user agent string.
1308 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1310 $this->useragent = (string) $ua;
1314 * Set callback function to create cache filename with
1317 * @param mixed $function Callback function
1319 function set_cache_name_function($function = 'md5')
1321 if (is_callable($function))
1323 $this->cache_name_function = $function;
1328 * Set javascript query string parameter
1331 * @param mixed $get Javascript query string parameter
1333 function set_javascript($get = 'js')
1337 $this->javascript = (string) $get;
1341 $this->javascript = false;
1346 * Set options to make SP as fast as possible. Forgoes a
1347 * substantial amount of data sanitization in favor of speed.
1350 * @param bool $set Whether to set them or not
1352 function set_stupidly_fast($set = false)
1356 $this->enable_order_by_date(false);
1357 $this->remove_div(false);
1358 $this->strip_comments(false);
1359 $this->strip_htmltags(false);
1360 $this->strip_attributes(false);
1361 $this->set_image_handler(false);
1366 * Set maximum number of feeds to check with autodiscovery
1369 * @param int $max Maximum number of feeds to check
1371 function set_max_checked_feeds($max = 10)
1373 $this->max_checked_feeds = (int) $max;
1376 function remove_div($enable = true)
1378 $this->sanitize->remove_div($enable);
1381 function strip_htmltags($tags = '', $encode = null)
1385 $tags = $this->strip_htmltags;
1387 $this->sanitize->strip_htmltags($tags);
1388 if ($encode !== null)
1390 $this->sanitize->encode_instead_of_strip($tags);
1394 function encode_instead_of_strip($enable = true)
1396 $this->sanitize->encode_instead_of_strip($enable);
1399 function strip_attributes($attribs = '')
1401 if ($attribs === '')
1403 $attribs = $this->strip_attributes;
1405 $this->sanitize->strip_attributes($attribs);
1408 function set_output_encoding($encoding = 'UTF-8')
1410 $this->sanitize->set_output_encoding($encoding);
1413 function strip_comments($strip = false)
1415 $this->sanitize->strip_comments($strip);
1419 * Set element/attribute key/value pairs of HTML attributes
1420 * containing URLs that need to be resolved relative to the feed
1424 * @param array $element_attribute Element/attribute key/value pairs
1426 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'))
1428 $this->sanitize->set_url_replacements($element_attribute);
1432 * Set the handler to enable the display of cached favicons.
1435 * @param str $page Web-accessible path to the handler_favicon.php file.
1436 * @param str $qs The query string that the value should be passed to.
1438 function set_favicon_handler($page = false, $qs = 'i')
1442 $this->favicon_handler = $page . '?' . $qs . '=';
1446 $this->favicon_handler = '';
1451 * Set the handler to enable the display of cached images.
1454 * @param str $page Web-accessible path to the handler_image.php file.
1455 * @param str $qs The query string that the value should be passed to.
1457 function set_image_handler($page = false, $qs = 'i')
1461 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1465 $this->image_handler = '';
1470 * Set the limit for items returned per-feed with multifeeds.
1473 * @param integer $limit The maximum number of items to return.
1475 function set_item_limit($limit = 0)
1477 $this->item_limit = (int) $limit;
1482 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1486 if (isset($_GET[$this->javascript]))
1488 if (function_exists('ob_gzhandler'))
1490 ob_start('ob_gzhandler');
1492 header('Content-type: text/javascript; charset: UTF-8');
1493 header('Cache-Control: must-revalidate');
1494 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1496 function embed_odeo(link) {
1497 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>');
1500 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1501 if (placeholder != '') {
1502 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1505 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1509 function embed_flash(bgcolor, width, height, link, loop, type) {
1510 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>');
1513 function embed_flv(width, height, link, placeholder, loop, player) {
1514 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>');
1517 function embed_wmedia(width, height, link) {
1518 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1524 // Pass whatever was set with config options over to the sanitizer.
1525 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1526 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1528 if ($this->feed_url !== null || $this->raw_data !== null)
1530 $this->data = array();
1531 $this->multifeed_objects = array();
1534 if ($this->feed_url !== null)
1536 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1537 // Decide whether to enable caching
1538 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1540 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1542 // If it's enabled and we don't want an XML dump, use the cache
1543 if ($cache && !$this->xml_dump)
1546 $this->data = $cache->load();
1547 if (!empty($this->data))
1549 // If the cache is for an outdated build of SimplePie
1550 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1553 $this->data = array();
1555 // If we've hit a collision just rerun it with caching disabled
1556 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1559 $this->data = array();
1561 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1562 elseif (isset($this->data['feed_url']))
1564 // If the autodiscovery cache is still valid use it.
1565 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1567 // Do not need to do feed autodiscovery yet.
1568 if ($this->data['feed_url'] == $this->data['url'])
1571 $this->data = array();
1575 $this->set_feed_url($this->data['feed_url']);
1576 return $this->init();
1580 // Check if the cache has been updated
1581 elseif ($cache->mtime() + $this->cache_duration < time())
1583 // If we have last-modified and/or etag set
1584 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1587 if (isset($this->data['headers']['last-modified']))
1589 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1591 if (isset($this->data['headers']['etag']))
1593 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1595 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1598 if ($file->status_code == 304)
1605 $headers = $file->headers;
1614 // If the cache is still valid, just return true
1620 // If the cache is empty, delete it
1624 $this->data = array();
1627 // 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.
1630 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1632 $file =& $this->file;
1636 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1639 // If the file connection has an error, set SimplePie::error to that and quit
1640 if (!$file->success)
1642 $this->error = $file->error;
1643 if (!empty($this->data))
1653 if (!$this->force_feed)
1655 // Check if the supplied URL is a feed, if it isn't, look for it.
1656 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1657 if (!$locate->is_feed($file))
1659 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1661 if ($file = $locate->find($this->autodiscovery))
1665 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1666 if (!$cache->save($this))
1668 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1670 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1672 $this->feed_url = $file->url;
1676 $this->error = "A feed could not be found at $this->feed_url";
1677 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1684 $headers = $file->headers;
1685 $data = $file->body;
1686 $sniffer = new $this->content_type_sniffer_class($file);
1687 $sniffed = $sniffer->get_type();
1691 $data = $this->raw_data;
1694 // Set up array of possible encodings
1695 $encodings = array();
1697 // First check to see if input has been overridden.
1698 if ($this->input_encoding !== false)
1700 $encodings[] = $this->input_encoding;
1703 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1704 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1706 // RFC 3023 (only applies to sniffed content)
1707 if (isset($sniffed))
1709 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1711 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1713 $encodings[] = strtoupper($charset[1]);
1715 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1716 $encodings[] = 'UTF-8';
1718 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1720 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1722 $encodings[] = $charset[1];
1724 $encodings[] = 'US-ASCII';
1726 // Text MIME-type default
1727 elseif (substr($sniffed, 0, 5) === 'text/')
1729 $encodings[] = 'US-ASCII';
1733 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1734 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1735 $encodings[] = 'UTF-8';
1736 $encodings[] = 'ISO-8859-1';
1738 // There's no point in trying an encoding twice
1739 $encodings = array_unique($encodings);
1741 // If we want the XML, just output that with the most likely encoding and quit
1742 if ($this->xml_dump)
1744 header('Content-type: text/xml; charset=' . $encodings[0]);
1749 // Loop through each possible encoding, till we return something, or run out of possibilities
1750 foreach ($encodings as $encoding)
1752 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1753 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1755 // Create new parser
1756 $parser =& new $this->parser_class();
1758 // If it's parsed fine
1759 if ($parser->parse($utf8_data, 'UTF-8'))
1761 $this->data = $parser->get_data();
1762 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1764 if (isset($headers))
1766 $this->data['headers'] = $headers;
1768 $this->data['build'] = SIMPLEPIE_BUILD;
1770 // Cache the file if caching is enabled
1771 if ($cache && !$cache->save($this))
1773 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1779 $this->error = "A feed could not be found at $this->feed_url";
1780 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1786 // We have an error, just set SimplePie::error to it and quit
1787 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1788 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1791 elseif (!empty($this->multifeed_url))
1795 $this->multifeed_objects = array();
1796 foreach ($this->multifeed_url as $url)
1800 // This keyword needs to defy coding standards for PHP4 compatibility
1801 $this->multifeed_objects[$i] = clone($this);
1805 $this->multifeed_objects[$i] = $this;
1807 $this->multifeed_objects[$i]->set_feed_url($url);
1808 $success |= $this->multifeed_objects[$i]->init();
1811 return (bool) $success;
1820 * Return the error message for the occured error
1823 * @return string Error message
1827 return $this->error;
1830 function get_encoding()
1832 return $this->sanitize->output_encoding;
1835 function handle_content_type($mime = 'text/html')
1837 if (!headers_sent())
1839 $header = "Content-type: $mime;";
1840 if ($this->get_encoding())
1842 $header .= ' charset=' . $this->get_encoding();
1846 $header .= ' charset=UTF-8';
1854 if (!isset($this->data['type']))
1856 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1857 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1859 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1861 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1863 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1865 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1867 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1868 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1869 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1870 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1872 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1874 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1875 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1876 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1877 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1879 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1882 elseif (isset($this->data['child']['']['rss']))
1884 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1885 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1887 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1890 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1891 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1893 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1896 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1900 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1907 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1911 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1915 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1919 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1926 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1929 return $this->data['type'];
1933 * Returns the URL for the favicon of the feed's website.
1935 * @todo Cache atom:icon
1939 function get_favicon()
1941 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1943 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1945 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1947 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1949 if ($this->cache && $this->favicon_handler)
1951 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1952 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1956 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1960 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1962 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1964 $sniffer = new $this->content_type_sniffer_class($file);
1965 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1967 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1969 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1973 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1974 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1982 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1989 * @todo If we have a perm redirect we should return the new URL
1990 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1991 * @todo Also, |atom:link|@rel=self
1993 function subscribe_url()
1995 if ($this->feed_url !== null)
1997 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2005 function subscribe_feed()
2007 if ($this->feed_url !== null)
2009 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2017 function subscribe_outlook()
2019 if ($this->feed_url !== null)
2021 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2029 function subscribe_podcast()
2031 if ($this->feed_url !== null)
2033 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2041 function subscribe_itunes()
2043 if ($this->feed_url !== null)
2045 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2054 * Creates the subscribe_* methods' return data
2057 * @param string $feed_url String to prefix to the feed URL
2058 * @param string $site_url String to prefix to the site URL (and
2059 * suffix to the feed URL)
2060 * @return mixed URL if feed exists, false otherwise
2062 function subscribe_service($feed_url, $site_url = null)
2064 if ($this->subscribe_url())
2066 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2067 if ($site_url !== null && $this->get_link() !== null)
2069 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2079 function subscribe_aol()
2081 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2084 function subscribe_bloglines()
2086 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2089 function subscribe_eskobo()
2091 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2094 function subscribe_feedfeeds()
2096 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2099 function subscribe_feedster()
2101 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2104 function subscribe_google()
2106 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2109 function subscribe_gritwire()
2111 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2114 function subscribe_msn()
2116 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2119 function subscribe_netvibes()
2121 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2124 function subscribe_newsburst()
2126 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2129 function subscribe_newsgator()
2131 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2134 function subscribe_odeo()
2136 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2139 function subscribe_podnova()
2141 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2144 function subscribe_rojo()
2146 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2149 function subscribe_yahoo()
2151 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2154 function get_feed_tags($namespace, $tag)
2156 $type = $this->get_type();
2157 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2159 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2161 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2164 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2166 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2168 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2171 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2173 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2175 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2178 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2180 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2182 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2188 function get_channel_tags($namespace, $tag)
2190 $type = $this->get_type();
2191 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2193 if ($return = $this->get_feed_tags($namespace, $tag))
2198 if ($type & SIMPLEPIE_TYPE_RSS_10)
2200 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2202 if (isset($channel[0]['child'][$namespace][$tag]))
2204 return $channel[0]['child'][$namespace][$tag];
2208 if ($type & SIMPLEPIE_TYPE_RSS_090)
2210 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2212 if (isset($channel[0]['child'][$namespace][$tag]))
2214 return $channel[0]['child'][$namespace][$tag];
2218 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2220 if ($channel = $this->get_feed_tags('', 'channel'))
2222 if (isset($channel[0]['child'][$namespace][$tag]))
2224 return $channel[0]['child'][$namespace][$tag];
2231 function get_image_tags($namespace, $tag)
2233 $type = $this->get_type();
2234 if ($type & SIMPLEPIE_TYPE_RSS_10)
2236 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2238 if (isset($image[0]['child'][$namespace][$tag]))
2240 return $image[0]['child'][$namespace][$tag];
2244 if ($type & SIMPLEPIE_TYPE_RSS_090)
2246 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2248 if (isset($image[0]['child'][$namespace][$tag]))
2250 return $image[0]['child'][$namespace][$tag];
2254 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2256 if ($image = $this->get_channel_tags('', 'image'))
2258 if (isset($image[0]['child'][$namespace][$tag]))
2260 return $image[0]['child'][$namespace][$tag];
2267 function get_base($element = array())
2269 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2271 return $element['xml_base'];
2273 elseif ($this->get_link() !== null)
2275 return $this->get_link();
2279 return $this->subscribe_url();
2283 function sanitize($data, $type, $base = '')
2285 return $this->sanitize->sanitize($data, $type, $base);
2288 function get_title()
2290 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2292 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2294 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2296 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2306 elseif ($return = $this->get_channel_tags('', 'title'))
2308 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2310 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2312 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2314 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2316 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2324 function get_category($key = 0)
2326 $categories = $this->get_categories();
2327 if (isset($categories[$key]))
2329 return $categories[$key];
2337 function get_categories()
2339 $categories = array();
2341 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2346 if (isset($category['attribs']['']['term']))
2348 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2350 if (isset($category['attribs']['']['scheme']))
2352 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2354 if (isset($category['attribs']['']['label']))
2356 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2358 $categories[] =& new $this->category_class($term, $scheme, $label);
2360 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2362 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2364 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2366 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2368 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2370 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2373 if (!empty($categories))
2375 return SimplePie_Misc::array_unique($categories);
2383 function get_author($key = 0)
2385 $authors = $this->get_authors();
2386 if (isset($authors[$key]))
2388 return $authors[$key];
2396 function get_authors()
2399 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2404 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2406 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2408 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2410 $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]));
2412 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2414 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2416 if ($name !== null || $email !== null || $uri !== null)
2418 $authors[] =& new $this->author_class($name, $uri, $email);
2421 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2426 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2428 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2430 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2432 $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]));
2434 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2436 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2438 if ($name !== null || $email !== null || $url !== null)
2440 $authors[] =& new $this->author_class($name, $url, $email);
2443 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2445 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2447 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2449 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2451 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2453 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2456 if (!empty($authors))
2458 return SimplePie_Misc::array_unique($authors);
2466 function get_contributor($key = 0)
2468 $contributors = $this->get_contributors();
2469 if (isset($contributors[$key]))
2471 return $contributors[$key];
2479 function get_contributors()
2481 $contributors = array();
2482 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2487 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2489 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2491 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2493 $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]));
2495 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2497 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2499 if ($name !== null || $email !== null || $uri !== null)
2501 $contributors[] =& new $this->author_class($name, $uri, $email);
2504 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2509 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2511 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2513 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2515 $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]));
2517 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2519 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2521 if ($name !== null || $email !== null || $url !== null)
2523 $contributors[] =& new $this->author_class($name, $url, $email);
2527 if (!empty($contributors))
2529 return SimplePie_Misc::array_unique($contributors);
2537 function get_link($key = 0, $rel = 'alternate')
2539 $links = $this->get_links($rel);
2540 if (isset($links[$key]))
2542 return $links[$key];
2551 * Added for parity between the parent-level and the item/entry-level.
2553 function get_permalink()
2555 return $this->get_link(0);
2558 function get_links($rel = 'alternate')
2560 if (!isset($this->data['links']))
2562 $this->data['links'] = array();
2563 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2565 foreach ($links as $link)
2567 if (isset($link['attribs']['']['href']))
2569 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2570 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2574 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2576 foreach ($links as $link)
2578 if (isset($link['attribs']['']['href']))
2580 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2581 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2586 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2588 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2590 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2592 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2594 if ($links = $this->get_channel_tags('', 'link'))
2596 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2599 $keys = array_keys($this->data['links']);
2600 foreach ($keys as $key)
2602 if (SimplePie_Misc::is_isegment_nz_nc($key))
2604 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2606 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2607 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2611 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2614 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2616 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2618 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2622 if (isset($this->data['links'][$rel]))
2624 return $this->data['links'][$rel];
2632 function get_description()
2634 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2636 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2638 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2640 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2642 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2644 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2646 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2648 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2650 elseif ($return = $this->get_channel_tags('', 'description'))
2652 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2654 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2656 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2658 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2660 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2662 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2664 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2666 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2668 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2676 function get_copyright()
2678 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2680 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2684 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2686 elseif ($return = $this->get_channel_tags('', 'copyright'))
2688 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2690 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2692 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2694 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2704 function get_language()
2706 if ($return = $this->get_channel_tags('', 'language'))
2708 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2710 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2712 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2714 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2716 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2718 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2720 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2722 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2724 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2726 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2728 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2730 elseif (isset($this->data['headers']['content-language']))
2732 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2740 function get_latitude()
2742 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2744 return (float) $return[0]['data'];
2746 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2748 return (float) $match[1];
2756 function get_longitude()
2758 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2760 return (float) $return[0]['data'];
2762 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2764 return (float) $return[0]['data'];
2766 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2768 return (float) $match[2];
2776 function get_image_title()
2778 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2780 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2782 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2786 elseif ($return = $this->get_image_tags('', 'title'))
2788 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2790 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2792 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2794 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2796 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2804 function get_image_url()
2806 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2808 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2810 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2812 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2814 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2816 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2818 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2820 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2822 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2824 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2826 elseif ($return = $this->get_image_tags('', 'url'))
2828 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2836 function get_image_link()
2838 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2840 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2842 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2844 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2846 elseif ($return = $this->get_image_tags('', 'link'))
2848 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2856 function get_image_width()
2858 if ($return = $this->get_image_tags('', 'width'))
2860 return round($return[0]['data']);
2862 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2872 function get_image_height()
2874 if ($return = $this->get_image_tags('', 'height'))
2876 return round($return[0]['data']);
2878 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2888 function get_item_quantity($max = 0)
2890 $qty = count($this->get_items());
2897 return ($qty > $max) ? $max : $qty;
2901 function get_item($key = 0)
2903 $items = $this->get_items();
2904 if (isset($items[$key]))
2906 return $items[$key];
2914 function get_items($start = 0, $end = 0)
2916 if (!empty($this->multifeed_objects))
2918 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2920 elseif (!isset($this->data['items']))
2922 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2924 $keys = array_keys($items);
2925 foreach ($keys as $key)
2927 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2930 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2932 $keys = array_keys($items);
2933 foreach ($keys as $key)
2935 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2938 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2940 $keys = array_keys($items);
2941 foreach ($keys as $key)
2943 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2946 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2948 $keys = array_keys($items);
2949 foreach ($keys as $key)
2951 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2954 if ($items = $this->get_channel_tags('', 'item'))
2956 $keys = array_keys($items);
2957 foreach ($keys as $key)
2959 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2964 if (!empty($this->data['items']))
2966 // If we want to order it by date, check if all items have a date, and then sort it
2967 if ($this->order_by_date)
2969 if (!isset($this->data['ordered_items']))
2972 foreach ($this->data['items'] as $item)
2974 if (!$item->get_date('U'))
2981 $this->data['ordered_items'] = $this->data['items'];
2984 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2987 $items = $this->data['ordered_items'];
2991 $items = $this->data['items'];
2994 // Slice the data as desired
2997 return array_slice($items, $start);
3001 return array_slice($items, $start, $end);
3010 function sort_items($a, $b)
3012 return $a->get_date('U') <= $b->get_date('U');
3015 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3017 if (is_array($urls) && sizeof($urls) > 0)
3020 foreach ($urls as $arg)
3022 if (is_a($arg, 'SimplePie'))
3024 $items = array_merge($items, $arg->get_items(0, $limit));
3028 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3033 foreach ($items as $item)
3035 if (!$item->get_date('U'))
3044 usort($items, array('SimplePie', 'sort_items'));
3049 return array_slice($items, $start);
3053 return array_slice($items, $start, $end);
3058 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3064 class SimplePie_Item
3067 var $data = array();
3069 function SimplePie_Item($feed, $data)
3071 $this->feed = $feed;
3072 $this->data = $data;
3075 function __toString()
3077 return md5(serialize($this->data));
3081 * Remove items that link back to this before destroying this object
3083 function __destruct()
3088 function get_item_tags($namespace, $tag)
3090 if (isset($this->data['child'][$namespace][$tag]))
3092 return $this->data['child'][$namespace][$tag];
3100 function get_base($element = array())
3102 return $this->feed->get_base($element);
3105 function sanitize($data, $type, $base = '')
3107 return $this->feed->sanitize($data, $type, $base);
3115 function get_id($hash = false)
3119 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3121 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3123 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3125 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3127 elseif ($return = $this->get_item_tags('', 'guid'))
3129 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3131 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3133 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3135 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3137 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3139 elseif (($return = $this->get_permalink()) !== null)
3143 elseif (($return = $this->get_title()) !== null)
3148 if ($this->get_permalink() !== null || $this->get_title() !== null)
3150 return md5($this->get_permalink() . $this->get_title());
3154 return md5(serialize($this->data));
3158 function get_title()
3160 if (!isset($this->data['title']))
3162 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3164 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3166 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3168 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3170 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3172 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3176 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3178 elseif ($return = $this->get_item_tags('', 'title'))
3180 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3182 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3184 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3186 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3188 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3192 $this->data['title'] = null;
3195 return $this->data['title'];
3198 function get_description($description_only = false)
3200 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3202 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3204 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3206 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3210 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3212 elseif ($return = $this->get_item_tags('', 'description'))
3214 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3216 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3218 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3220 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3222 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3224 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3226 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3228 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3230 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3232 elseif (!$description_only)
3234 return $this->get_content(true);
3242 function get_content($content_only = false)
3244 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3246 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3248 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3250 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3252 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3254 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3256 elseif (!$content_only)
3258 return $this->get_description(true);
3266 function get_category($key = 0)
3268 $categories = $this->get_categories();
3269 if (isset($categories[$key]))
3271 return $categories[$key];
3279 function get_categories()
3281 $categories = array();
3283 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3288 if (isset($category['attribs']['']['term']))
3290 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3292 if (isset($category['attribs']['']['scheme']))
3294 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3296 if (isset($category['attribs']['']['label']))
3298 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3300 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3302 foreach ((array) $this->get_item_tags('', 'category') as $category)
3304 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3306 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3308 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3310 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3312 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3315 if (!empty($categories))
3317 return SimplePie_Misc::array_unique($categories);
3325 function get_author($key = 0)
3327 $authors = $this->get_authors();
3328 if (isset($authors[$key]))
3330 return $authors[$key];
3338 function get_contributor($key = 0)
3340 $contributors = $this->get_contributors();
3341 if (isset($contributors[$key]))
3343 return $contributors[$key];
3351 function get_contributors()
3353 $contributors = array();
3354 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3359 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3361 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3363 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3365 $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]));
3367 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3369 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3371 if ($name !== null || $email !== null || $uri !== null)
3373 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3376 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3381 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3383 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3385 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3387 $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]));
3389 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3391 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3393 if ($name !== null || $email !== null || $url !== null)
3395 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3399 if (!empty($contributors))
3401 return SimplePie_Misc::array_unique($contributors);
3410 * @todo Atom inheritance (item author, source author, feed author)
3412 function get_authors()
3415 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3420 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3422 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3424 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3426 $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]));
3428 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3430 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3432 if ($name !== null || $email !== null || $uri !== null)
3434 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3437 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3442 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3444 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3446 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3448 $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]));
3450 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3452 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3454 if ($name !== null || $email !== null || $url !== null)
3456 $authors[] =& new $this->feed->author_class($name, $url, $email);
3459 if ($author = $this->get_item_tags('', 'author'))
3461 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3463 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3465 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3467 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3469 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3471 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3473 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3476 if (!empty($authors))
3478 return SimplePie_Misc::array_unique($authors);
3480 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3484 elseif ($authors = $this->feed->get_authors())
3494 function get_copyright()
3496 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3498 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3500 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3502 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3504 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3506 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3514 function get_date($date_format = 'j F Y, g:i a')
3516 if (!isset($this->data['date']))
3518 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3520 $this->data['date']['raw'] = $return[0]['data'];
3522 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3524 $this->data['date']['raw'] = $return[0]['data'];
3526 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3528 $this->data['date']['raw'] = $return[0]['data'];
3530 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3532 $this->data['date']['raw'] = $return[0]['data'];
3534 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3536 $this->data['date']['raw'] = $return[0]['data'];
3538 elseif ($return = $this->get_item_tags('', 'pubDate'))
3540 $this->data['date']['raw'] = $return[0]['data'];
3542 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3544 $this->data['date']['raw'] = $return[0]['data'];
3546 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3548 $this->data['date']['raw'] = $return[0]['data'];
3551 if (!empty($this->data['date']['raw']))
3553 $parser = SimplePie_Parse_Date::get();
3554 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3558 $this->data['date'] = null;
3561 if ($this->data['date'])
3563 $date_format = (string) $date_format;
3564 switch ($date_format)
3567 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3570 return $this->data['date']['parsed'];
3573 return date($date_format, $this->data['date']['parsed']);
3582 function get_local_date($date_format = '%c')
3586 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3588 elseif (($date = $this->get_date('U')) !== null)
3590 return strftime($date_format, $date);
3598 function get_permalink()
3600 $link = $this->get_link();
3601 $enclosure = $this->get_enclosure(0);
3606 elseif ($enclosure !== null)
3608 return $enclosure->get_link();
3616 function get_link($key = 0, $rel = 'alternate')
3618 $links = $this->get_links($rel);
3619 if ($links[$key] !== null)
3621 return $links[$key];
3629 function get_links($rel = 'alternate')
3631 if (!isset($this->data['links']))
3633 $this->data['links'] = array();
3634 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3636 if (isset($link['attribs']['']['href']))
3638 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3639 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3643 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3645 if (isset($link['attribs']['']['href']))
3647 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3648 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3651 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3653 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3655 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3657 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3659 if ($links = $this->get_item_tags('', 'link'))
3661 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3663 if ($links = $this->get_item_tags('', 'guid'))
3665 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3667 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3671 $keys = array_keys($this->data['links']);
3672 foreach ($keys as $key)
3674 if (SimplePie_Misc::is_isegment_nz_nc($key))
3676 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3678 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3679 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3683 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3686 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3688 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3690 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3693 if (isset($this->data['links'][$rel]))
3695 return $this->data['links'][$rel];
3704 * @todo Add ability to prefer one type of content over another (in a media group).
3706 function get_enclosure($key = 0, $prefer = null)
3708 $enclosures = $this->get_enclosures();
3709 if (isset($enclosures[$key]))
3711 return $enclosures[$key];
3720 * Grabs all available enclosures (podcasts, etc.)
3722 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3724 * 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.
3726 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3727 * @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).
3729 function get_enclosures()
3731 if (!isset($this->data['enclosures']))
3733 $this->data['enclosures'] = array();
3736 $captions_parent = null;
3737 $categories_parent = null;
3738 $copyrights_parent = null;
3739 $credits_parent = null;
3740 $description_parent = null;
3741 $duration_parent = null;
3742 $hashes_parent = null;
3743 $keywords_parent = null;
3744 $player_parent = null;
3745 $ratings_parent = null;
3746 $restrictions_parent = null;
3747 $thumbnails_parent = null;
3748 $title_parent = null;
3750 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3751 $parent = $this->get_feed();
3754 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3756 foreach ($captions as $caption)
3758 $caption_type = null;
3759 $caption_lang = null;
3760 $caption_startTime = null;
3761 $caption_endTime = null;
3762 $caption_text = null;
3763 if (isset($caption['attribs']['']['type']))
3765 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3767 if (isset($caption['attribs']['']['lang']))
3769 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3771 if (isset($caption['attribs']['']['start']))
3773 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3775 if (isset($caption['attribs']['']['end']))
3777 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3779 if (isset($caption['data']))
3781 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3783 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3786 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3788 foreach ($captions as $caption)
3790 $caption_type = null;
3791 $caption_lang = null;
3792 $caption_startTime = null;
3793 $caption_endTime = null;
3794 $caption_text = null;
3795 if (isset($caption['attribs']['']['type']))
3797 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3799 if (isset($caption['attribs']['']['lang']))
3801 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3803 if (isset($caption['attribs']['']['start']))
3805 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3807 if (isset($caption['attribs']['']['end']))
3809 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3811 if (isset($caption['data']))
3813 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3815 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3818 if (is_array($captions_parent))
3820 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3824 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3829 if (isset($category['data']))
3831 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3833 if (isset($category['attribs']['']['scheme']))
3835 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3839 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3841 if (isset($category['attribs']['']['label']))
3843 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3845 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3847 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3852 if (isset($category['data']))
3854 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3856 if (isset($category['attribs']['']['scheme']))
3858 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3862 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3864 if (isset($category['attribs']['']['label']))
3866 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3868 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3870 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3873 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3875 if (isset($category['attribs']['']['text']))
3877 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3879 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3881 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3883 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3885 if (isset($subcategory['attribs']['']['text']))
3887 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3889 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3893 if (is_array($categories_parent))
3895 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3899 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3901 $copyright_url = null;
3902 $copyright_label = null;
3903 if (isset($copyright[0]['attribs']['']['url']))
3905 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3907 if (isset($copyright[0]['data']))
3909 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3911 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3913 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3915 $copyright_url = null;
3916 $copyright_label = null;
3917 if (isset($copyright[0]['attribs']['']['url']))
3919 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3921 if (isset($copyright[0]['data']))
3923 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3925 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3929 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3931 foreach ($credits as $credit)
3933 $credit_role = null;
3934 $credit_scheme = null;
3935 $credit_name = null;
3936 if (isset($credit['attribs']['']['role']))
3938 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3940 if (isset($credit['attribs']['']['scheme']))
3942 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3946 $credit_scheme = 'urn:ebu';
3948 if (isset($credit['data']))
3950 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3952 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3955 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3957 foreach ($credits as $credit)
3959 $credit_role = null;
3960 $credit_scheme = null;
3961 $credit_name = null;
3962 if (isset($credit['attribs']['']['role']))
3964 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3966 if (isset($credit['attribs']['']['scheme']))
3968 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 $credit_scheme = 'urn:ebu';
3974 if (isset($credit['data']))
3976 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3978 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3981 if (is_array($credits_parent))
3983 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3987 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3989 if (isset($description_parent[0]['data']))
3991 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3994 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3996 if (isset($description_parent[0]['data']))
3998 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4003 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4008 if (isset($duration_parent[0]['data']))
4010 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4011 if (sizeof($temp) > 0)
4013 (int) $seconds = array_pop($temp);
4015 if (sizeof($temp) > 0)
4017 (int) $minutes = array_pop($temp);
4018 $seconds += $minutes * 60;
4020 if (sizeof($temp) > 0)
4022 (int) $hours = array_pop($temp);
4023 $seconds += $hours * 3600;
4026 $duration_parent = $seconds;
4031 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4033 foreach ($hashes_iterator as $hash)
4037 if (isset($hash['data']))
4039 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4041 if (isset($hash['attribs']['']['algo']))
4043 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4049 $hashes_parent[] = $algo.':'.$value;
4052 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4054 foreach ($hashes_iterator as $hash)
4058 if (isset($hash['data']))
4060 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4062 if (isset($hash['attribs']['']['algo']))
4064 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4070 $hashes_parent[] = $algo.':'.$value;
4073 if (is_array($hashes_parent))
4075 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4079 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4081 if (isset($keywords[0]['data']))
4083 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4084 foreach ($temp as $word)
4086 $keywords_parent[] = trim($word);
4091 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4093 if (isset($keywords[0]['data']))
4095 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4096 foreach ($temp as $word)
4098 $keywords_parent[] = trim($word);
4103 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4105 if (isset($keywords[0]['data']))
4107 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4108 foreach ($temp as $word)
4110 $keywords_parent[] = trim($word);
4115 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4117 if (isset($keywords[0]['data']))
4119 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4120 foreach ($temp as $word)
4122 $keywords_parent[] = trim($word);
4127 if (is_array($keywords_parent))
4129 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4133 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4135 if (isset($player_parent[0]['attribs']['']['url']))
4137 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4140 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4142 if (isset($player_parent[0]['attribs']['']['url']))
4144 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4149 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4151 foreach ($ratings as $rating)
4153 $rating_scheme = null;
4154 $rating_value = null;
4155 if (isset($rating['attribs']['']['scheme']))
4157 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4161 $rating_scheme = 'urn:simple';
4163 if (isset($rating['data']))
4165 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4167 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4170 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4172 foreach ($ratings as $rating)
4174 $rating_scheme = 'urn:itunes';
4175 $rating_value = null;
4176 if (isset($rating['data']))
4178 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4180 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4183 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4185 foreach ($ratings as $rating)
4187 $rating_scheme = null;
4188 $rating_value = null;
4189 if (isset($rating['attribs']['']['scheme']))
4191 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4195 $rating_scheme = 'urn:simple';
4197 if (isset($rating['data']))
4199 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4201 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4204 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4206 foreach ($ratings as $rating)
4208 $rating_scheme = 'urn:itunes';
4209 $rating_value = null;
4210 if (isset($rating['data']))
4212 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4214 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4217 if (is_array($ratings_parent))
4219 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4223 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4225 foreach ($restrictions as $restriction)
4227 $restriction_relationship = null;
4228 $restriction_type = null;
4229 $restriction_value = null;
4230 if (isset($restriction['attribs']['']['relationship']))
4232 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4234 if (isset($restriction['attribs']['']['type']))
4236 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4238 if (isset($restriction['data']))
4240 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4242 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4245 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4247 foreach ($restrictions as $restriction)
4249 $restriction_relationship = 'allow';
4250 $restriction_type = null;
4251 $restriction_value = 'itunes';
4252 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4254 $restriction_relationship = 'deny';
4256 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4259 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4261 foreach ($restrictions as $restriction)
4263 $restriction_relationship = null;
4264 $restriction_type = null;
4265 $restriction_value = null;
4266 if (isset($restriction['attribs']['']['relationship']))
4268 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4270 if (isset($restriction['attribs']['']['type']))
4272 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4274 if (isset($restriction['data']))
4276 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4278 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4281 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4283 foreach ($restrictions as $restriction)
4285 $restriction_relationship = 'allow';
4286 $restriction_type = null;
4287 $restriction_value = 'itunes';
4288 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4290 $restriction_relationship = 'deny';
4292 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4295 if (is_array($restrictions_parent))
4297 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4301 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4303 foreach ($thumbnails as $thumbnail)
4305 if (isset($thumbnail['attribs']['']['url']))
4307 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4311 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4313 foreach ($thumbnails as $thumbnail)
4315 if (isset($thumbnail['attribs']['']['url']))
4317 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4323 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4325 if (isset($title_parent[0]['data']))
4327 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4330 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4332 if (isset($title_parent[0]['data']))
4334 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4352 $samplingrate = null;
4362 $description = null;
4367 $restrictions = null;
4371 // If we have media:group tags, loop through them.
4372 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4374 // If we have media:content tags, loop through them.
4375 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4377 if (isset($content['attribs']['']['url']))
4390 $samplingrate = null;
4400 $description = null;
4405 $restrictions = null;
4409 // Start checking the attributes of media:content
4410 if (isset($content['attribs']['']['bitrate']))
4412 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4414 if (isset($content['attribs']['']['channels']))
4416 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4418 if (isset($content['attribs']['']['duration']))
4420 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4424 $duration = $duration_parent;
4426 if (isset($content['attribs']['']['expression']))
4428 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4430 if (isset($content['attribs']['']['framerate']))
4432 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4434 if (isset($content['attribs']['']['height']))
4436 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4438 if (isset($content['attribs']['']['lang']))
4440 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4442 if (isset($content['attribs']['']['fileSize']))
4444 $length = ceil($content['attribs']['']['fileSize']);
4446 if (isset($content['attribs']['']['medium']))
4448 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4450 if (isset($content['attribs']['']['samplingrate']))
4452 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4454 if (isset($content['attribs']['']['type']))
4456 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4458 if (isset($content['attribs']['']['width']))
4460 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4462 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4464 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4467 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4469 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4471 $caption_type = null;
4472 $caption_lang = null;
4473 $caption_startTime = null;
4474 $caption_endTime = null;
4475 $caption_text = null;
4476 if (isset($caption['attribs']['']['type']))
4478 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4480 if (isset($caption['attribs']['']['lang']))
4482 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4484 if (isset($caption['attribs']['']['start']))
4486 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4488 if (isset($caption['attribs']['']['end']))
4490 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4492 if (isset($caption['data']))
4494 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4496 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4498 if (is_array($captions))
4500 $captions = array_values(SimplePie_Misc::array_unique($captions));
4503 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4505 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4507 $caption_type = null;
4508 $caption_lang = null;
4509 $caption_startTime = null;
4510 $caption_endTime = null;
4511 $caption_text = null;
4512 if (isset($caption['attribs']['']['type']))
4514 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4516 if (isset($caption['attribs']['']['lang']))
4518 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4520 if (isset($caption['attribs']['']['start']))
4522 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4524 if (isset($caption['attribs']['']['end']))
4526 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4528 if (isset($caption['data']))
4530 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4532 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4534 if (is_array($captions))
4536 $captions = array_values(SimplePie_Misc::array_unique($captions));
4541 $captions = $captions_parent;
4545 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4547 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4552 if (isset($category['data']))
4554 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4556 if (isset($category['attribs']['']['scheme']))
4558 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4562 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4564 if (isset($category['attribs']['']['label']))
4566 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4568 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4571 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4573 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4578 if (isset($category['data']))
4580 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4582 if (isset($category['attribs']['']['scheme']))
4584 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4588 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4590 if (isset($category['attribs']['']['label']))
4592 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4594 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4597 if (is_array($categories) && is_array($categories_parent))
4599 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4601 elseif (is_array($categories))
4603 $categories = array_values(SimplePie_Misc::array_unique($categories));
4605 elseif (is_array($categories_parent))
4607 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4611 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4613 $copyright_url = null;
4614 $copyright_label = null;
4615 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4617 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4619 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4621 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4623 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4625 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4627 $copyright_url = null;
4628 $copyright_label = null;
4629 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4631 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4633 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4635 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4637 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4641 $copyrights = $copyrights_parent;
4645 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4647 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4649 $credit_role = null;
4650 $credit_scheme = null;
4651 $credit_name = null;
4652 if (isset($credit['attribs']['']['role']))
4654 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4656 if (isset($credit['attribs']['']['scheme']))
4658 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4662 $credit_scheme = 'urn:ebu';
4664 if (isset($credit['data']))
4666 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4668 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4670 if (is_array($credits))
4672 $credits = array_values(SimplePie_Misc::array_unique($credits));
4675 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4677 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4679 $credit_role = null;
4680 $credit_scheme = null;
4681 $credit_name = null;
4682 if (isset($credit['attribs']['']['role']))
4684 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4686 if (isset($credit['attribs']['']['scheme']))
4688 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4692 $credit_scheme = 'urn:ebu';
4694 if (isset($credit['data']))
4696 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4698 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4700 if (is_array($credits))
4702 $credits = array_values(SimplePie_Misc::array_unique($credits));
4707 $credits = $credits_parent;
4711 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4713 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4715 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4717 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4721 $description = $description_parent;
4725 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4727 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4731 if (isset($hash['data']))
4733 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4735 if (isset($hash['attribs']['']['algo']))
4737 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4743 $hashes[] = $algo.':'.$value;
4745 if (is_array($hashes))
4747 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4750 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4752 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4756 if (isset($hash['data']))
4758 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4760 if (isset($hash['attribs']['']['algo']))
4762 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4768 $hashes[] = $algo.':'.$value;
4770 if (is_array($hashes))
4772 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4777 $hashes = $hashes_parent;
4781 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4783 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4785 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4786 foreach ($temp as $word)
4788 $keywords[] = trim($word);
4792 if (is_array($keywords))
4794 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4797 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4799 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4801 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4802 foreach ($temp as $word)
4804 $keywords[] = trim($word);
4808 if (is_array($keywords))
4810 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4815 $keywords = $keywords_parent;
4819 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4821 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4823 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4825 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4829 $player = $player_parent;
4833 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4835 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4837 $rating_scheme = null;
4838 $rating_value = null;
4839 if (isset($rating['attribs']['']['scheme']))
4841 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4845 $rating_scheme = 'urn:simple';
4847 if (isset($rating['data']))
4849 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4851 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4853 if (is_array($ratings))
4855 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4858 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4860 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4862 $rating_scheme = null;
4863 $rating_value = null;
4864 if (isset($rating['attribs']['']['scheme']))
4866 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4870 $rating_scheme = 'urn:simple';
4872 if (isset($rating['data']))
4874 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4876 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4878 if (is_array($ratings))
4880 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4885 $ratings = $ratings_parent;
4889 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4891 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4893 $restriction_relationship = null;
4894 $restriction_type = null;
4895 $restriction_value = null;
4896 if (isset($restriction['attribs']['']['relationship']))
4898 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4900 if (isset($restriction['attribs']['']['type']))
4902 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4904 if (isset($restriction['data']))
4906 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4908 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4910 if (is_array($restrictions))
4912 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4915 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4917 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4919 $restriction_relationship = null;
4920 $restriction_type = null;
4921 $restriction_value = null;
4922 if (isset($restriction['attribs']['']['relationship']))
4924 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4926 if (isset($restriction['attribs']['']['type']))
4928 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4930 if (isset($restriction['data']))
4932 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4934 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4936 if (is_array($restrictions))
4938 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4943 $restrictions = $restrictions_parent;
4947 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4949 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4951 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4953 if (is_array($thumbnails))
4955 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4958 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4960 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4962 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4964 if (is_array($thumbnails))
4966 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4971 $thumbnails = $thumbnails_parent;
4975 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4977 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4979 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4981 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4985 $title = $title_parent;
4988 $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);
4993 // If we have standalone media:content tags, loop through them.
4994 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4996 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4998 if (isset($content['attribs']['']['url']))
5011 $samplingrate = null;
5021 $description = null;
5026 $restrictions = null;
5030 // Start checking the attributes of media:content
5031 if (isset($content['attribs']['']['bitrate']))
5033 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5035 if (isset($content['attribs']['']['channels']))
5037 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5039 if (isset($content['attribs']['']['duration']))
5041 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5045 $duration = $duration_parent;
5047 if (isset($content['attribs']['']['expression']))
5049 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5051 if (isset($content['attribs']['']['framerate']))
5053 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5055 if (isset($content['attribs']['']['height']))
5057 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5059 if (isset($content['attribs']['']['lang']))
5061 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5063 if (isset($content['attribs']['']['fileSize']))
5065 $length = ceil($content['attribs']['']['fileSize']);
5067 if (isset($content['attribs']['']['medium']))
5069 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5071 if (isset($content['attribs']['']['samplingrate']))
5073 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5075 if (isset($content['attribs']['']['type']))
5077 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5079 if (isset($content['attribs']['']['width']))
5081 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5083 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5085 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5088 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5090 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5092 $caption_type = null;
5093 $caption_lang = null;
5094 $caption_startTime = null;
5095 $caption_endTime = null;
5096 $caption_text = null;
5097 if (isset($caption['attribs']['']['type']))
5099 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5101 if (isset($caption['attribs']['']['lang']))
5103 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5105 if (isset($caption['attribs']['']['start']))
5107 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5109 if (isset($caption['attribs']['']['end']))
5111 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5113 if (isset($caption['data']))
5115 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5117 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5119 if (is_array($captions))
5121 $captions = array_values(SimplePie_Misc::array_unique($captions));
5126 $captions = $captions_parent;
5130 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5132 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5137 if (isset($category['data']))
5139 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5141 if (isset($category['attribs']['']['scheme']))
5143 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5147 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5149 if (isset($category['attribs']['']['label']))
5151 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5153 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5156 if (is_array($categories) && is_array($categories_parent))
5158 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5160 elseif (is_array($categories))
5162 $categories = array_values(SimplePie_Misc::array_unique($categories));
5164 elseif (is_array($categories_parent))
5166 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5174 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5176 $copyright_url = null;
5177 $copyright_label = null;
5178 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5180 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5182 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5184 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5186 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5190 $copyrights = $copyrights_parent;
5194 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5196 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5198 $credit_role = null;
5199 $credit_scheme = null;
5200 $credit_name = null;
5201 if (isset($credit['attribs']['']['role']))
5203 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5205 if (isset($credit['attribs']['']['scheme']))
5207 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5211 $credit_scheme = 'urn:ebu';
5213 if (isset($credit['data']))
5215 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5217 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5219 if (is_array($credits))
5221 $credits = array_values(SimplePie_Misc::array_unique($credits));
5226 $credits = $credits_parent;
5230 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5232 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5236 $description = $description_parent;
5240 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5242 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5246 if (isset($hash['data']))
5248 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5250 if (isset($hash['attribs']['']['algo']))
5252 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5258 $hashes[] = $algo.':'.$value;
5260 if (is_array($hashes))
5262 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5267 $hashes = $hashes_parent;
5271 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5273 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5275 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5276 foreach ($temp as $word)
5278 $keywords[] = trim($word);
5282 if (is_array($keywords))
5284 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5289 $keywords = $keywords_parent;
5293 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5295 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5299 $player = $player_parent;
5303 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5305 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5307 $rating_scheme = null;
5308 $rating_value = null;
5309 if (isset($rating['attribs']['']['scheme']))
5311 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5315 $rating_scheme = 'urn:simple';
5317 if (isset($rating['data']))
5319 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5321 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5323 if (is_array($ratings))
5325 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5330 $ratings = $ratings_parent;
5334 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5336 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5338 $restriction_relationship = null;
5339 $restriction_type = null;
5340 $restriction_value = null;
5341 if (isset($restriction['attribs']['']['relationship']))
5343 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5345 if (isset($restriction['attribs']['']['type']))
5347 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5349 if (isset($restriction['data']))
5351 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5353 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5355 if (is_array($restrictions))
5357 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5362 $restrictions = $restrictions_parent;
5366 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5368 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5370 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5372 if (is_array($thumbnails))
5374 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5379 $thumbnails = $thumbnails_parent;
5383 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5385 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5389 $title = $title_parent;
5392 $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);
5397 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5399 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5412 $samplingrate = null;
5417 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5418 if (isset($link['attribs']['']['type']))
5420 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5422 if (isset($link['attribs']['']['length']))
5424 $length = ceil($link['attribs']['']['length']);
5427 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5428 $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);
5432 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5434 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5447 $samplingrate = null;
5452 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5453 if (isset($link['attribs']['']['type']))
5455 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5457 if (isset($link['attribs']['']['length']))
5459 $length = ceil($link['attribs']['']['length']);
5462 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5463 $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);
5467 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5469 if (isset($enclosure[0]['attribs']['']['url']))
5482 $samplingrate = null;
5487 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5488 if (isset($enclosure[0]['attribs']['']['type']))
5490 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5492 if (isset($enclosure[0]['attribs']['']['length']))
5494 $length = ceil($enclosure[0]['attribs']['']['length']);
5497 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5498 $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);
5502 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))
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);
5508 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5510 if (!empty($this->data['enclosures']))
5512 return $this->data['enclosures'];
5520 function get_latitude()
5522 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5524 return (float) $return[0]['data'];
5526 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5528 return (float) $match[1];
5536 function get_longitude()
5538 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5540 return (float) $return[0]['data'];
5542 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5544 return (float) $return[0]['data'];
5546 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5548 return (float) $match[2];
5556 function get_source()
5558 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5560 return new $this->feed->source_class($this, $return[0]);
5569 * Creates the add_to_* methods' return data
5572 * @param string $item_url String to prefix to the item permalink
5573 * @param string $title_url String to prefix to the item title
5574 * (and suffix to the item permalink)
5575 * @return mixed URL if feed exists, false otherwise
5577 function add_to_service($item_url, $title_url = null, $summary_url = null)
5579 if ($this->get_permalink() !== null)
5581 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5582 if ($title_url !== null && $this->get_title() !== null)
5584 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5586 if ($summary_url !== null && $this->get_description() !== null)
5588 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5598 function add_to_blinklist()
5600 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5603 function add_to_blogmarks()
5605 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5608 function add_to_delicious()
5610 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5613 function add_to_digg()
5615 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5618 function add_to_furl()
5620 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5623 function add_to_magnolia()
5625 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5628 function add_to_myweb20()
5630 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5633 function add_to_newsvine()
5635 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5638 function add_to_reddit()
5640 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5643 function add_to_segnalo()
5645 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5648 function add_to_simpy()
5650 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5653 function add_to_spurl()
5655 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5658 function add_to_wists()
5660 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5663 function search_technorati()
5665 return $this->add_to_service('http://www.technorati.com/search/');
5669 class SimplePie_Source
5672 var $data = array();
5674 function SimplePie_Source($item, $data)
5676 $this->item = $item;
5677 $this->data = $data;
5680 function __toString()
5682 return md5(serialize($this->data));
5686 * Remove items that link back to this before destroying this object
5688 function __destruct()
5693 function get_source_tags($namespace, $tag)
5695 if (isset($this->data['child'][$namespace][$tag]))
5697 return $this->data['child'][$namespace][$tag];
5705 function get_base($element = array())
5707 return $this->item->get_base($element);
5710 function sanitize($data, $type, $base = '')
5712 return $this->item->sanitize($data, $type, $base);
5720 function get_title()
5722 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5724 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5726 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5728 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5730 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5732 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5734 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5736 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5738 elseif ($return = $this->get_source_tags('', 'title'))
5740 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5742 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5744 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5746 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5748 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5756 function get_category($key = 0)
5758 $categories = $this->get_categories();
5759 if (isset($categories[$key]))
5761 return $categories[$key];
5769 function get_categories()
5771 $categories = array();
5773 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5778 if (isset($category['attribs']['']['term']))
5780 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5782 if (isset($category['attribs']['']['scheme']))
5784 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5786 if (isset($category['attribs']['']['label']))
5788 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5790 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5792 foreach ((array) $this->get_source_tags('', 'category') as $category)
5794 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5796 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5798 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5800 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5802 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5805 if (!empty($categories))
5807 return SimplePie_Misc::array_unique($categories);
5815 function get_author($key = 0)
5817 $authors = $this->get_authors();
5818 if (isset($authors[$key]))
5820 return $authors[$key];
5828 function get_authors()
5831 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5836 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5838 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5840 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5842 $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]));
5844 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5846 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5848 if ($name !== null || $email !== null || $uri !== null)
5850 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5853 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5858 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5860 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5862 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5864 $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]));
5866 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5868 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5870 if ($name !== null || $email !== null || $url !== null)
5872 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5875 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5877 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5879 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5881 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5883 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5885 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5888 if (!empty($authors))
5890 return SimplePie_Misc::array_unique($authors);
5898 function get_contributor($key = 0)
5900 $contributors = $this->get_contributors();
5901 if (isset($contributors[$key]))
5903 return $contributors[$key];
5911 function get_contributors()
5913 $contributors = array();
5914 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5919 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5921 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5923 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5925 $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]));
5927 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5929 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5931 if ($name !== null || $email !== null || $uri !== null)
5933 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5936 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5941 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5943 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5945 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5947 $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]));
5949 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5951 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5953 if ($name !== null || $email !== null || $url !== null)
5955 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5959 if (!empty($contributors))
5961 return SimplePie_Misc::array_unique($contributors);
5969 function get_link($key = 0, $rel = 'alternate')
5971 $links = $this->get_links($rel);
5972 if (isset($links[$key]))
5974 return $links[$key];
5983 * Added for parity between the parent-level and the item/entry-level.
5985 function get_permalink()
5987 return $this->get_link(0);
5990 function get_links($rel = 'alternate')
5992 if (!isset($this->data['links']))
5994 $this->data['links'] = array();
5995 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5997 foreach ($links as $link)
5999 if (isset($link['attribs']['']['href']))
6001 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6002 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6006 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6008 foreach ($links as $link)
6010 if (isset($link['attribs']['']['href']))
6012 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6013 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6018 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6020 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6022 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6024 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6026 if ($links = $this->get_source_tags('', 'link'))
6028 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6031 $keys = array_keys($this->data['links']);
6032 foreach ($keys as $key)
6034 if (SimplePie_Misc::is_isegment_nz_nc($key))
6036 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6038 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6039 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6043 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6046 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6048 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6050 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6054 if (isset($this->data['links'][$rel]))
6056 return $this->data['links'][$rel];
6064 function get_description()
6066 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6068 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6070 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6072 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6074 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6076 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6078 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6080 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6082 elseif ($return = $this->get_source_tags('', 'description'))
6084 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6086 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6088 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6090 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6092 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6094 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6096 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6098 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6100 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6108 function get_copyright()
6110 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6112 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6114 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6116 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6118 elseif ($return = $this->get_source_tags('', 'copyright'))
6120 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6122 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6124 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6126 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6128 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6136 function get_language()
6138 if ($return = $this->get_source_tags('', 'language'))
6140 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6142 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6144 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6146 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6148 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6150 elseif (isset($this->data['xml_lang']))
6152 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6160 function get_latitude()
6162 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6164 return (float) $return[0]['data'];
6166 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6168 return (float) $match[1];
6176 function get_longitude()
6178 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6180 return (float) $return[0]['data'];
6182 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6184 return (float) $return[0]['data'];
6186 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6188 return (float) $match[2];
6196 function get_image_url()
6198 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6200 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6202 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6204 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6206 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6208 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6217 class SimplePie_Author
6223 // Constructor, used to input the data
6224 function SimplePie_Author($name = null, $link = null, $email = null)
6226 $this->name = $name;
6227 $this->link = $link;
6228 $this->email = $email;
6231 function __toString()
6233 // There is no $this->data here
6234 return md5(serialize($this));
6239 if ($this->name !== null)
6251 if ($this->link !== null)
6261 function get_email()
6263 if ($this->email !== null)
6265 return $this->email;
6274 class SimplePie_Category
6280 // Constructor, used to input the data
6281 function SimplePie_Category($term = null, $scheme = null, $label = null)
6283 $this->term = $term;
6284 $this->scheme = $scheme;
6285 $this->label = $label;
6288 function __toString()
6290 // There is no $this->data here
6291 return md5(serialize($this));
6296 if ($this->term !== null)
6306 function get_scheme()
6308 if ($this->scheme !== null)
6310 return $this->scheme;
6318 function get_label()
6320 if ($this->label !== null)
6322 return $this->label;
6326 return $this->get_term();
6331 class SimplePie_Enclosure
6361 // Constructor, used to input the data
6362 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)
6364 $this->bitrate = $bitrate;
6365 $this->captions = $captions;
6366 $this->categories = $categories;
6367 $this->channels = $channels;
6368 $this->copyright = $copyright;
6369 $this->credits = $credits;
6370 $this->description = $description;
6371 $this->duration = $duration;
6372 $this->expression = $expression;
6373 $this->framerate = $framerate;
6374 $this->hashes = $hashes;
6375 $this->height = $height;
6376 $this->javascript = $javascript;
6377 $this->keywords = $keywords;
6378 $this->lang = $lang;
6379 $this->length = $length;
6380 $this->link = $link;
6381 $this->medium = $medium;
6382 $this->player = $player;
6383 $this->ratings = $ratings;
6384 $this->restrictions = $restrictions;
6385 $this->samplingrate = $samplingrate;
6386 $this->thumbnails = $thumbnails;
6387 $this->title = $title;
6388 $this->type = $type;
6389 $this->width = $width;
6390 if (class_exists('idna_convert'))
6392 $idn =& new idna_convert;
6393 $parsed = SimplePie_Misc::parse_url($link);
6394 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6396 $this->handler = $this->get_handler(); // Needs to load last
6399 function __toString()
6401 // There is no $this->data here
6402 return md5(serialize($this));
6405 function get_bitrate()
6407 if ($this->bitrate !== null)
6409 return $this->bitrate;
6417 function get_caption($key = 0)
6419 $captions = $this->get_captions();
6420 if (isset($captions[$key]))
6422 return $captions[$key];
6430 function get_captions()
6432 if ($this->captions !== null)
6434 return $this->captions;
6442 function get_category($key = 0)
6444 $categories = $this->get_categories();
6445 if (isset($categories[$key]))
6447 return $categories[$key];
6455 function get_categories()
6457 if ($this->categories !== null)
6459 return $this->categories;
6467 function get_channels()
6469 if ($this->channels !== null)
6471 return $this->channels;
6479 function get_copyright()
6481 if ($this->copyright !== null)
6483 return $this->copyright;
6491 function get_credit($key = 0)
6493 $credits = $this->get_credits();
6494 if (isset($credits[$key]))
6496 return $credits[$key];
6504 function get_credits()
6506 if ($this->credits !== null)
6508 return $this->credits;
6516 function get_description()
6518 if ($this->description !== null)
6520 return $this->description;
6528 function get_duration($convert = false)
6530 if ($this->duration !== null)
6534 $time = SimplePie_Misc::time_hms($this->duration);
6539 return $this->duration;
6548 function get_expression()
6550 if ($this->expression !== null)
6552 return $this->expression;
6560 function get_extension()
6562 if ($this->link !== null)
6564 $url = SimplePie_Misc::parse_url($this->link);
6565 if ($url['path'] !== '')
6567 return pathinfo($url['path'], PATHINFO_EXTENSION);
6573 function get_framerate()
6575 if ($this->framerate !== null)
6577 return $this->framerate;
6585 function get_handler()
6587 return $this->get_real_type(true);
6590 function get_hash($key = 0)
6592 $hashes = $this->get_hashes();
6593 if (isset($hashes[$key]))
6595 return $hashes[$key];
6603 function get_hashes()
6605 if ($this->hashes !== null)
6607 return $this->hashes;
6615 function get_height()
6617 if ($this->height !== null)
6619 return $this->height;
6627 function get_language()
6629 if ($this->lang !== null)
6639 function get_keyword($key = 0)
6641 $keywords = $this->get_keywords();
6642 if (isset($keywords[$key]))
6644 return $keywords[$key];
6652 function get_keywords()
6654 if ($this->keywords !== null)
6656 return $this->keywords;
6664 function get_length()
6666 if ($this->length !== null)
6668 return $this->length;
6678 if ($this->link !== null)
6680 return urldecode($this->link);
6688 function get_medium()
6690 if ($this->medium !== null)
6692 return $this->medium;
6700 function get_player()
6702 if ($this->player !== null)
6704 return $this->player;
6712 function get_rating($key = 0)
6714 $ratings = $this->get_ratings();
6715 if (isset($ratings[$key]))
6717 return $ratings[$key];
6725 function get_ratings()
6727 if ($this->ratings !== null)
6729 return $this->ratings;
6737 function get_restriction($key = 0)
6739 $restrictions = $this->get_restrictions();
6740 if (isset($restrictions[$key]))
6742 return $restrictions[$key];
6750 function get_restrictions()
6752 if ($this->restrictions !== null)
6754 return $this->restrictions;
6762 function get_sampling_rate()
6764 if ($this->samplingrate !== null)
6766 return $this->samplingrate;
6776 $length = $this->get_length();
6777 if ($length !== null)
6779 return round($length/1048576, 2);
6787 function get_thumbnail($key = 0)
6789 $thumbnails = $this->get_thumbnails();
6790 if (isset($thumbnails[$key]))
6792 return $thumbnails[$key];
6800 function get_thumbnails()
6802 if ($this->thumbnails !== null)
6804 return $this->thumbnails;
6812 function get_title()
6814 if ($this->title !== null)
6816 return $this->title;
6826 if ($this->type !== null)
6836 function get_width()
6838 if ($this->width !== null)
6840 return $this->width;
6848 function native_embed($options='')
6850 return $this->embed($options, true);
6854 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6856 function embed($options = '', $native = false)
6866 $bgcolor = '#ffffff';
6868 $widescreen = false;
6869 $handler = $this->get_handler();
6870 $type = $this->get_real_type();
6872 // Process options and reassign values as necessary
6873 if (is_array($options))
6879 $options = explode(',', $options);
6880 foreach($options as $option)
6882 $opt = explode(':', $option, 2);
6883 if (isset($opt[0], $opt[1]))
6885 $opt[0] = trim($opt[0]);
6886 $opt[1] = trim($opt[1]);
6902 $altclass = $opt[1];
6922 $mediaplayer = $opt[1];
6926 $widescreen = $opt[1];
6933 $mime = explode('/', $type, 2);
6936 // Process values for 'auto'
6937 if ($width == 'auto')
6939 if ($mime == 'video')
6941 if ($height == 'auto')
6945 elseif ($widescreen)
6947 $width = round((intval($height)/9)*16);
6951 $width = round((intval($height)/3)*4);
6960 if ($height == 'auto')
6962 if ($mime == 'audio')
6966 elseif ($mime == 'video')
6968 if ($width == 'auto')
6979 elseif ($widescreen)
6981 $height = round((intval($width)/16)*9);
6985 $height = round((intval($width)/4)*3);
6993 elseif ($mime == 'audio')
6998 // Set proper placeholder value
6999 if ($mime == 'audio')
7001 $placeholder = $audio;
7003 elseif ($mime == 'video')
7005 $placeholder = $video;
7010 // Make sure the JS library is included
7013 static $javascript_outputted = null;
7014 if (!$javascript_outputted && $this->javascript)
7016 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7017 $javascript_outputted = true;
7022 if ($handler == 'odeo')
7026 $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>';
7030 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7035 elseif ($handler == 'flash')
7039 $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>";
7043 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7047 // Flash Media Player file types.
7048 // Preferred handler for MP3 file types.
7049 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7054 $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>";
7058 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7062 // QuickTime 7 file types. Need to test with QuickTime 6.
7063 // Only handle MP3's if the Flash Media Player is not present.
7064 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7069 if ($placeholder != ""){
7070 $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>";
7073 $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>";
7078 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7083 elseif ($handler == 'wmedia')
7088 $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>";
7092 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7097 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7102 function get_real_type($find_handler = false)
7104 // If it's Odeo, let's get it out of the way.
7105 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7110 // Mime-types by handler.
7111 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7112 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7113 $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
7114 $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
7115 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7117 if ($this->get_type() !== null)
7119 $type = strtolower($this->type);
7126 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7127 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7129 switch (strtolower($this->get_extension()))
7134 $type = 'audio/acc';
7141 $type = 'audio/aiff';
7145 $type = 'audio/wav';
7152 $type = 'audio/midi';
7156 $type = 'audio/x-m4a';
7161 $type = 'audio/mp3';
7165 $type = 'audio/wav';
7169 $type = 'audio/x-ms-wax';
7173 $type = 'audio/x-ms-wma';
7179 $type = 'video/3gpp';
7184 $type = 'video/3gpp2';
7188 $type = 'video/x-ms-asf';
7192 $type = 'video/x-flv';
7206 $type = 'video/mpeg';
7210 $type = 'video/x-m4v';
7215 $type = 'video/quicktime';
7220 $type = 'video/mp4';
7224 $type = 'video/sd-video';
7228 $type = 'video/x-ms-wm';
7232 $type = 'video/x-ms-wmv';
7236 $type = 'video/x-ms-wvx';
7241 $type = 'application/futuresplash';
7245 $type = 'application/x-shockwave-flash';
7252 if (in_array($type, $types_flash))
7256 elseif (in_array($type, $types_fmedia))
7260 elseif (in_array($type, $types_quicktime))
7264 elseif (in_array($type, $types_wmedia))
7268 elseif (in_array($type, $types_mp3))
7284 class SimplePie_Caption
7292 // Constructor, used to input the data
7293 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7295 $this->type = $type;
7296 $this->lang = $lang;
7297 $this->startTime = $startTime;
7298 $this->endTime = $endTime;
7299 $this->text = $text;
7302 function __toString()
7304 // There is no $this->data here
7305 return md5(serialize($this));
7308 function get_endtime()
7310 if ($this->endTime !== null)
7312 return $this->endTime;
7320 function get_language()
7322 if ($this->lang !== null)
7332 function get_starttime()
7334 if ($this->startTime !== null)
7336 return $this->startTime;
7346 if ($this->text !== null)
7358 if ($this->type !== null)
7369 class SimplePie_Credit
7375 // Constructor, used to input the data
7376 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7378 $this->role = $role;
7379 $this->scheme = $scheme;
7380 $this->name = $name;
7383 function __toString()
7385 // There is no $this->data here
7386 return md5(serialize($this));
7391 if ($this->role !== null)
7401 function get_scheme()
7403 if ($this->scheme !== null)
7405 return $this->scheme;
7415 if ($this->name !== null)
7426 class SimplePie_Copyright
7431 // Constructor, used to input the data
7432 function SimplePie_Copyright($url = null, $label = null)
7435 $this->label = $label;
7438 function __toString()
7440 // There is no $this->data here
7441 return md5(serialize($this));
7446 if ($this->url !== null)
7456 function get_attribution()
7458 if ($this->label !== null)
7460 return $this->label;
7469 class SimplePie_Rating
7474 // Constructor, used to input the data
7475 function SimplePie_Rating($scheme = null, $value = null)
7477 $this->scheme = $scheme;
7478 $this->value = $value;
7481 function __toString()
7483 // There is no $this->data here
7484 return md5(serialize($this));
7487 function get_scheme()
7489 if ($this->scheme !== null)
7491 return $this->scheme;
7499 function get_value()
7501 if ($this->value !== null)
7503 return $this->value;
7512 class SimplePie_Restriction
7518 // Constructor, used to input the data
7519 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7521 $this->relationship = $relationship;
7522 $this->type = $type;
7523 $this->value = $value;
7526 function __toString()
7528 // There is no $this->data here
7529 return md5(serialize($this));
7532 function get_relationship()
7534 if ($this->relationship !== null)
7536 return $this->relationship;
7546 if ($this->type !== null)
7556 function get_value()
7558 if ($this->value !== null)
7560 return $this->value;
7570 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7572 class SimplePie_File
7576 var $success = true;
7577 var $headers = array();
7582 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7584 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7586 if (class_exists('idna_convert'))
7588 $idn =& new idna_convert;
7589 $parsed = SimplePie_Misc::parse_url($url);
7590 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7593 $this->useragent = $useragent;
7594 if (preg_match('/^http(s)?:\/\//i', $url))
7596 if ($useragent === null)
7598 $useragent = ini_get('user_agent');
7599 $this->useragent = $useragent;
7601 if (!is_array($headers))
7605 if (!$force_fsockopen && function_exists('curl_exec'))
7607 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7609 $headers2 = array();
7610 foreach ($headers as $key => $value)
7612 $headers2[] = "$key: $value";
7614 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7616 curl_setopt($fp, CURLOPT_ENCODING, '');
7618 curl_setopt($fp, CURLOPT_URL, $url);
7619 curl_setopt($fp, CURLOPT_HEADER, 1);
7620 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7621 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7622 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7623 curl_setopt($fp, CURLOPT_REFERER, $url);
7624 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7625 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7626 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7628 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7629 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7632 $this->headers = curl_exec($fp);
7633 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7635 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7636 $this->headers = curl_exec($fp);
7638 if (curl_errno($fp))
7640 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7641 $this->success = false;
7645 $info = curl_getinfo($fp);
7647 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7648 $this->headers = array_pop($this->headers);
7649 $parser =& new SimplePie_HTTP_Parser($this->headers);
7650 if ($parser->parse())
7652 $this->headers = $parser->headers;
7653 $this->body = $parser->body;
7654 $this->status_code = $parser->status_code;
7655 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)
7658 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7659 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7666 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7667 $url_parts = parse_url($url);
7668 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7670 $url_parts['host'] = "ssl://$url_parts[host]";
7671 $url_parts['port'] = 443;
7673 if (!isset($url_parts['port']))
7675 $url_parts['port'] = 80;
7677 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7680 $this->error = 'fsockopen error: ' . $errstr;
7681 $this->success = false;
7685 stream_set_timeout($fp, $timeout);
7686 if (isset($url_parts['path']))
7688 if (isset($url_parts['query']))
7690 $get = "$url_parts[path]?$url_parts[query]";
7694 $get = $url_parts['path'];
7701 $out = "GET $get HTTP/1.0\r\n";
7702 $out .= "Host: $url_parts[host]\r\n";
7703 $out .= "User-Agent: $useragent\r\n";
7704 if (extension_loaded('zlib'))
7706 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7709 if (isset($url_parts['user']) && isset($url_parts['pass']))
7711 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7713 foreach ($headers as $key => $value)
7715 $out .= "$key: $value\r\n";
7717 $out .= "Connection: Close\r\n\r\n";
7720 $info = stream_get_meta_data($fp);
7722 $this->headers = '';
7723 while (!$info['eof'] && !$info['timed_out'])
7725 $this->headers .= fread($fp, 1160);
7726 $info = stream_get_meta_data($fp);
7728 if (!$info['timed_out'])
7730 $parser =& new SimplePie_HTTP_Parser($this->headers);
7731 if ($parser->parse())
7733 $this->headers = $parser->headers;
7734 $this->body = $parser->body;
7735 $this->status_code = $parser->status_code;
7736 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)
7739 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7740 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7742 if (isset($this->headers['content-encoding']))
7744 // Hey, we act dumb elsewhere, so let's do that here too
7745 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7749 $decoder = new SimplePie_gzdecode($this->body);
7750 if (!$decoder->parse())
7752 $this->error = 'Unable to decode HTTP "gzip" stream';
7753 $this->success = false;
7757 $this->body = $decoder->data;
7762 if (($body = gzuncompress($this->body)) === false)
7764 if (($body = gzinflate($this->body)) === false)
7766 $this->error = 'Unable to decode HTTP "deflate" stream';
7767 $this->success = false;
7770 $this->body = $body;
7774 $this->error = 'Unknown content coding';
7775 $this->success = false;
7782 $this->error = 'fsocket timed out';
7783 $this->success = false;
7791 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7792 if (!$this->body = file_get_contents($url))
7794 $this->error = 'file_get_contents could not read the file';
7795 $this->success = false;
7802 * HTTP Response Parser
7804 * @package SimplePie
7806 class SimplePie_HTTP_Parser
7814 var $http_version = 0.0;
7822 var $status_code = 0;
7833 * Key/value pairs of the headers
7838 var $headers = array();
7841 * Body of the response
7849 * Current state of the state machine
7854 var $state = 'http_version';
7865 * Input data length (to avoid calling strlen() everytime this is needed)
7870 var $data_length = 0;
7873 * Current position of the pointer
7881 * Name of the hedaer currently being parsed
7889 * Value of the hedaer currently being parsed
7897 * Create an instance of the class with the input data
7900 * @param string $data Input data
7902 function SimplePie_HTTP_Parser($data)
7904 $this->data = $data;
7905 $this->data_length = strlen($this->data);
7909 * Parse the input data
7912 * @return bool true on success, false on failure
7916 while ($this->state && $this->state !== 'emit' && $this->has_data())
7918 $state = $this->state;
7922 if ($this->state === 'emit' || $this->state === 'body')
7928 $this->http_version = '';
7929 $this->status_code = '';
7931 $this->headers = array();
7938 * Check whether there is data beyond the pointer
7941 * @return bool true if there is further data, false if not
7945 return (bool) ($this->position < $this->data_length);
7949 * See if the next character is LWS
7952 * @return bool true if the next character is LWS, false if not
7954 function is_linear_whitespace()
7956 return (bool) ($this->data[$this->position] === "\x09"
7957 || $this->data[$this->position] === "\x20"
7958 || ($this->data[$this->position] === "\x0A"
7959 && isset($this->data[$this->position + 1])
7960 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7964 * Parse the HTTP version
7968 function http_version()
7970 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7972 $len = strspn($this->data, '0123456789.', 5);
7973 $this->http_version = substr($this->data, 5, $len);
7974 $this->position += 5 + $len;
7975 if (substr_count($this->http_version, '.') <= 1)
7977 $this->http_version = (float) $this->http_version;
7978 $this->position += strspn($this->data, "\x09\x20", $this->position);
7979 $this->state = 'status';
7983 $this->state = false;
7988 $this->state = false;
7993 * Parse the status code
7999 if ($len = strspn($this->data, '0123456789', $this->position))
8001 $this->status_code = (int) substr($this->data, $this->position, $len);
8002 $this->position += $len;
8003 $this->state = 'reason';
8007 $this->state = false;
8012 * Parse the reason phrase
8018 $len = strcspn($this->data, "\x0A", $this->position);
8019 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8020 $this->position += $len + 1;
8021 $this->state = 'new_line';
8025 * Deal with a new line, shifting data around as needed
8031 $this->value = trim($this->value, "\x0D\x20");
8032 if ($this->name !== '' && $this->value !== '')
8034 $this->name = strtolower($this->name);
8035 if (isset($this->headers[$this->name]))
8037 $this->headers[$this->name] .= ', ' . $this->value;
8041 $this->headers[$this->name] = $this->value;
8046 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8048 $this->position += 2;
8049 $this->state = 'body';
8051 elseif ($this->data[$this->position] === "\x0A")
8054 $this->state = 'body';
8058 $this->state = 'name';
8063 * Parse a header name
8069 $len = strcspn($this->data, "\x0A:", $this->position);
8070 if (isset($this->data[$this->position + $len]))
8072 if ($this->data[$this->position + $len] === "\x0A")
8074 $this->position += $len;
8075 $this->state = 'new_line';
8079 $this->name = substr($this->data, $this->position, $len);
8080 $this->position += $len + 1;
8081 $this->state = 'value';
8086 $this->state = false;
8091 * Parse LWS, replacing consecutive LWS characters with a single space
8095 function linear_whitespace()
8099 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8101 $this->position += 2;
8103 elseif ($this->data[$this->position] === "\x0A")
8107 $this->position += strspn($this->data, "\x09\x20", $this->position);
8108 } while ($this->has_data() && $this->is_linear_whitespace());
8109 $this->value .= "\x20";
8113 * See what state to move to while within non-quoted header values
8119 if ($this->is_linear_whitespace())
8121 $this->linear_whitespace();
8125 switch ($this->data[$this->position])
8129 $this->state = 'quote';
8134 $this->state = 'new_line';
8138 $this->state = 'value_char';
8145 * Parse a header value while outside quotes
8149 function value_char()
8151 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8152 $this->value .= substr($this->data, $this->position, $len);
8153 $this->position += $len;
8154 $this->state = 'value';
8158 * See what state to move to while within quoted header values
8164 if ($this->is_linear_whitespace())
8166 $this->linear_whitespace();
8170 switch ($this->data[$this->position])
8174 $this->state = 'value';
8179 $this->state = 'new_line';
8184 $this->state = 'quote_escaped';
8188 $this->state = 'quote_char';
8195 * Parse a header value while within quotes
8199 function quote_char()
8201 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8202 $this->value .= substr($this->data, $this->position, $len);
8203 $this->position += $len;
8204 $this->state = 'value';
8208 * Parse an escaped character within quotes
8212 function quote_escaped()
8214 $this->value .= $this->data[$this->position];
8216 $this->state = 'quote';
8226 $this->body = substr($this->data, $this->position);
8227 $this->state = 'emit';
8234 * @package SimplePie
8236 class SimplePie_gzdecode
8242 * @see gzdecode::$data
8244 var $compressed_data;
8247 * Size of compressed data
8251 var $compressed_size;
8254 * Minimum size of a valid gzip string
8258 var $min_compressed_size = 18;
8261 * Current position of pointer
8278 * @see gzdecode::$compressed_data
8307 * @see gzdecode::$extra_field
8308 * @see gzdecode::$SI2
8316 * @see gzdecode::$extra_field
8317 * @see gzdecode::$SI1
8322 * Extra field content
8325 * @see gzdecode::$SI1
8326 * @see gzdecode::$SI2
8338 * Human readable comment
8345 * Don't allow anything to be set
8349 function __set($name, $value)
8351 trigger_error("Cannot write property $name", E_USER_ERROR);
8355 * Set the compressed string and related properties
8359 function SimplePie_gzdecode($data)
8361 $this->compressed_data = $data;
8362 $this->compressed_size = strlen($data);
8366 * Decode the GZIP stream
8372 if ($this->compressed_size >= $this->min_compressed_size)
8374 // Check ID1, ID2, and CM
8375 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8380 // Get the FLG (FLaGs)
8381 $this->flags = ord($this->compressed_data[3]);
8383 // FLG bits above (1 << 4) are reserved
8384 if ($this->flags > 0x1F)
8389 // Advance the pointer after the above
8390 $this->position += 4;
8393 $mtime = substr($this->compressed_data, $this->position, 4);
8394 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8395 if (current(unpack('S', "\x00\x01")) === 1)
8397 $mtime = strrev($mtime);
8399 $this->MTIME = current(unpack('l', $mtime));
8400 $this->position += 4;
8402 // Get the XFL (eXtra FLags)
8403 $this->XFL = ord($this->compressed_data[$this->position++]);
8405 // Get the OS (Operating System)
8406 $this->OS = ord($this->compressed_data[$this->position++]);
8409 if ($this->flags & 4)
8411 // Read subfield IDs
8412 $this->SI1 = $this->compressed_data[$this->position++];
8413 $this->SI2 = $this->compressed_data[$this->position++];
8415 // SI2 set to zero is reserved for future use
8416 if ($this->SI2 === "\x00")
8421 // Get the length of the extra field
8422 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8425 // Check the length of the string is still valid
8426 $this->min_compressed_size += $len + 4;
8427 if ($this->compressed_size >= $this->min_compressed_size)
8429 // Set the extra field to the given data
8430 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8431 $this->position += $len;
8440 if ($this->flags & 8)
8442 // Get the length of the filename
8443 $len = strspn($this->compressed_data, "\x00", $this->position);
8445 // Check the length of the string is still valid
8446 $this->min_compressed_size += $len + 1;
8447 if ($this->compressed_size >= $this->min_compressed_size)
8449 // Set the original filename to the given string
8450 $this->filename = substr($this->compressed_data, $this->position, $len);
8451 $this->position += $len + 1;
8459 // Parse the FCOMMENT
8460 if ($this->flags & 16)
8462 // Get the length of the comment
8463 $len = strspn($this->compressed_data, "\x00", $this->position);
8465 // Check the length of the string is still valid
8466 $this->min_compressed_size += $len + 1;
8467 if ($this->compressed_size >= $this->min_compressed_size)
8469 // Set the original comment to the given string
8470 $this->comment = substr($this->compressed_data, $this->position, $len);
8471 $this->position += $len + 1;
8480 if ($this->flags & 2)
8482 // Check the length of the string is still valid
8483 $this->min_compressed_size += $len + 2;
8484 if ($this->compressed_size >= $this->min_compressed_size)
8487 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8489 // Check the CRC matches
8490 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8492 $this->position += 2;
8505 // Decompress the actual data
8506 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8512 $this->position = $this->compressed_size - 8;
8515 // Check CRC of data
8516 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8517 $this->position += 4;
8518 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8523 // Check ISIZE of data
8524 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8525 $this->position += 4;
8526 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8531 // Wow, against all odds, we've actually got a valid gzip string
8541 class SimplePie_Cache
8544 * Don't call the constructor. Please.
8548 function SimplePie_Cache()
8550 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8554 * Create a new SimplePie_Cache object
8559 function create($location, $filename, $extension)
8561 return new SimplePie_Cache_File($location, $filename, $extension);
8565 class SimplePie_Cache_File
8572 function SimplePie_Cache_File($location, $filename, $extension)
8574 $this->location = $location;
8575 $this->filename = rawurlencode($filename);
8576 $this->extension = rawurlencode($extension);
8577 $this->name = "$location/$this->filename.$this->extension";
8580 function save($data)
8582 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8584 if (is_a($data, 'SimplePie'))
8586 $data = $data->data;
8589 $data = serialize($data);
8591 if (function_exists('file_put_contents'))
8593 return (bool) file_put_contents($this->name, $data);
8597 $fp = fopen($this->name, 'wb');
8611 if (file_exists($this->name) && is_readable($this->name))
8613 return unserialize(file_get_contents($this->name));
8620 if (file_exists($this->name))
8622 return filemtime($this->name);
8629 if (file_exists($this->name))
8631 return touch($this->name);
8638 if (file_exists($this->name))
8640 return unlink($this->name);
8646 class SimplePie_Misc
8648 function time_hms($seconds)
8652 $hours = floor($seconds / 3600);
8653 $remainder = $seconds % 3600;
8656 $time .= $hours.':';
8659 $minutes = floor($remainder / 60);
8660 $seconds = $remainder % 60;
8661 if ($minutes < 10 && $hours > 0)
8663 $minutes = '0' . $minutes;
8667 $seconds = '0' . $seconds;
8670 $time .= $minutes.':';
8676 function absolutize_url($relative, $base)
8678 if ($relative !== '')
8680 $relative = SimplePie_Misc::parse_url($relative);
8681 if ($relative['scheme'] !== '')
8683 $target = $relative;
8685 elseif ($base !== '')
8687 $base = SimplePie_Misc::parse_url($base);
8688 $target = SimplePie_Misc::parse_url('');
8689 if ($relative['authority'] !== '')
8691 $target = $relative;
8692 $target['scheme'] = $base['scheme'];
8696 $target['scheme'] = $base['scheme'];
8697 $target['authority'] = $base['authority'];
8698 if ($relative['path'] !== '')
8700 if (strpos($relative['path'], '/') === 0)
8702 $target['path'] = $relative['path'];
8704 elseif ($base['authority'] !== '' && $base['path'] === '')
8706 $target['path'] = '/' . $relative['path'];
8708 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8710 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8714 $target['path'] = $relative['path'];
8716 $target['query'] = $relative['query'];
8720 $target['path'] = $base['path'];
8721 if ($relative['query'] !== '')
8723 $target['query'] = $relative['query'];
8725 elseif ($base['query'] !== '')
8727 $target['query'] = $base['query'];
8731 $target['fragment'] = $relative['fragment'];
8735 // No base URL, just return the relative URL
8736 $target = $relative;
8738 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8744 $return = SimplePie_Misc::normalize_url($return);
8748 function remove_dot_segments($input)
8751 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8753 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8754 if (strpos($input, '../') === 0)
8756 $input = substr($input, 3);
8758 elseif (strpos($input, './') === 0)
8760 $input = substr($input, 2);
8762 // 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,
8763 elseif (strpos($input, '/./') === 0)
8765 $input = substr_replace($input, '/', 0, 3);
8767 elseif ($input == '/.')
8771 // 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,
8772 elseif (strpos($input, '/../') === 0)
8774 $input = substr_replace($input, '/', 0, 4);
8775 $output = substr_replace($output, '', strrpos($output, '/'));
8777 elseif ($input == '/..')
8780 $output = substr_replace($output, '', strrpos($output, '/'));
8782 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8783 elseif ($input == '.' || $input == '..')
8787 // 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
8788 elseif (($pos = strpos($input, '/', 1)) !== false)
8790 $output .= substr($input, 0, $pos);
8791 $input = substr_replace($input, '', 0, $pos);
8799 return $output . $input;
8802 function get_element($realname, $string)
8805 $name = preg_quote($realname, '/');
8806 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8808 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8810 $return[$i]['tag'] = $realname;
8811 $return[$i]['full'] = $matches[$i][0][0];
8812 $return[$i]['offset'] = $matches[$i][0][1];
8813 if (strlen($matches[$i][3][0]) <= 2)
8815 $return[$i]['self_closing'] = true;
8819 $return[$i]['self_closing'] = false;
8820 $return[$i]['content'] = $matches[$i][4][0];
8822 $return[$i]['attribs'] = array();
8823 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))
8825 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8827 if (count($attribs[$j]) == 2)
8829 $attribs[$j][2] = $attribs[$j][1];
8831 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8839 function element_implode($element)
8841 $full = "<$element[tag]";
8842 foreach ($element['attribs'] as $key => $value)
8844 $key = strtolower($key);
8845 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8847 if ($element['self_closing'])
8853 $full .= ">$element[content]</$element[tag]>";
8858 function error($message, $level, $file, $line)
8863 $note = 'PHP Error';
8865 case E_USER_WARNING:
8866 $note = 'PHP Warning';
8869 $note = 'PHP Notice';
8872 $note = 'Unknown Error';
8875 error_log("$note: $message in $file on line $line", 0);
8880 * If a file has been cached, retrieve and display it.
8882 * This is most useful for caching images (get_favicon(), etc.),
8883 * however it works for all cached files. This WILL NOT display ANY
8884 * file/image/page/whatever, but rather only display what has already
8885 * been cached by SimplePie.
8888 * @see SimplePie::get_favicon()
8889 * @param str $identifier_url URL that is used to identify the content.
8890 * This may or may not be the actual URL of the live content.
8891 * @param str $cache_location Location of SimplePie's cache. Defaults
8893 * @param str $cache_extension The file extension that the file was
8894 * cached with. Defaults to 'spc'.
8895 * @param str $cache_class Name of the cache-handling class being used
8896 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8897 * as-is unless you've overloaded the class.
8898 * @param str $cache_name_function Obsolete. Exists for backwards
8899 * compatibility reasons only.
8901 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8903 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8905 if ($file = $cache->load())
8907 if (isset($file['headers']['content-type']))
8909 header('Content-type:' . $file['headers']['content-type']);
8913 header('Content-type: application/octet-stream');
8915 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8920 die('Cached file for ' . $identifier_url . ' cannot be found.');
8923 function fix_protocol($url, $http = 1)
8925 $url = SimplePie_Misc::normalize_url($url);
8926 $parsed = SimplePie_Misc::parse_url($url);
8927 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8929 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8932 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8934 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8937 if ($http == 2 && $parsed['scheme'] !== '')
8941 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8943 return substr_replace($url, 'podcast', 0, 4);
8945 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8947 return substr_replace($url, 'itpc', 0, 4);
8955 function parse_url($url)
8957 static $cache = array();
8958 if (isset($cache[$url]))
8960 return $cache[$url];
8962 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8964 for ($i = count($match); $i <= 9; $i++)
8968 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8972 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8976 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8981 $return .= "$scheme:";
8983 if ($authority !== '')
8985 $return .= "//$authority";
8993 $return .= "?$query";
8995 if ($fragment !== '')
8997 $return .= "#$fragment";
9002 function normalize_url($url)
9004 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
9005 $url = SimplePie_Misc::parse_url($url);
9006 $url['scheme'] = strtolower($url['scheme']);
9007 if ($url['authority'] !== '')
9009 $url['authority'] = strtolower($url['authority']);
9010 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
9012 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9015 function percent_encoding_normalization($match)
9017 $integer = hexdec($match[1]);
9018 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9020 return chr($integer);
9024 return strtoupper($match[0]);
9029 * Remove bad UTF-8 bytes
9031 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9032 * FAQ: Multilingual Forms (modified to include full ASCII range)
9034 * @author Geoffrey Sneddon
9035 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9036 * @param string $str String to remove bad UTF-8 bytes from
9037 * @return string UTF-8 string
9039 function utf8_bad_replace($str)
9041 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9045 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9049 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))
9051 return implode("\xEF\xBF\xBD", $matches[0]);
9053 elseif ($str !== '')
9055 return "\xEF\xBF\xBD";
9064 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9068 * @param string $string Windows-1252 encoded string
9069 * @return string UTF-8 encoded string
9071 function windows_1252_to_utf8($string)
9073 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");
9075 return strtr($string, $convert_table);
9078 function change_encoding($data, $input, $output)
9080 $input = SimplePie_Misc::encoding($input);
9081 $output = SimplePie_Misc::encoding($output);
9083 // We fail to fail on non US-ASCII bytes
9084 if ($input === 'US-ASCII')
9086 static $non_ascii_octects = '';
9087 if (!$non_ascii_octects)
9089 for ($i = 0x80; $i <= 0xFF; $i++)
9091 $non_ascii_octects .= chr($i);
9094 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9097 // This is first, as behaviour of this is completely predictable
9098 if ($input === 'Windows-1252' && $output === 'UTF-8')
9100 return SimplePie_Misc::windows_1252_to_utf8($data);
9102 // This is second, as behaviour of this varies only with PHP version
9103 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9107 // This is last, as behaviour of this varies with OS userland and PHP version
9108 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9112 // If we can't do anything, just fail
9119 function encoding($charset)
9121 /* Character sets are case-insensitive, and also need some further
9122 normalization in the real world (though we'll return them in the form given
9123 in their registration). */
9124 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9126 case 'adobestandardencoding':
9127 case 'csadobestandardencoding':
9128 return 'Adobe-Standard-Encoding';
9130 case 'adobesymbolencoding':
9132 return 'Adobe-Symbol-Encoding';
9138 return 'Amiga-1251';
9140 case 'ansix31101983':
9142 case 'csiso99naplps':
9145 return 'ANSI_X3.110-1983';
9149 case 'csiso89asmo449':
9160 return 'Big5-HKSCS';
9171 case 'csiso4unitedkingdom':
9179 case 'csiso47bsviewdata':
9181 return 'BS_viewdata';
9189 case 'csaz243419851':
9190 case 'csiso121canadian1':
9193 return 'CSA_Z243.4-1985-1';
9196 case 'csaz243419852':
9197 case 'csiso122canadian2':
9200 return 'CSA_Z243.4-1985-2';
9202 case 'csaz24341985gr':
9203 case 'csiso123csaz24341985gr':
9205 return 'CSA_Z243.4-1985-gr';
9207 case 'csiso139csn369103':
9210 return 'CSN_369103';
9217 case 'csiso21german':
9228 case 'csiso646danish':
9235 case 'csibmebcdicatde':
9237 return 'EBCDIC-AT-DE';
9239 case 'csebcdicatdea':
9241 return 'EBCDIC-AT-DE-A';
9243 case 'csebcdiccafr':
9245 return 'EBCDIC-CA-FR';
9247 case 'csebcdicdkno':
9249 return 'EBCDIC-DK-NO';
9251 case 'csebcdicdknoa':
9253 return 'EBCDIC-DK-NO-A';
9261 return 'EBCDIC-ES-A';
9265 return 'EBCDIC-ES-S';
9267 case 'csebcdicfise':
9269 return 'EBCDIC-FI-SE';
9271 case 'csebcdicfisea':
9273 return 'EBCDIC-FI-SE-A';
9295 case 'csiso111ecmacyrillic':
9296 case 'ecmacyrillic':
9299 return 'ECMA-cyrillic';
9301 case 'csiso17spanish':
9307 case 'csiso85spanish2':
9313 case 'cseucfixwidjapanese':
9314 case 'extendedunixcodefixedwidthforjapanese':
9315 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9317 case 'cseucpkdfmtjapanese':
9319 case 'extendedunixcodepackedformatforjapanese':
9320 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9332 case 'csiso58gb231280':
9338 case 'csiso57gb1988':
9342 return 'GB_1988-80';
9344 case 'csiso153gost1976874':
9348 return 'GOST_19768-74';
9351 case 'csiso150greekccitt':
9354 return 'greek-ccitt';
9356 case 'csiso88greek7':
9361 case 'csiso18greek7old':
9364 return 'greek7-old';
9368 return 'HP-DeskTop';
9380 return 'HP-Pi-font';
9389 return 'HZ-GB-2312';
9391 case 'csibmsymbols':
9393 return 'IBM-Symbols';
9402 case 'pcmultilingual850euro':
9407 case 'ebcdiclatin9euro':
9413 case 'ebcdicus37euro':
9419 case 'ebcdicde273euro':
9425 case 'ebcdicdk277euro':
9426 case 'ebcdicno277euro':
9432 case 'ebcdicfi278euro':
9433 case 'ebcdicse278euro':
9439 case 'ebcdicit280euro':
9445 case 'ebcdices284euro':
9451 case 'ebcdicgb285euro':
9457 case 'ebcdicfr297euro':
9463 case 'ebcdicinternational500euro':
9469 case 'ebcdicis871euro':
9544 case 'ebcdicjpkana':
9574 case 'cspc8codepage437':
9586 case 'cspc775baltic':
9592 case 'cspc850multilingual':
9635 case 'cspc862latinhebrew':
9677 case 'ebcdiccproece':
9690 case 'ebcdiccyrillic':
9731 case 'csiso143iecp271':
9741 case 'csiso50inis8':
9746 case 'csiso51iniscyrillic':
9747 case 'iniscyrillic':
9749 return 'INIS-cyrillic';
9756 return 'ISO-2022-CN';
9758 case 'iso2022cnext':
9759 return 'ISO-2022-CN-EXT';
9763 return 'ISO-2022-JP';
9765 case 'csiso2022jp2':
9767 return 'ISO-2022-JP-2';
9771 return 'ISO-2022-KR';
9773 case 'cswindows30latin1':
9774 case 'iso88591windows30latin1':
9775 return 'ISO-8859-1-Windows-3.0-Latin-1';
9777 case 'cswindows31latin1':
9778 case 'iso88591windows31latin1':
9779 return 'ISO-8859-1-Windows-3.1-Latin-1';
9785 case 'iso885921987':
9788 return 'ISO-8859-2';
9790 case 'cswindows31latin2':
9791 case 'iso88592windowslatin2':
9792 return 'ISO-8859-2-Windows-Latin-2';
9798 case 'iso885931988':
9801 return 'ISO-8859-3';
9807 case 'iso885941988':
9810 return 'ISO-8859-4';
9812 case 'csisolatincyrillic':
9817 case 'iso885951988':
9818 return 'ISO-8859-5';
9822 case 'csisolatinarabic':
9827 case 'iso885961987':
9828 return 'ISO-8859-6';
9833 return 'ISO-8859-6-E';
9838 return 'ISO-8859-6-I';
9840 case 'csisolatingreek':
9848 case 'iso885971987':
9849 return 'ISO-8859-7';
9851 case 'csisolatinhebrew':
9856 case 'iso885981988':
9857 return 'ISO-8859-8';
9862 return 'ISO-8859-8-E';
9867 return 'ISO-8859-8-I';
9869 case 'cswindows31latin5':
9870 case 'iso88599windowslatin5':
9871 return 'ISO-8859-9-Windows-Latin-5';
9876 case 'iso8859101992':
9879 return 'ISO-8859-10';
9882 return 'ISO-8859-13';
9888 case 'iso8859141998':
9891 return 'ISO-8859-14';
9896 return 'ISO-8859-15';
9901 case 'iso8859162001':
9904 return 'ISO-8859-16';
9907 return 'ISO-10646-J-1';
9910 case 'iso10646ucs2':
9911 return 'ISO-10646-UCS-2';
9914 case 'iso10646ucs4':
9915 return 'ISO-10646-UCS-4';
9917 case 'csunicodeascii':
9918 case 'iso10646ucsbasic':
9919 return 'ISO-10646-UCS-Basic';
9921 case 'csunicodelatin1':
9923 case 'iso10646unicodelatin1':
9924 return 'ISO-10646-Unicode-Latin1';
9926 case 'csiso10646utf1':
9927 case 'iso10646utf1':
9928 return 'ISO-10646-UTF-1';
9934 return 'ISO-11548-1';
9940 case 'csunicodeibm1261':
9941 case 'isounicodeibm1261':
9942 return 'ISO-Unicode-IBM-1261';
9944 case 'csunicodeibm1264':
9945 case 'isounicodeibm1264':
9946 return 'ISO-Unicode-IBM-1264';
9948 case 'csunicodeibm1265':
9949 case 'isounicodeibm1265':
9950 return 'ISO-Unicode-IBM-1265';
9952 case 'csunicodeibm1268':
9953 case 'isounicodeibm1268':
9954 return 'ISO-Unicode-IBM-1268';
9956 case 'csunicodeibm1276':
9957 case 'isounicodeibm1276':
9958 return 'ISO-Unicode-IBM-1276';
9960 case 'csiso646basic1983':
9961 case 'iso646basic1983':
9963 return 'ISO_646.basic:1983';
9965 case 'csiso2intlrefversion':
9968 case 'iso646irv1983':
9969 return 'ISO_646.irv:1983';
9975 return 'ISO_2033-1983';
9977 case 'csiso5427cyrillic':
9983 case 'iso5427cyrillic1981':
9985 return 'ISO_5427:1981';
9987 case 'csiso5428greek':
9990 return 'ISO_5428:1980';
9992 case 'csiso6937add':
9995 return 'ISO_6937-2-25';
9997 case 'csisotextcomm':
10000 return 'ISO_6937-2-add';
10002 case 'csiso8859supp':
10004 case 'iso8859supp':
10006 return 'ISO_8859-supp';
10008 case 'csiso10367box':
10010 case 'iso10367box':
10011 return 'ISO_10367-box';
10013 case 'csiso15italian':
10019 case 'csiso13jisc6220jp':
10021 case 'jisc62201969':
10022 case 'jisc62201969jp':
10025 return 'JIS_C6220-1969-jp';
10027 case 'csiso14jisc6220ro':
10030 case 'jisc62201969ro':
10032 return 'JIS_C6220-1969-ro';
10034 case 'csiso42jisc62261978':
10036 case 'jisc62261978':
10037 return 'JIS_C6226-1978';
10039 case 'csiso87jisx0208':
10041 case 'jisc62261983':
10042 case 'jisx02081983':
10044 return 'JIS_C6226-1983';
10046 case 'csiso91jisc62291984a':
10048 case 'jisc62291984a':
10050 return 'JIS_C6229-1984-a';
10052 case 'csiso92jisc62991984b':
10054 case 'iso646jpocrb':
10055 case 'jisc62291984b':
10057 return 'JIS_C6229-1984-b';
10059 case 'csiso93jis62291984badd':
10061 case 'jisc62291984badd':
10063 return 'JIS_C6229-1984-b-add';
10065 case 'csiso94jis62291984hand':
10067 case 'jisc62291984hand':
10069 return 'JIS_C6229-1984-hand';
10071 case 'csiso95jis62291984handadd':
10073 case 'jisc62291984handadd':
10074 case 'jpocrhandadd':
10075 return 'JIS_C6229-1984-hand-add';
10077 case 'csiso96jisc62291984kana':
10079 case 'jisc62291984kana':
10080 return 'JIS_C6229-1984-kana';
10082 case 'csjisencoding':
10083 case 'jisencoding':
10084 return 'JIS_Encoding';
10086 case 'cshalfwidthkatakana':
10089 return 'JIS_X0201';
10091 case 'csiso159jisx02121990':
10093 case 'jisx02121990':
10095 return 'JIS_X0212-1990';
10097 case 'csiso141jusib1002':
10103 return 'JUS_I.B1.002';
10105 case 'csiso147macedonian':
10107 case 'jusib1003mac':
10109 return 'JUS_I.B1.003-mac';
10111 case 'csiso146serbian':
10113 case 'jusib1003serb':
10115 return 'JUS_I.B1.003-serb';
10117 case 'koi7switched':
10118 return 'KOI7-switched';
10135 case 'strk10482002':
10138 case 'csiso19latingreek':
10141 return 'latin-greek';
10143 case 'csiso27latingreek1':
10145 case 'latingreek1':
10146 return 'Latin-greek-1';
10148 case 'csiso158lap':
10152 return 'latin-lap';
10154 case 'csmacintosh':
10157 return 'macintosh';
10159 case 'csmicrosoftpublishing':
10160 case 'microsoftpublishing':
10161 return 'Microsoft-Publishing';
10171 case 'csiso86hungarian':
10176 return 'MSZ_7795.3';
10181 return 'NATS-DANO';
10183 case 'csnatsdanoadd':
10185 case 'natsdanoadd':
10186 return 'NATS-DANO-ADD';
10191 return 'NATS-SEFI';
10193 case 'csnatssefiadd':
10195 case 'natssefiadd':
10196 return 'NATS-SEFI-ADD';
10198 case 'csiso151cuba':
10203 return 'NC_NC00-10:81';
10205 case 'csiso69french':
10210 return 'NF_Z_62-010';
10212 case 'csiso25french':
10215 case 'nfz620101973':
10216 return 'NF_Z_62-010_(1973)';
10218 case 'csiso60danishnorwegian':
10219 case 'csiso60norwegian1':
10224 return 'NS_4551-1';
10226 case 'csiso61norwegian2':
10231 return 'NS_4551-2';
10233 case 'osdebcdicdf03irv':
10234 return 'OSD_EBCDIC_DF03_IRV';
10236 case 'osdebcdicdf041':
10237 return 'OSD_EBCDIC_DF04_1';
10239 case 'osdebcdicdf0415':
10240 return 'OSD_EBCDIC_DF04_15';
10242 case 'cspc8danishnorwegian':
10243 case 'pc8danishnorwegian':
10244 return 'PC8-Danish-Norwegian';
10246 case 'cspc8turkish':
10248 return 'PC8-Turkish';
10250 case 'csiso16portuguese':
10256 case 'csiso84portuguese2':
10264 case 'cyrillicasian':
10272 case 'csiso10swedish':
10279 return 'SEN_850200_B';
10281 case 'csiso11swedishfornames':
10286 return 'SEN_850200_C';
10291 return 'Shift_JIS';
10293 case 'csiso102t617bit':
10296 return 'T.61-7bit';
10298 case 'csiso103t618bit':
10302 return 'T.61-8bit';
10304 case 'csiso128t101g2':
10313 case 'csunicode11':
10315 return 'UNICODE-1-1';
10317 case 'csunicode11utf7':
10318 case 'unicode11utf7':
10319 return 'UNICODE-1-1-UTF-7';
10321 case 'csunknown8bit':
10322 case 'unknown8bit':
10323 return 'UNKNOWN-8BIT';
10325 case 'ansix341968':
10326 case 'ansix341986':
10333 case 'iso646irv1991':
10366 case 'csventurainternational':
10367 case 'venturainternational':
10368 return 'Ventura-International';
10370 case 'csventuramath':
10371 case 'venturamath':
10372 return 'Ventura-Math';
10374 case 'csventuraus':
10376 return 'Ventura-US';
10378 case 'csiso70videotexsupp1':
10380 case 'videotexsuppl':
10381 return 'videotex-suppl';
10391 case 'cswindows31j':
10393 return 'Windows-31J';
10397 return 'Windows-874';
10402 case 'csksc56011987':
10406 case 'ksc56011987':
10407 case 'ksc56011989':
10408 return 'Windows-949';
10410 case 'windows1250':
10411 return 'windows-1250';
10413 case 'windows1251':
10414 return 'windows-1251';
10417 case 'csisolatin1':
10421 case 'iso885911987':
10424 case 'windows1252':
10425 return 'Windows-1252';
10427 case 'windows1252':
10428 return 'windows-1252';
10430 case 'windows1253':
10431 return 'windows-1253';
10433 case 'csisolatin5':
10436 case 'iso885991989':
10439 case 'windows1254':
10440 return 'Windows-1254';
10442 case 'windows1254':
10443 return 'windows-1254';
10445 case 'windows1255':
10446 return 'windows-1255';
10448 case 'windows1256':
10449 return 'windows-1256';
10451 case 'windows1257':
10452 return 'windows-1257';
10454 case 'windows1258':
10455 return 'windows-1258';
10462 function get_curl_version()
10464 if (is_array($curl = curl_version()))
10466 $curl = $curl['version'];
10468 elseif (substr($curl, 0, 5) == 'curl/')
10470 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10472 elseif (substr($curl, 0, 8) == 'libcurl/')
10474 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10483 function is_subclass_of($class1, $class2)
10485 if (func_num_args() != 2)
10487 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10489 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10491 return is_subclass_of($class1, $class2);
10493 elseif (is_string($class1) && is_string($class2))
10495 if (class_exists($class1))
10497 if (class_exists($class2))
10499 $class2 = strtolower($class2);
10500 while ($class1 = strtolower(get_parent_class($class1)))
10502 if ($class1 == $class2)
10511 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10518 * Strip HTML comments
10521 * @param string $data Data to strip comments from
10522 * @return string Comment stripped string
10524 function strip_comments($data)
10527 while (($start = strpos($data, '<!--')) !== false)
10529 $output .= substr($data, 0, $start);
10530 if (($end = strpos($data, '-->', $start)) !== false)
10532 $data = substr_replace($data, '', 0, $end + 3);
10539 return $output . $data;
10542 function parse_date($dt)
10544 $parser = SimplePie_Parse_Date::get();
10545 return $parser->parse($dt);
10549 * Decode HTML entities
10553 * @param string $data Input data
10554 * @return string Output data
10556 function entities_decode($data)
10558 $decoder = new SimplePie_Decode_HTML_Entities($data);
10559 return $decoder->parse();
10563 * Remove RFC822 comments
10566 * @param string $data Data to strip comments from
10567 * @return string Comment stripped string
10569 function uncomment_rfc822($string)
10571 $string = (string) $string;
10573 $length = strlen($string);
10578 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10580 $output .= substr($string, $position, $pos - $position);
10581 $position = $pos + 1;
10582 if ($string[$pos - 1] !== '\\')
10585 while ($depth && $position < $length)
10587 $position += strcspn($string, '()', $position);
10588 if ($string[$position - 1] === '\\')
10593 elseif (isset($string[$position]))
10595 switch ($string[$position])
10618 $output .= substr($string, $position);
10623 function parse_mime($mime)
10625 if (($pos = strpos($mime, ';')) === false)
10627 return trim($mime);
10631 return trim(substr($mime, 0, $pos));
10635 function htmlspecialchars_decode($string, $quote_style)
10637 if (function_exists('htmlspecialchars_decode'))
10639 return htmlspecialchars_decode($string, $quote_style);
10643 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10647 function atom_03_construct_type($attribs)
10649 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10651 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10655 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10657 if (isset($attribs['']['type']))
10659 switch (strtolower(trim($attribs['']['type'])))
10663 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10667 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10670 case 'application/xhtml+xml':
10671 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10674 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10679 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10683 function atom_10_construct_type($attribs)
10685 if (isset($attribs['']['type']))
10687 switch (strtolower(trim($attribs['']['type'])))
10690 return SIMPLEPIE_CONSTRUCT_TEXT;
10693 return SIMPLEPIE_CONSTRUCT_HTML;
10696 return SIMPLEPIE_CONSTRUCT_XHTML;
10699 return SIMPLEPIE_CONSTRUCT_NONE;
10702 return SIMPLEPIE_CONSTRUCT_TEXT;
10705 function atom_10_content_construct_type($attribs)
10707 if (isset($attribs['']['type']))
10709 $type = strtolower(trim($attribs['']['type']));
10713 return SIMPLEPIE_CONSTRUCT_TEXT;
10716 return SIMPLEPIE_CONSTRUCT_HTML;
10719 return SIMPLEPIE_CONSTRUCT_XHTML;
10721 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10723 return SIMPLEPIE_CONSTRUCT_NONE;
10727 return SIMPLEPIE_CONSTRUCT_BASE64;
10732 return SIMPLEPIE_CONSTRUCT_TEXT;
10736 function is_isegment_nz_nc($string)
10738 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);
10741 function space_seperated_tokens($string)
10743 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10744 $string_length = strlen($string);
10746 $position = strspn($string, $space_characters);
10749 while ($position < $string_length)
10751 $len = strcspn($string, $space_characters, $position);
10752 $tokens[] = substr($string, $position, $len);
10754 $position += strspn($string, $space_characters, $position);
10760 function array_unique($array)
10762 if (version_compare(PHP_VERSION, '5.2', '>='))
10764 return array_unique($array);
10768 $array = (array) $array;
10769 $new_array = array();
10770 $new_array_strings = array();
10771 foreach ($array as $key => $value)
10773 if (is_object($value))
10775 if (method_exists($value, '__toString'))
10777 $cmp = $value->__toString();
10781 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10784 elseif (is_array($value))
10786 $cmp = (string) reset($value);
10790 $cmp = (string) $value;
10792 if (!in_array($cmp, $new_array_strings))
10794 $new_array[$key] = $value;
10795 $new_array_strings[] = $cmp;
10803 * Converts a unicode codepoint to a UTF-8 character
10807 * @param int $codepoint Unicode codepoint
10808 * @return string UTF-8 character
10810 function codepoint_to_utf8($codepoint)
10812 static $cache = array();
10813 $codepoint = (int) $codepoint;
10814 if (isset($cache[$codepoint]))
10816 return $cache[$codepoint];
10818 elseif ($codepoint < 0)
10820 return $cache[$codepoint] = false;
10822 else if ($codepoint <= 0x7f)
10824 return $cache[$codepoint] = chr($codepoint);
10826 else if ($codepoint <= 0x7ff)
10828 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10830 else if ($codepoint <= 0xffff)
10832 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10834 else if ($codepoint <= 0x10ffff)
10836 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10840 // U+FFFD REPLACEMENT CHARACTER
10841 return $cache[$codepoint] = "\xEF\xBF\xBD";
10846 * Re-implementation of PHP 5's stripos()
10848 * Returns the numeric position of the first occurrence of needle in the
10853 * @param object $haystack
10854 * @param string $needle Note that the needle may be a string of one or more
10855 * characters. If needle is not a string, it is converted to an integer
10856 * and applied as the ordinal value of a character.
10857 * @param int $offset The optional offset parameter allows you to specify which
10858 * character in haystack to start searching. The position returned is still
10859 * relative to the beginning of haystack.
10860 * @return bool If needle is not found, stripos() will return boolean false.
10862 function stripos($haystack, $needle, $offset = 0)
10864 if (function_exists('stripos'))
10866 return stripos($haystack, $needle, $offset);
10870 if (is_string($needle))
10872 $needle = strtolower($needle);
10874 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10876 $needle = strtolower(chr($needle));
10880 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10884 return strpos(strtolower($haystack), $needle, $offset);
10889 * Similar to parse_str()
10891 * Returns an associative array of name/value pairs, where the value is an
10892 * array of values that have used the same name
10896 * @param string $str The input string.
10899 function parse_str($str)
10902 $str = explode('&', $str);
10904 foreach ($str as $section)
10906 if (strpos($section, '=') !== false)
10908 list($name, $value) = explode('=', $section, 2);
10909 $return[urldecode($name)][] = urldecode($value);
10913 $return[urldecode($section)][] = null;
10921 * Detect XML encoding, as per XML 1.0 Appendix F.1
10923 * @todo Add support for EBCDIC
10924 * @param string $data XML data
10925 * @return array Possible encodings
10927 function xml_encoding($data)
10929 // UTF-32 Big Endian BOM
10930 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10932 $encoding[] = 'UTF-32BE';
10934 // UTF-32 Little Endian BOM
10935 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10937 $encoding[] = 'UTF-32LE';
10939 // UTF-16 Big Endian BOM
10940 elseif (substr($data, 0, 2) === "\xFE\xFF")
10942 $encoding[] = 'UTF-16BE';
10944 // UTF-16 Little Endian BOM
10945 elseif (substr($data, 0, 2) === "\xFF\xFE")
10947 $encoding[] = 'UTF-16LE';
10950 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10952 $encoding[] = 'UTF-8';
10954 // UTF-32 Big Endian Without BOM
10955 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")
10957 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10959 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10960 if ($parser->parse())
10962 $encoding[] = $parser->encoding;
10965 $encoding[] = 'UTF-32BE';
10967 // UTF-32 Little Endian Without BOM
10968 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")
10970 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10972 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10973 if ($parser->parse())
10975 $encoding[] = $parser->encoding;
10978 $encoding[] = 'UTF-32LE';
10980 // UTF-16 Big Endian Without BOM
10981 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10983 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10985 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10986 if ($parser->parse())
10988 $encoding[] = $parser->encoding;
10991 $encoding[] = 'UTF-16BE';
10993 // UTF-16 Little Endian Without BOM
10994 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10996 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10998 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10999 if ($parser->parse())
11001 $encoding[] = $parser->encoding;
11004 $encoding[] = 'UTF-16LE';
11006 // US-ASCII (or superset)
11007 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11009 if ($pos = strpos($data, "\x3F\x3E"))
11011 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11012 if ($parser->parse())
11014 $encoding[] = $parser->encoding;
11017 $encoding[] = 'UTF-8';
11019 // Fallback to UTF-8
11022 $encoding[] = 'UTF-8';
11029 * Decode HTML Entities
11031 * This implements HTML5 as of revision 967 (2007-06-28)
11033 * @package SimplePie
11035 class SimplePie_Decode_HTML_Entities
11038 * Data to be parsed
11046 * Currently consumed bytes
11051 var $consumed = '';
11054 * Position of the current byte being parsed
11062 * Create an instance of the class with the input data
11065 * @param string $data Input data
11067 function SimplePie_Decode_HTML_Entities($data)
11069 $this->data = $data;
11073 * Parse the input data
11076 * @return string Output data
11080 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11084 $this->consumed = '';
11086 return $this->data;
11090 * Consume the next byte
11093 * @return mixed The next byte, or false, if there is no more data
11097 if (isset($this->data[$this->position]))
11099 $this->consumed .= $this->data[$this->position];
11100 return $this->data[$this->position++];
11104 $this->consumed = false;
11110 * Consume a range of characters
11113 * @param string $chars Characters to consume
11114 * @return mixed A series of characters that match the range, or false
11116 function consume_range($chars)
11118 if ($len = strspn($this->data, $chars, $this->position))
11120 $data = substr($this->data, $this->position, $len);
11121 $this->consumed .= $data;
11122 $this->position += $len;
11127 $this->consumed = false;
11133 * Unconsume one byte
11137 function unconsume()
11139 $this->consumed = substr($this->consumed, 0, -1);
11150 switch ($this->consume())
11164 switch ($this->consume())
11168 $range = '0123456789ABCDEFabcdef';
11173 $range = '0123456789';
11175 $this->unconsume();
11179 if ($codepoint = $this->consume_range($range))
11181 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");
11185 $codepoint = hexdec($codepoint);
11189 $codepoint = intval($codepoint);
11192 if (isset($windows_1252_specials[$codepoint]))
11194 $replacement = $windows_1252_specials[$codepoint];
11198 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11201 if ($this->consume() != ';')
11203 $this->unconsume();
11206 $consumed_length = strlen($this->consumed);
11207 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11208 $this->position += strlen($replacement) - $consumed_length;
11213 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");
11215 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11217 $consumed = substr($this->consumed, 1);
11218 if (isset($entities[$consumed]))
11220 $match = $consumed;
11224 if ($match !== null)
11226 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11227 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11237 * @package SimplePie
11239 class SimplePie_Parse_Date
11244 * @access protected
11250 * List of days, calendar day name => ordinal day number in the week
11252 * @access protected
11315 'keskiviikko' => 3,
11339 * List of months, calendar month name => calendar month number
11341 * @access protected
11344 var $month = array(
11355 // No long form of May
11484 * List of timezones, abbreviation => offset from UTC
11486 * @access protected
11489 var $timezone = array(
11692 * Cached PCRE for SimplePie_Parse_Date::$day
11694 * @access protected
11700 * Cached PCRE for SimplePie_Parse_Date::$month
11702 * @access protected
11708 * Array of user-added callback methods
11713 var $built_in = array();
11716 * Array of user-added callback methods
11721 var $user = array();
11724 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11725 * self::month_pcre, and self::built_in
11729 function SimplePie_Parse_Date()
11731 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11732 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11735 if (!isset($cache[get_class($this)]))
11737 if (extension_loaded('Reflection'))
11739 $class = new ReflectionClass(get_class($this));
11740 $methods = $class->getMethods();
11741 $all_methods = array();
11742 foreach ($methods as $method)
11744 $all_methods[] = $method->getName();
11749 $all_methods = get_class_methods($this);
11752 foreach ($all_methods as $method)
11754 if (strtolower(substr($method, 0, 5)) === 'date_')
11756 $cache[get_class($this)][] = $method;
11761 foreach ($cache[get_class($this)] as $method)
11763 $this->built_in[] = $method;
11777 $object = new SimplePie_Parse_Date;
11787 * @param string $date Date to parse
11788 * @return int Timestamp corresponding to date string, or false on failure
11790 function parse($date)
11792 foreach ($this->user as $method)
11794 if (($returned = call_user_func($method, $date)) !== false)
11800 foreach ($this->built_in as $method)
11802 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11812 * Add a callback method to parse a date
11816 * @param callback $callback
11818 function add_callback($callback)
11820 if (is_callable($callback))
11822 $this->user[] = $callback;
11826 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11831 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11832 * well as allowing any of upper or lower case "T", horizontal tabs, or
11833 * spaces to be used as the time seperator (including more than one))
11835 * @access protected
11836 * @return int Timestamp
11838 function date_w3cdtf($date)
11843 $year = '([0-9]{4})';
11844 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11845 $decimal = '([0-9]*)';
11846 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11847 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11849 if (preg_match($pcre, $date, $match))
11852 Capturing subpatterns:
11859 7: Decimal fraction of a second
11863 11: Timezone minutes
11866 // Fill in empty matches
11867 for ($i = count($match); $i <= 3; $i++)
11872 for ($i = count($match); $i <= 7; $i++)
11877 // Numeric timezone
11878 if (isset($match[9]) && $match[9] !== '')
11880 $timezone = $match[10] * 3600;
11881 $timezone += $match[11] * 60;
11882 if ($match[9] === '-')
11884 $timezone = 0 - $timezone;
11892 // Convert the number of seconds to an integer, taking decimals into account
11893 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11895 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11904 * Remove RFC822 comments
11906 * @access protected
11907 * @param string $data Data to strip comments from
11908 * @return string Comment stripped string
11910 function remove_rfc2822_comments($string)
11912 $string = (string) $string;
11914 $length = strlen($string);
11919 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11921 $output .= substr($string, $position, $pos - $position);
11922 $position = $pos + 1;
11923 if ($string[$pos - 1] !== '\\')
11926 while ($depth && $position < $length)
11928 $position += strcspn($string, '()', $position);
11929 if ($string[$position - 1] === '\\')
11934 elseif (isset($string[$position]))
11936 switch ($string[$position])
11959 $output .= substr($string, $position);
11965 * Parse RFC2822's date format
11967 * @access protected
11968 * @return int Timestamp
11970 function date_rfc2822($date)
11975 $wsp = '[\x09\x20]';
11976 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11977 $optional_fws = $fws . '?';
11978 $day_name = $this->day_pcre;
11979 $month = $this->month_pcre;
11980 $day = '([0-9]{1,2})';
11981 $hour = $minute = $second = '([0-9]{2})';
11982 $year = '([0-9]{2,4})';
11983 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11984 $character_zone = '([A-Z]{1,5})';
11985 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11986 $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';
11988 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11991 Capturing subpatterns:
12001 10: Timezone minutes
12002 11: Alphabetic timezone
12005 // Find the month number
12006 $month = $this->month[strtolower($match[3])];
12008 // Numeric timezone
12009 if ($match[8] !== '')
12011 $timezone = $match[9] * 3600;
12012 $timezone += $match[10] * 60;
12013 if ($match[8] === '-')
12015 $timezone = 0 - $timezone;
12018 // Character timezone
12019 elseif (isset($this->timezone[strtoupper($match[11])]))
12021 $timezone = $this->timezone[strtoupper($match[11])];
12023 // Assume everything else to be -0000
12029 // Deal with 2/3 digit years
12030 if ($match[4] < 50)
12034 elseif ($match[4] < 1000)
12039 // Second is optional, if it is empty set it to zero
12040 if ($match[7] !== '')
12042 $second = $match[7];
12049 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12058 * Parse RFC850's date format
12060 * @access protected
12061 * @return int Timestamp
12063 function date_rfc850($date)
12068 $space = '[\x09\x20]+';
12069 $day_name = $this->day_pcre;
12070 $month = $this->month_pcre;
12071 $day = '([0-9]{1,2})';
12072 $year = $hour = $minute = $second = '([0-9]{2})';
12073 $zone = '([A-Z]{1,5})';
12074 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12076 if (preg_match($pcre, $date, $match))
12079 Capturing subpatterns:
12091 $month = $this->month[strtolower($match[3])];
12093 // Character timezone
12094 if (isset($this->timezone[strtoupper($match[8])]))
12096 $timezone = $this->timezone[strtoupper($match[8])];
12098 // Assume everything else to be -0000
12104 // Deal with 2 digit year
12105 if ($match[4] < 50)
12114 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12123 * Parse C99's asctime()'s date format
12125 * @access protected
12126 * @return int Timestamp
12128 function date_asctime($date)
12133 $space = '[\x09\x20]+';
12134 $wday_name = $this->day_pcre;
12135 $mon_name = $this->month_pcre;
12136 $day = '([0-9]{1,2})';
12137 $hour = $sec = $min = '([0-9]{2})';
12138 $year = '([0-9]{4})';
12139 $terminator = '\x0A?\x00?';
12140 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12142 if (preg_match($pcre, $date, $match))
12145 Capturing subpatterns:
12155 $month = $this->month[strtolower($match[2])];
12156 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12165 * Parse dates using strtotime()
12167 * @access protected
12168 * @return int Timestamp
12170 function date_strtotime($date)
12172 $strtotime = strtotime($date);
12173 if ($strtotime === -1 || $strtotime === false)
12185 * Content-type sniffing
12187 * @package SimplePie
12189 class SimplePie_Content_Type_Sniffer
12194 * @var SimplePie_File
12200 * Create an instance of the class with the input file
12203 * @param SimplePie_Content_Type_Sniffer $file Input file
12205 function SimplePie_Content_Type_Sniffer($file)
12207 $this->file = $file;
12211 * Get the Content-Type of the specified file
12214 * @return string Actual Content-Type
12216 function get_type()
12218 if (isset($this->file->headers['content-type']))
12220 if (!isset($this->file->headers['content-encoding'])
12221 && ($this->file->headers['content-type'] === 'text/plain'
12222 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12223 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12225 return $this->text_or_binary();
12228 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12230 $official = substr($this->file->headers['content-type'], 0, $pos);
12234 $official = $this->file->headers['content-type'];
12236 $official = strtolower($official);
12238 if ($official === 'unknown/unknown'
12239 || $official === 'application/unknown')
12241 return $this->unknown();
12243 elseif (substr($official, -4) === '+xml'
12244 || $official === 'text/xml'
12245 || $official === 'application/xml')
12249 elseif (substr($official, 0, 6) === 'image/')
12251 if ($return = $this->image())
12260 elseif ($official === 'text/html')
12262 return $this->feed_or_html();
12271 return $this->unknown();
12276 * Sniff text or binary
12279 * @return string Actual Content-Type
12281 function text_or_binary()
12283 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12284 || substr($this->file->body, 0, 2) === "\xFF\xFE"
12285 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12286 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12288 return 'text/plain';
12290 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12292 return 'application/octect-stream';
12296 return 'text/plain';
12304 * @return string Actual Content-Type
12308 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12309 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12310 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12311 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12313 return 'text/html';
12315 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12317 return 'application/pdf';
12319 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12321 return 'application/postscript';
12323 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12324 || substr($this->file->body, 0, 6) === 'GIF89a')
12326 return 'image/gif';
12328 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12330 return 'image/png';
12332 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12334 return 'image/jpeg';
12336 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12338 return 'image/bmp';
12342 return $this->text_or_binary();
12350 * @return string Actual Content-Type
12354 if (substr($this->file->body, 0, 6) === 'GIF87a'
12355 || substr($this->file->body, 0, 6) === 'GIF89a')
12357 return 'image/gif';
12359 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12361 return 'image/png';
12363 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12365 return 'image/jpeg';
12367 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12369 return 'image/bmp';
12381 * @return string Actual Content-Type
12383 function feed_or_html()
12385 $len = strlen($this->file->body);
12386 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12388 while ($pos < $len)
12390 switch ($this->file->body[$pos])
12396 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12404 return 'text/html';
12407 if (substr($this->file->body, $pos, 3) === '!--')
12410 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12416 return 'text/html';
12419 elseif (substr($this->file->body, $pos, 1) === '!')
12421 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12427 return 'text/html';
12430 elseif (substr($this->file->body, $pos, 1) === '?')
12432 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12438 return 'text/html';
12441 elseif (substr($this->file->body, $pos, 3) === 'rss'
12442 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12444 return 'application/rss+xml';
12446 elseif (substr($this->file->body, $pos, 4) === 'feed')
12448 return 'application/atom+xml';
12452 return 'text/html';
12456 return 'text/html';
12461 * Parses the XML Declaration
12463 * @package SimplePie
12465 class SimplePie_XML_Declaration_Parser
12473 var $version = '1.0';
12481 var $encoding = 'UTF-8';
12489 var $standalone = false;
12492 * Current state of the state machine
12497 var $state = 'before_version_name';
12508 * Input data length (to avoid calling strlen() everytime this is needed)
12513 var $data_length = 0;
12516 * Current position of the pointer
12524 * Create an instance of the class with the input data
12527 * @param string $data Input data
12529 function SimplePie_XML_Declaration_Parser($data)
12531 $this->data = $data;
12532 $this->data_length = strlen($this->data);
12536 * Parse the input data
12539 * @return bool true on success, false on failure
12543 while ($this->state && $this->state !== 'emit' && $this->has_data())
12545 $state = $this->state;
12549 if ($this->state === 'emit')
12555 $this->version = '';
12556 $this->encoding = '';
12557 $this->standalone = '';
12563 * Check whether there is data beyond the pointer
12566 * @return bool true if there is further data, false if not
12568 function has_data()
12570 return (bool) ($this->position < $this->data_length);
12574 * Advance past any whitespace
12576 * @return int Number of whitespace characters passed
12578 function skip_whitespace()
12580 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12581 $this->position += $whitespace;
12582 return $whitespace;
12588 function get_value()
12590 $quote = substr($this->data, $this->position, 1);
12591 if ($quote === '"' || $quote === "'")
12594 $len = strcspn($this->data, $quote, $this->position);
12595 if ($this->has_data())
12597 $value = substr($this->data, $this->position, $len);
12598 $this->position += $len + 1;
12605 function before_version_name()
12607 if ($this->skip_whitespace())
12609 $this->state = 'version_name';
12613 $this->state = false;
12617 function version_name()
12619 if (substr($this->data, $this->position, 7) === 'version')
12621 $this->position += 7;
12622 $this->skip_whitespace();
12623 $this->state = 'version_equals';
12627 $this->state = false;
12631 function version_equals()
12633 if (substr($this->data, $this->position, 1) === '=')
12636 $this->skip_whitespace();
12637 $this->state = 'version_value';
12641 $this->state = false;
12645 function version_value()
12647 if ($this->version = $this->get_value())
12649 $this->skip_whitespace();
12650 if ($this->has_data())
12652 $this->state = 'encoding_name';
12656 $this->state = 'emit';
12661 $this->state = 'standalone_name';
12665 function encoding_name()
12667 if (substr($this->data, $this->position, 8) === 'encoding')
12669 $this->position += 8;
12670 $this->skip_whitespace();
12671 $this->state = 'encoding_equals';
12675 $this->state = false;
12679 function encoding_equals()
12681 if (substr($this->data, $this->position, 1) === '=')
12684 $this->skip_whitespace();
12685 $this->state = 'encoding_value';
12689 $this->state = false;
12693 function encoding_value()
12695 if ($this->encoding = $this->get_value())
12697 $this->skip_whitespace();
12698 if ($this->has_data())
12700 $this->state = 'standalone_name';
12704 $this->state = 'emit';
12709 $this->state = false;
12713 function standalone_name()
12715 if (substr($this->data, $this->position, 10) === 'standalone')
12717 $this->position += 10;
12718 $this->skip_whitespace();
12719 $this->state = 'standalone_equals';
12723 $this->state = false;
12727 function standalone_equals()
12729 if (substr($this->data, $this->position, 1) === '=')
12732 $this->skip_whitespace();
12733 $this->state = 'standalone_value';
12737 $this->state = false;
12741 function standalone_value()
12743 if ($standalone = $this->get_value())
12745 switch ($standalone)
12748 $this->standalone = true;
12752 $this->standalone = false;
12756 $this->state = false;
12760 $this->skip_whitespace();
12761 if ($this->has_data())
12763 $this->state = false;
12767 $this->state = 'emit';
12772 $this->state = false;
12777 class SimplePie_Locator
12782 var $local = array();
12783 var $elsewhere = array();
12784 var $file_class = 'SimplePie_File';
12785 var $cached_entities = array();
12788 var $base_location = 0;
12789 var $checked_feeds = 0;
12790 var $max_checked_feeds = 10;
12791 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12793 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12795 $this->file =& $file;
12796 $this->file_class = $file_class;
12797 $this->useragent = $useragent;
12798 $this->timeout = $timeout;
12799 $this->max_checked_feeds = $max_checked_feeds;
12800 $this->content_type_sniffer_class = $content_type_sniffer_class;
12803 function find($type = SIMPLEPIE_LOCATOR_ALL)
12805 if ($this->is_feed($this->file))
12807 return $this->file;
12810 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12812 $sniffer = new $this->content_type_sniffer_class($this->file);
12813 if ($sniffer->get_type() !== 'text/html')
12819 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12824 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12829 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12831 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12836 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12841 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12846 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12854 function is_feed(&$file)
12856 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12858 $sniffer = new $this->content_type_sniffer_class($file);
12859 $sniffed = $sniffer->get_type();
12860 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12869 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12879 function get_base()
12881 $this->http_base = $this->file->url;
12882 $this->base = $this->http_base;
12883 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12884 foreach ($elements as $element)
12886 if ($element['attribs']['href']['data'] !== '')
12888 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12889 $this->base_location = $element['offset'];
12895 function autodiscovery()
12897 $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));
12899 foreach ($links as $link)
12901 if ($this->checked_feeds == $this->max_checked_feeds)
12905 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12907 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12909 if ($this->base_location < $link['offset'])
12911 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12915 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12918 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'))))
12920 $this->checked_feeds++;
12921 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12922 if ($this->is_feed($feed))
12933 function get_links()
12935 $links = SimplePie_Misc::get_element('a', $this->file->body);
12936 foreach ($links as $link)
12938 if (isset($link['attribs']['href']['data']))
12940 $href = trim($link['attribs']['href']['data']);
12941 $parsed = SimplePie_Misc::parse_url($href);
12942 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12944 if ($this->base_location < $link['offset'])
12946 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12950 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12953 $current = SimplePie_Misc::parse_url($this->file->url);
12955 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12957 $this->local[] = $href;
12961 $this->elsewhere[] = $href;
12966 $this->local = array_unique($this->local);
12967 $this->elsewhere = array_unique($this->elsewhere);
12968 if (!empty($this->local) || !empty($this->elsewhere))
12975 function extension(&$array)
12977 foreach ($array as $key => $value)
12979 if ($this->checked_feeds == $this->max_checked_feeds)
12983 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12985 $this->checked_feeds++;
12986 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12987 if ($this->is_feed($feed))
12993 unset($array[$key]);
13000 function body(&$array)
13002 foreach ($array as $key => $value)
13004 if ($this->checked_feeds == $this->max_checked_feeds)
13008 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13010 $this->checked_feeds++;
13011 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
13012 if ($this->is_feed($feed))
13018 unset($array[$key]);
13026 class SimplePie_Parser
13031 var $current_column;
13033 var $separator = ' ';
13035 var $namespace = array('');
13036 var $element = array('');
13037 var $xml_base = array('');
13038 var $xml_base_explicit = array(false);
13039 var $xml_lang = array('');
13040 var $data = array();
13041 var $datas = array(array());
13042 var $current_xhtml_construct = -1;
13045 function parse(&$data, $encoding)
13047 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13048 if (strtoupper($encoding) == 'US-ASCII')
13050 $this->encoding = 'UTF-8';
13054 $this->encoding = $encoding;
13058 // UTF-32 Big Endian BOM
13059 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13061 $data = substr($data, 4);
13063 // UTF-32 Little Endian BOM
13064 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13066 $data = substr($data, 4);
13068 // UTF-16 Big Endian BOM
13069 elseif (substr($data, 0, 2) === "\xFE\xFF")
13071 $data = substr($data, 2);
13073 // UTF-16 Little Endian BOM
13074 elseif (substr($data, 0, 2) === "\xFF\xFE")
13076 $data = substr($data, 2);
13079 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13081 $data = substr($data, 3);
13084 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13086 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13087 if ($declaration->parse())
13089 $data = substr($data, $pos + 2);
13090 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13094 $this->error_string = 'SimplePie bug! Please report this!';
13099 // Work around libxml bug
13100 $data = str_replace('<', '<', $data);
13101 $data = str_replace('>', '>', $data);
13102 $data = str_replace('&', '&', $data);
13103 $data = str_replace(''', ''', $data);
13104 $data = str_replace('"', '"', $data);
13108 // Create the parser
13109 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13110 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13111 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13112 xml_set_object($xml, $this);
13113 xml_set_character_data_handler($xml, 'cdata');
13114 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13117 if (!xml_parse($xml, $data, true))
13119 $this->error_code = xml_get_error_code($xml);
13120 $this->error_string = xml_error_string($this->error_code);
13123 $this->current_line = xml_get_current_line_number($xml);
13124 $this->current_column = xml_get_current_column_number($xml);
13125 $this->current_byte = xml_get_current_byte_index($xml);
13126 xml_parser_free($xml);
13130 function get_error_code()
13132 return $this->error_code;
13135 function get_error_string()
13137 return $this->error_string;
13140 function get_current_line()
13142 return $this->current_line;
13145 function get_current_column()
13147 return $this->current_column;
13150 function get_current_byte()
13152 return $this->current_byte;
13155 function get_data()
13157 return $this->data;
13160 function tag_open($parser, $tag, $attributes)
13162 if ($this->feed === 0)
13166 elseif ($this->feed == false)
13168 if (in_array($tag, array(
13169 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13170 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13172 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13183 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13185 $attribs = array();
13186 foreach ($attributes as $name => $value)
13188 list($attrib_namespace, $attribute) = $this->split_ns($name);
13189 $attribs[$attrib_namespace][$attribute] = $value;
13192 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13194 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13195 $this->xml_base_explicit[] = true;
13199 $this->xml_base[] = end($this->xml_base);
13200 $this->xml_base_explicit[] = end($this->xml_base_explicit);
13203 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13205 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13209 $this->xml_lang[] = end($this->xml_lang);
13212 if ($this->current_xhtml_construct >= 0)
13214 $this->current_xhtml_construct++;
13215 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13217 $this->data['data'] .= '<' . end($this->element);
13218 if (isset($attribs['']))
13220 foreach ($attribs[''] as $name => $value)
13222 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13225 $this->data['data'] .= '>';
13230 $this->datas[] =& $this->data;
13231 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13232 $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));
13233 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')
13234 || (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'))
13236 $this->current_xhtml_construct = 0;
13241 function cdata($parser, $cdata)
13243 if ($this->current_xhtml_construct >= 0)
13245 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13247 elseif ($this->feed > 1)
13249 $this->data['data'] .= $cdata;
13253 function tag_close($parser, $tag)
13260 if ($this->current_xhtml_construct >= 0)
13262 $this->current_xhtml_construct--;
13263 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')))
13265 $this->data['data'] .= '</' . end($this->element) . '>';
13268 if ($this->current_xhtml_construct == -1)
13270 $this->data =& $this->datas[$this->feed];
13271 array_pop($this->datas);
13274 array_pop($this->element);
13275 array_pop($this->namespace);
13276 array_pop($this->xml_base);
13277 array_pop($this->xml_base_explicit);
13278 array_pop($this->xml_lang);
13282 function split_ns($string)
13284 static $cache = array();
13285 if (!isset($cache[$string]))
13287 if ($pos = strpos($string, $this->separator))
13289 static $separator_length;
13290 if (!$separator_length)
13292 $separator_length = strlen($this->separator);
13294 $namespace = substr($string, 0, $pos);
13295 $local_name = substr($string, $pos + $separator_length);
13296 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13298 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13301 // Normalize the Media RSS namespaces
13302 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13304 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13306 $cache[$string] = array($namespace, $local_name);
13310 $cache[$string] = array('', $string);
13313 return $cache[$string];
13318 * @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
13320 class SimplePie_Sanitize
13326 var $remove_div = true;
13327 var $image_handler = '';
13328 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13329 var $encode_instead_of_strip = false;
13330 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13331 var $strip_comments = false;
13332 var $output_encoding = 'UTF-8';
13333 var $enable_cache = true;
13334 var $cache_location = './cache';
13335 var $cache_name_function = 'md5';
13336 var $cache_class = 'SimplePie_Cache';
13337 var $file_class = 'SimplePie_File';
13339 var $useragent = '';
13340 var $force_fsockopen = false;
13342 var $replace_url_attributes = array(
13345 'blockquote' => 'cite',
13347 'form' => 'action',
13348 'img' => array('longdesc', 'src'),
13354 function remove_div($enable = true)
13356 $this->remove_div = (bool) $enable;
13359 function set_image_handler($page = false)
13363 $this->image_handler = (string) $page;
13367 $this->image_handler = false;
13371 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13373 if (isset($enable_cache))
13375 $this->enable_cache = (bool) $enable_cache;
13378 if ($cache_location)
13380 $this->cache_location = (string) $cache_location;
13383 if ($cache_name_function)
13385 $this->cache_name_function = (string) $cache_name_function;
13390 $this->cache_class = (string) $cache_class;
13394 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13398 $this->file_class = (string) $file_class;
13403 $this->timeout = (string) $timeout;
13408 $this->useragent = (string) $useragent;
13411 if ($force_fsockopen)
13413 $this->force_fsockopen = (string) $force_fsockopen;
13417 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13421 if (is_array($tags))
13423 $this->strip_htmltags = $tags;
13427 $this->strip_htmltags = explode(',', $tags);
13432 $this->strip_htmltags = false;
13436 function encode_instead_of_strip($encode = false)
13438 $this->encode_instead_of_strip = (bool) $encode;
13441 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13445 if (is_array($attribs))
13447 $this->strip_attributes = $attribs;
13451 $this->strip_attributes = explode(',', $attribs);
13456 $this->strip_attributes = false;
13460 function strip_comments($strip = false)
13462 $this->strip_comments = (bool) $strip;
13465 function set_output_encoding($encoding = 'UTF-8')
13467 $this->output_encoding = (string) $encoding;
13471 * Set element/attribute key/value pairs of HTML attributes
13472 * containing URLs that need to be resolved relative to the feed
13476 * @param array $element_attribute Element/attribute key/value pairs
13478 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'))
13480 $this->replace_url_attributes = (array) $element_attribute;
13483 function sanitize($data, $type, $base = '')
13485 $data = trim($data);
13486 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13488 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13490 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))
13492 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13496 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13500 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13502 $data = base64_decode($data);
13505 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13507 if ($this->remove_div)
13509 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13510 $data = preg_replace('/<\/div>$/', '', $data);
13514 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13518 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13521 if ($this->strip_comments)
13523 $data = SimplePie_Misc::strip_comments($data);
13526 // Strip out HTML tags and attributes that might cause various security problems.
13527 // Based on recommendations by Mark Pilgrim at:
13528 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13529 if ($this->strip_htmltags)
13531 foreach ($this->strip_htmltags as $tag)
13533 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13534 while (preg_match($pcre, $data))
13536 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13541 if ($this->strip_attributes)
13543 foreach ($this->strip_attributes as $attrib)
13545 $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);
13549 // Replace relative URLs
13550 $this->base = $base;
13551 foreach ($this->replace_url_attributes as $element => $attributes)
13553 $data = $this->replace_urls($data, $element, $attributes);
13556 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13557 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13559 $images = SimplePie_Misc::get_element('img', $data);
13560 foreach ($images as $img)
13562 if (isset($img['attribs']['src']['data']))
13564 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13565 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13567 if ($cache->load())
13569 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13570 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13574 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13575 $headers = $file->headers;
13577 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13579 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13581 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13582 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13586 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13594 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13595 $data = trim($data);
13598 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13600 $data = SimplePie_Misc::absolutize_url($data, $base);
13603 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13605 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13608 if ($this->output_encoding != 'UTF-8')
13610 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13616 function replace_urls($data, $tag, $attributes)
13618 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13620 $elements = SimplePie_Misc::get_element($tag, $data);
13621 foreach ($elements as $element)
13623 if (is_array($attributes))
13625 foreach ($attributes as $attribute)
13627 if (isset($element['attribs'][$attribute]['data']))
13629 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13630 $new_element = SimplePie_Misc::element_implode($element);
13631 $data = str_replace($element['full'], $new_element, $data);
13632 $element['full'] = $new_element;
13636 elseif (isset($element['attribs'][$attributes]['data']))
13638 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13639 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13646 function do_strip_htmltags($match)
13648 if ($this->encode_instead_of_strip)
13650 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13652 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13653 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13654 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13658 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13661 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))