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 ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
756 if (!empty($this->data['items']))
758 foreach ($this->data['items'] as $item)
762 unset($item, $this->data['items']);
764 if (!empty($this->data['ordered_items']))
766 foreach ($this->data['ordered_items'] as $item)
770 unset($item, $this->data['ordered_items']);
776 * Force the given data/URL to be treated as a feed no matter what it
781 * @param bool $enable Force the given data/URL to be treated as a feed
783 function force_feed($enable = false)
785 $this->force_feed = (bool) $enable;
789 * This is the URL of the feed you want to parse.
791 * This allows you to enter the URL of the feed you want to parse, or the
792 * website you want to try to use auto-discovery on. This takes priority
793 * over any set raw data.
795 * You can set multiple feeds to mash together by passing an array instead
796 * of a string for the $url. Remember that with each additional feed comes
797 * additional processing and resources.
800 * @since 1.0 Preview Release
801 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
802 * @see SimplePie::set_raw_data()
804 function set_feed_url($url)
808 $this->multifeed_url = array();
809 foreach ($url as $value)
811 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
816 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
821 * Provides an instance of SimplePie_File to use as a feed
824 * @param object &$file Instance of SimplePie_File (or subclass)
825 * @return bool True on success, false on failure
827 function set_file(&$file)
829 if (is_a($file, 'SimplePie_File'))
831 $this->feed_url = $file->url;
832 $this->file =& $file;
839 * Allows you to use a string of RSS/Atom data instead of a remote feed.
841 * If you have a feed available as a string in PHP, you can tell SimplePie
842 * to parse that data string instead of a remote feed. Any set feed URL
847 * @param string $data RSS or Atom data as a string.
848 * @see SimplePie::set_feed_url()
850 function set_raw_data($data)
852 $this->raw_data = $data;
856 * Allows you to override the default timeout for fetching remote feeds.
858 * This allows you to change the maximum time the feed's server to respond
859 * and send the feed back.
863 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
865 function set_timeout($timeout = 10)
867 $this->timeout = (int) $timeout;
871 * Forces SimplePie to use fsockopen() instead of the preferred cURL
876 * @param bool $enable Force fsockopen() to be used
878 function force_fsockopen($enable = false)
880 $this->force_fsockopen = (bool) $enable;
884 * Outputs the raw XML content of the feed, after it has gone through
885 * SimplePie's filters.
887 * Used only for debugging, this function will output the XML content as
888 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
889 * before trying to parse it. Many parts of the feed are re-written in
890 * memory, and in the end, you have a parsable feed. XML dump shows you the
891 * actual XML that SimplePie tries to parse, which may or may not be very
892 * different from the original feed.
895 * @since 1.0 Preview Release
896 * @param bool $enable Enable XML dump
898 function enable_xml_dump($enable = false)
900 $this->xml_dump = (bool) $enable;
904 * Enables/disables caching in SimplePie.
906 * This option allows you to disable caching all-together in SimplePie.
907 * However, disabling the cache can lead to longer load times.
910 * @since 1.0 Preview Release
911 * @param bool $enable Enable caching
913 function enable_cache($enable = true)
915 $this->cache = (bool) $enable;
919 * Set the length of time (in seconds) that the contents of a feed
923 * @param int $seconds The feed content cache duration.
925 function set_cache_duration($seconds = 3600)
927 $this->cache_duration = (int) $seconds;
931 * Set the length of time (in seconds) that the autodiscovered feed
932 * URL will be cached.
935 * @param int $seconds The autodiscovered feed URL cache duration.
937 function set_autodiscovery_cache_duration($seconds = 604800)
939 $this->autodiscovery_cache_duration = (int) $seconds;
943 * Set the file system location where the cached files should be stored.
946 * @param string $location The file system location.
948 function set_cache_location($location = './cache')
950 $this->cache_location = (string) $location;
954 * Determines whether feed items should be sorted into reverse chronological order.
957 * @param bool $enable Sort as reverse chronological order.
959 function enable_order_by_date($enable = true)
961 $this->order_by_date = (bool) $enable;
965 * Allows you to override the character encoding reported by the feed.
968 * @param string $encoding Character encoding.
970 function set_input_encoding($encoding = false)
974 $this->input_encoding = (string) $encoding;
978 $this->input_encoding = false;
983 * Set how much feed autodiscovery to do
986 * @see SIMPLEPIE_LOCATOR_NONE
987 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
988 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
989 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
990 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
991 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
992 * @see SIMPLEPIE_LOCATOR_ALL
993 * @param int $level Feed Autodiscovery Level (level can be a
994 * combination of the above constants, see bitwise OR operator)
996 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
998 $this->autodiscovery = (int) $level;
1002 * Allows you to change which class SimplePie uses for caching.
1003 * Useful when you are overloading or extending SimplePie's default classes.
1006 * @param string $class Name of custom class.
1007 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1008 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1010 function set_cache_class($class = 'SimplePie_Cache')
1012 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1014 $this->cache_class = $class;
1021 * Allows you to change which class SimplePie uses for auto-discovery.
1022 * Useful when you are overloading or extending SimplePie's default classes.
1025 * @param string $class Name of custom class.
1026 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1027 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1029 function set_locator_class($class = 'SimplePie_Locator')
1031 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1033 $this->locator_class = $class;
1040 * Allows you to change which class SimplePie uses for XML parsing.
1041 * Useful when you are overloading or extending SimplePie's default classes.
1044 * @param string $class Name of custom class.
1045 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1046 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1048 function set_parser_class($class = 'SimplePie_Parser')
1050 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1052 $this->parser_class = $class;
1059 * Allows you to change which class SimplePie uses for remote file fetching.
1060 * Useful when you are overloading or extending SimplePie's default classes.
1063 * @param string $class Name of custom class.
1064 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1065 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1067 function set_file_class($class = 'SimplePie_File')
1069 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1071 $this->file_class = $class;
1078 * Allows you to change which class SimplePie uses for data sanitization.
1079 * Useful when you are overloading or extending SimplePie's default classes.
1082 * @param string $class Name of custom class.
1083 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1084 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1086 function set_sanitize_class($class = 'SimplePie_Sanitize')
1088 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1090 $this->sanitize =& new $class;
1097 * Allows you to change which class SimplePie uses for handling feed items.
1098 * Useful when you are overloading or extending SimplePie's default classes.
1101 * @param string $class Name of custom class.
1102 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1103 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1105 function set_item_class($class = 'SimplePie_Item')
1107 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1109 $this->item_class = $class;
1116 * Allows you to change which class SimplePie uses for handling author data.
1117 * Useful when you are overloading or extending SimplePie's default classes.
1120 * @param string $class Name of custom class.
1121 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1122 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1124 function set_author_class($class = 'SimplePie_Author')
1126 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1128 $this->author_class = $class;
1135 * Allows you to change which class SimplePie uses for handling category data.
1136 * Useful when you are overloading or extending SimplePie's default classes.
1139 * @param string $class Name of custom class.
1140 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1141 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1143 function set_category_class($class = 'SimplePie_Category')
1145 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1147 $this->category_class = $class;
1154 * Allows you to change which class SimplePie uses for feed enclosures.
1155 * Useful when you are overloading or extending SimplePie's default classes.
1158 * @param string $class Name of custom class.
1159 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1160 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1162 function set_enclosure_class($class = 'SimplePie_Enclosure')
1164 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1166 $this->enclosure_class = $class;
1173 * Allows you to change which class SimplePie uses for <media:text> captions
1174 * Useful when you are overloading or extending SimplePie's default classes.
1177 * @param string $class Name of custom class.
1178 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1179 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1181 function set_caption_class($class = 'SimplePie_Caption')
1183 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1185 $this->caption_class = $class;
1192 * Allows you to change which class SimplePie uses for <media:copyright>
1193 * Useful when you are overloading or extending SimplePie's default classes.
1196 * @param string $class Name of custom class.
1197 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1198 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1200 function set_copyright_class($class = 'SimplePie_Copyright')
1202 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1204 $this->copyright_class = $class;
1211 * Allows you to change which class SimplePie uses for <media:credit>
1212 * Useful when you are overloading or extending SimplePie's default classes.
1215 * @param string $class Name of custom class.
1216 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1217 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1219 function set_credit_class($class = 'SimplePie_Credit')
1221 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1223 $this->credit_class = $class;
1230 * Allows you to change which class SimplePie uses for <media:rating>
1231 * Useful when you are overloading or extending SimplePie's default classes.
1234 * @param string $class Name of custom class.
1235 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1236 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1238 function set_rating_class($class = 'SimplePie_Rating')
1240 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1242 $this->rating_class = $class;
1249 * Allows you to change which class SimplePie uses for <media:restriction>
1250 * Useful when you are overloading or extending SimplePie's default classes.
1253 * @param string $class Name of custom class.
1254 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1255 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1257 function set_restriction_class($class = 'SimplePie_Restriction')
1259 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1261 $this->restriction_class = $class;
1268 * Allows you to change which class SimplePie uses for content-type sniffing.
1269 * Useful when you are overloading or extending SimplePie's default classes.
1272 * @param string $class Name of custom class.
1273 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1274 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1276 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1278 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1280 $this->content_type_sniffer_class = $class;
1287 * Allows you to change which class SimplePie uses item sources.
1288 * Useful when you are overloading or extending SimplePie's default classes.
1291 * @param string $class Name of custom class.
1292 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1293 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1295 function set_source_class($class = 'SimplePie_Source')
1297 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1299 $this->source_class = $class;
1306 * Allows you to override the default user agent string.
1309 * @param string $ua New user agent string.
1311 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1313 $this->useragent = (string) $ua;
1317 * Set callback function to create cache filename with
1320 * @param mixed $function Callback function
1322 function set_cache_name_function($function = 'md5')
1324 if (is_callable($function))
1326 $this->cache_name_function = $function;
1331 * Set javascript query string parameter
1334 * @param mixed $get Javascript query string parameter
1336 function set_javascript($get = 'js')
1340 $this->javascript = (string) $get;
1344 $this->javascript = false;
1349 * Set options to make SP as fast as possible. Forgoes a
1350 * substantial amount of data sanitization in favor of speed.
1353 * @param bool $set Whether to set them or not
1355 function set_stupidly_fast($set = false)
1359 $this->enable_order_by_date(false);
1360 $this->remove_div(false);
1361 $this->strip_comments(false);
1362 $this->strip_htmltags(false);
1363 $this->strip_attributes(false);
1364 $this->set_image_handler(false);
1369 * Set maximum number of feeds to check with autodiscovery
1372 * @param int $max Maximum number of feeds to check
1374 function set_max_checked_feeds($max = 10)
1376 $this->max_checked_feeds = (int) $max;
1379 function remove_div($enable = true)
1381 $this->sanitize->remove_div($enable);
1384 function strip_htmltags($tags = '', $encode = null)
1388 $tags = $this->strip_htmltags;
1390 $this->sanitize->strip_htmltags($tags);
1391 if ($encode !== null)
1393 $this->sanitize->encode_instead_of_strip($tags);
1397 function encode_instead_of_strip($enable = true)
1399 $this->sanitize->encode_instead_of_strip($enable);
1402 function strip_attributes($attribs = '')
1404 if ($attribs === '')
1406 $attribs = $this->strip_attributes;
1408 $this->sanitize->strip_attributes($attribs);
1411 function set_output_encoding($encoding = 'UTF-8')
1413 $this->sanitize->set_output_encoding($encoding);
1416 function strip_comments($strip = false)
1418 $this->sanitize->strip_comments($strip);
1422 * Set element/attribute key/value pairs of HTML attributes
1423 * containing URLs that need to be resolved relative to the feed
1427 * @param array $element_attribute Element/attribute key/value pairs
1429 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'))
1431 $this->sanitize->set_url_replacements($element_attribute);
1435 * Set the handler to enable the display of cached favicons.
1438 * @param str $page Web-accessible path to the handler_favicon.php file.
1439 * @param str $qs The query string that the value should be passed to.
1441 function set_favicon_handler($page = false, $qs = 'i')
1445 $this->favicon_handler = $page . '?' . $qs . '=';
1449 $this->favicon_handler = '';
1454 * Set the handler to enable the display of cached images.
1457 * @param str $page Web-accessible path to the handler_image.php file.
1458 * @param str $qs The query string that the value should be passed to.
1460 function set_image_handler($page = false, $qs = 'i')
1464 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1468 $this->image_handler = '';
1473 * Set the limit for items returned per-feed with multifeeds.
1476 * @param integer $limit The maximum number of items to return.
1478 function set_item_limit($limit = 0)
1480 $this->item_limit = (int) $limit;
1485 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1489 if (isset($_GET[$this->javascript]))
1491 if (function_exists('ob_gzhandler'))
1493 ob_start('ob_gzhandler');
1495 header('Content-type: text/javascript; charset: UTF-8');
1496 header('Cache-Control: must-revalidate');
1497 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1499 function embed_odeo(link) {
1500 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>');
1503 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1504 if (placeholder != '') {
1505 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>');
1508 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>');
1512 function embed_flash(bgcolor, width, height, link, loop, type) {
1513 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>');
1516 function embed_flv(width, height, link, placeholder, loop, player) {
1517 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>');
1520 function embed_wmedia(width, height, link) {
1521 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1527 // Pass whatever was set with config options over to the sanitizer.
1528 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1529 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1531 if ($this->feed_url !== null || $this->raw_data !== null)
1533 $this->data = array();
1534 $this->multifeed_objects = array();
1537 if ($this->feed_url !== null)
1539 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1540 // Decide whether to enable caching
1541 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1543 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1545 // If it's enabled and we don't want an XML dump, use the cache
1546 if ($cache && !$this->xml_dump)
1549 $this->data = $cache->load();
1550 if (!empty($this->data))
1552 // If the cache is for an outdated build of SimplePie
1553 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1556 $this->data = array();
1558 // If we've hit a collision just rerun it with caching disabled
1559 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1562 $this->data = array();
1564 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1565 elseif (isset($this->data['feed_url']))
1567 // If the autodiscovery cache is still valid use it.
1568 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1570 // Do not need to do feed autodiscovery yet.
1571 if ($this->data['feed_url'] == $this->data['url'])
1574 $this->data = array();
1578 $this->set_feed_url($this->data['feed_url']);
1579 return $this->init();
1583 // Check if the cache has been updated
1584 elseif ($cache->mtime() + $this->cache_duration < time())
1586 // If we have last-modified and/or etag set
1587 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1590 if (isset($this->data['headers']['last-modified']))
1592 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1594 if (isset($this->data['headers']['etag']))
1596 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1598 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1601 if ($file->status_code == 304)
1608 $headers = $file->headers;
1617 // If the cache is still valid, just return true
1623 // If the cache is empty, delete it
1627 $this->data = array();
1630 // 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.
1633 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1635 $file =& $this->file;
1639 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1642 // If the file connection has an error, set SimplePie::error to that and quit
1643 if (!$file->success)
1645 $this->error = $file->error;
1646 if (!empty($this->data))
1656 if (!$this->force_feed)
1658 // Check if the supplied URL is a feed, if it isn't, look for it.
1659 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1660 if (!$locate->is_feed($file))
1662 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1664 if ($file = $locate->find($this->autodiscovery))
1668 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1669 if (!$cache->save($this))
1671 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1673 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1675 $this->feed_url = $file->url;
1679 $this->error = "A feed could not be found at $this->feed_url";
1680 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1687 $headers = $file->headers;
1688 $data = $file->body;
1689 $sniffer =& new $this->content_type_sniffer_class($file);
1690 $sniffed = $sniffer->get_type();
1694 $data = $this->raw_data;
1697 // Set up array of possible encodings
1698 $encodings = array();
1700 // First check to see if input has been overridden.
1701 if ($this->input_encoding !== false)
1703 $encodings[] = $this->input_encoding;
1706 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1707 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1709 // RFC 3023 (only applies to sniffed content)
1710 if (isset($sniffed))
1712 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1714 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1716 $encodings[] = strtoupper($charset[1]);
1718 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1719 $encodings[] = 'UTF-8';
1721 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1723 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1725 $encodings[] = $charset[1];
1727 $encodings[] = 'US-ASCII';
1729 // Text MIME-type default
1730 elseif (substr($sniffed, 0, 5) === 'text/')
1732 $encodings[] = 'US-ASCII';
1736 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1737 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1738 $encodings[] = 'UTF-8';
1739 $encodings[] = 'ISO-8859-1';
1741 // There's no point in trying an encoding twice
1742 $encodings = array_unique($encodings);
1744 // If we want the XML, just output that with the most likely encoding and quit
1745 if ($this->xml_dump)
1747 header('Content-type: text/xml; charset=' . $encodings[0]);
1752 // Loop through each possible encoding, till we return something, or run out of possibilities
1753 foreach ($encodings as $encoding)
1755 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1756 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1758 // Create new parser
1759 $parser =& new $this->parser_class();
1761 // If it's parsed fine
1762 if ($parser->parse($utf8_data, 'UTF-8'))
1764 $this->data = $parser->get_data();
1765 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1767 if (isset($headers))
1769 $this->data['headers'] = $headers;
1771 $this->data['build'] = SIMPLEPIE_BUILD;
1773 // Cache the file if caching is enabled
1774 if ($cache && !$cache->save($this))
1776 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1782 $this->error = "A feed could not be found at $this->feed_url";
1783 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1789 // We have an error, just set SimplePie::error to it and quit
1790 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1791 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1794 elseif (!empty($this->multifeed_url))
1798 $this->multifeed_objects = array();
1799 foreach ($this->multifeed_url as $url)
1803 // This keyword needs to defy coding standards for PHP4 compatibility
1804 $this->multifeed_objects[$i] = clone($this);
1808 $this->multifeed_objects[$i] = $this;
1810 $this->multifeed_objects[$i]->set_feed_url($url);
1811 $success |= $this->multifeed_objects[$i]->init();
1814 return (bool) $success;
1823 * Return the error message for the occured error
1826 * @return string Error message
1830 return $this->error;
1833 function get_encoding()
1835 return $this->sanitize->output_encoding;
1838 function handle_content_type($mime = 'text/html')
1840 if (!headers_sent())
1842 $header = "Content-type: $mime;";
1843 if ($this->get_encoding())
1845 $header .= ' charset=' . $this->get_encoding();
1849 $header .= ' charset=UTF-8';
1857 if (!isset($this->data['type']))
1859 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1860 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1862 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1864 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1866 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1868 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1870 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1871 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1872 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1873 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1875 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1877 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1878 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1879 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1880 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1882 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1885 elseif (isset($this->data['child']['']['rss']))
1887 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1888 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1890 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1893 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1894 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1896 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1899 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1918 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1922 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1929 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1932 return $this->data['type'];
1936 * Returns the URL for the favicon of the feed's website.
1938 * @todo Cache atom:icon
1942 function get_favicon()
1944 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1946 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1948 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1950 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1952 if ($this->cache && $this->favicon_handler)
1954 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1955 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1959 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1963 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1965 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1967 $sniffer =& new $this->content_type_sniffer_class($file);
1968 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1970 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1972 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1976 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1977 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1985 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1992 * @todo If we have a perm redirect we should return the new URL
1993 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1994 * @todo Also, |atom:link|@rel=self
1996 function subscribe_url()
1998 if ($this->feed_url !== null)
2000 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2008 function subscribe_feed()
2010 if ($this->feed_url !== null)
2012 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2020 function subscribe_outlook()
2022 if ($this->feed_url !== null)
2024 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2032 function subscribe_podcast()
2034 if ($this->feed_url !== null)
2036 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2044 function subscribe_itunes()
2046 if ($this->feed_url !== null)
2048 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2057 * Creates the subscribe_* methods' return data
2060 * @param string $feed_url String to prefix to the feed URL
2061 * @param string $site_url String to prefix to the site URL (and
2062 * suffix to the feed URL)
2063 * @return mixed URL if feed exists, false otherwise
2065 function subscribe_service($feed_url, $site_url = null)
2067 if ($this->subscribe_url())
2069 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2070 if ($site_url !== null && $this->get_link() !== null)
2072 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2082 function subscribe_aol()
2084 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2087 function subscribe_bloglines()
2089 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2092 function subscribe_eskobo()
2094 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2097 function subscribe_feedfeeds()
2099 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2102 function subscribe_feedster()
2104 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2107 function subscribe_google()
2109 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2112 function subscribe_gritwire()
2114 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2117 function subscribe_msn()
2119 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2122 function subscribe_netvibes()
2124 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2127 function subscribe_newsburst()
2129 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2132 function subscribe_newsgator()
2134 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2137 function subscribe_odeo()
2139 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2142 function subscribe_podnova()
2144 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2147 function subscribe_rojo()
2149 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2152 function subscribe_yahoo()
2154 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2157 function get_feed_tags($namespace, $tag)
2159 $type = $this->get_type();
2160 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2162 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2164 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2167 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2169 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2171 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2174 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2176 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2178 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2181 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2183 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2185 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2191 function get_channel_tags($namespace, $tag)
2193 $type = $this->get_type();
2194 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2196 if ($return = $this->get_feed_tags($namespace, $tag))
2201 if ($type & SIMPLEPIE_TYPE_RSS_10)
2203 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2205 if (isset($channel[0]['child'][$namespace][$tag]))
2207 return $channel[0]['child'][$namespace][$tag];
2211 if ($type & SIMPLEPIE_TYPE_RSS_090)
2213 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2215 if (isset($channel[0]['child'][$namespace][$tag]))
2217 return $channel[0]['child'][$namespace][$tag];
2221 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2223 if ($channel = $this->get_feed_tags('', 'channel'))
2225 if (isset($channel[0]['child'][$namespace][$tag]))
2227 return $channel[0]['child'][$namespace][$tag];
2234 function get_image_tags($namespace, $tag)
2236 $type = $this->get_type();
2237 if ($type & SIMPLEPIE_TYPE_RSS_10)
2239 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2241 if (isset($image[0]['child'][$namespace][$tag]))
2243 return $image[0]['child'][$namespace][$tag];
2247 if ($type & SIMPLEPIE_TYPE_RSS_090)
2249 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2251 if (isset($image[0]['child'][$namespace][$tag]))
2253 return $image[0]['child'][$namespace][$tag];
2257 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2259 if ($image = $this->get_channel_tags('', 'image'))
2261 if (isset($image[0]['child'][$namespace][$tag]))
2263 return $image[0]['child'][$namespace][$tag];
2270 function get_base($element = array())
2272 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2274 return $element['xml_base'];
2276 elseif ($this->get_link() !== null)
2278 return $this->get_link();
2282 return $this->subscribe_url();
2286 function sanitize($data, $type, $base = '')
2288 return $this->sanitize->sanitize($data, $type, $base);
2291 function get_title()
2293 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2295 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2297 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2299 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2301 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2303 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2307 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2309 elseif ($return = $this->get_channel_tags('', 'title'))
2311 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2313 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2315 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2317 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2319 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2327 function get_category($key = 0)
2329 $categories = $this->get_categories();
2330 if (isset($categories[$key]))
2332 return $categories[$key];
2340 function get_categories()
2342 $categories = array();
2344 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2349 if (isset($category['attribs']['']['term']))
2351 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2353 if (isset($category['attribs']['']['scheme']))
2355 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2357 if (isset($category['attribs']['']['label']))
2359 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2361 $categories[] =& new $this->category_class($term, $scheme, $label);
2363 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2365 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2367 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2369 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2371 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2373 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2376 if (!empty($categories))
2378 return SimplePie_Misc::array_unique($categories);
2386 function get_author($key = 0)
2388 $authors = $this->get_authors();
2389 if (isset($authors[$key]))
2391 return $authors[$key];
2399 function get_authors()
2402 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2407 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2409 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2411 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2413 $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]));
2415 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2417 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2419 if ($name !== null || $email !== null || $uri !== null)
2421 $authors[] =& new $this->author_class($name, $uri, $email);
2424 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2429 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2431 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2433 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2435 $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]));
2437 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2439 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2441 if ($name !== null || $email !== null || $url !== null)
2443 $authors[] =& new $this->author_class($name, $url, $email);
2446 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2448 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2450 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2452 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2454 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2456 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2459 if (!empty($authors))
2461 return SimplePie_Misc::array_unique($authors);
2469 function get_contributor($key = 0)
2471 $contributors = $this->get_contributors();
2472 if (isset($contributors[$key]))
2474 return $contributors[$key];
2482 function get_contributors()
2484 $contributors = array();
2485 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2490 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2492 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2494 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2496 $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]));
2498 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2500 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2502 if ($name !== null || $email !== null || $uri !== null)
2504 $contributors[] =& new $this->author_class($name, $uri, $email);
2507 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2512 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2514 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2516 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2518 $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]));
2520 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2522 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2524 if ($name !== null || $email !== null || $url !== null)
2526 $contributors[] =& new $this->author_class($name, $url, $email);
2530 if (!empty($contributors))
2532 return SimplePie_Misc::array_unique($contributors);
2540 function get_link($key = 0, $rel = 'alternate')
2542 $links = $this->get_links($rel);
2543 if (isset($links[$key]))
2545 return $links[$key];
2554 * Added for parity between the parent-level and the item/entry-level.
2556 function get_permalink()
2558 return $this->get_link(0);
2561 function get_links($rel = 'alternate')
2563 if (!isset($this->data['links']))
2565 $this->data['links'] = array();
2566 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2568 foreach ($links as $link)
2570 if (isset($link['attribs']['']['href']))
2572 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2573 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2577 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2579 foreach ($links as $link)
2581 if (isset($link['attribs']['']['href']))
2583 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2584 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2589 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2591 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2593 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2595 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2597 if ($links = $this->get_channel_tags('', 'link'))
2599 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2602 $keys = array_keys($this->data['links']);
2603 foreach ($keys as $key)
2605 if (SimplePie_Misc::is_isegment_nz_nc($key))
2607 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2609 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2610 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2614 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2617 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2619 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2621 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2625 if (isset($this->data['links'][$rel]))
2627 return $this->data['links'][$rel];
2635 function get_description()
2637 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2639 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2641 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2643 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2645 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2647 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2651 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2653 elseif ($return = $this->get_channel_tags('', 'description'))
2655 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2657 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2659 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2661 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2663 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2665 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2667 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2669 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2671 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2679 function get_copyright()
2681 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2683 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2685 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2687 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2689 elseif ($return = $this->get_channel_tags('', 'copyright'))
2691 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2693 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2695 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2697 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2699 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2707 function get_language()
2709 if ($return = $this->get_channel_tags('', 'language'))
2711 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2715 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2719 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2721 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2723 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2727 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2729 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2731 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2733 elseif (isset($this->data['headers']['content-language']))
2735 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2743 function get_latitude()
2745 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2747 return (float) $return[0]['data'];
2749 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2751 return (float) $match[1];
2759 function get_longitude()
2761 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2763 return (float) $return[0]['data'];
2765 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2767 return (float) $return[0]['data'];
2769 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2771 return (float) $match[2];
2779 function get_image_title()
2781 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2783 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2787 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789 elseif ($return = $this->get_image_tags('', 'title'))
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2793 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2795 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2797 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2799 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2807 function get_image_url()
2809 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2811 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2813 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2815 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2819 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2823 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2825 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2827 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2829 elseif ($return = $this->get_image_tags('', 'url'))
2831 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2839 function get_image_link()
2841 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2845 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2847 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2849 elseif ($return = $this->get_image_tags('', 'link'))
2851 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859 function get_image_width()
2861 if ($return = $this->get_image_tags('', 'width'))
2863 return round($return[0]['data']);
2865 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2875 function get_image_height()
2877 if ($return = $this->get_image_tags('', 'height'))
2879 return round($return[0]['data']);
2881 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2891 function get_item_quantity($max = 0)
2893 $qty = count($this->get_items());
2900 return ($qty > $max) ? $max : $qty;
2904 function get_item($key = 0)
2906 $items = $this->get_items();
2907 if (isset($items[$key]))
2909 return $items[$key];
2917 function get_items($start = 0, $end = 0)
2919 if (!empty($this->multifeed_objects))
2921 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2923 elseif (!isset($this->data['items']))
2925 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2927 $keys = array_keys($items);
2928 foreach ($keys as $key)
2930 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2933 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2935 $keys = array_keys($items);
2936 foreach ($keys as $key)
2938 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2941 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2943 $keys = array_keys($items);
2944 foreach ($keys as $key)
2946 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2949 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2951 $keys = array_keys($items);
2952 foreach ($keys as $key)
2954 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2957 if ($items = $this->get_channel_tags('', 'item'))
2959 $keys = array_keys($items);
2960 foreach ($keys as $key)
2962 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2967 if (!empty($this->data['items']))
2969 // If we want to order it by date, check if all items have a date, and then sort it
2970 if ($this->order_by_date)
2972 if (!isset($this->data['ordered_items']))
2975 foreach ($this->data['items'] as $item)
2977 if (!$item->get_date('U'))
2984 $this->data['ordered_items'] = $this->data['items'];
2987 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2990 $items = $this->data['ordered_items'];
2994 $items = $this->data['items'];
2997 // Slice the data as desired
3000 return array_slice($items, $start);
3004 return array_slice($items, $start, $end);
3013 function sort_items($a, $b)
3015 return $a->get_date('U') <= $b->get_date('U');
3018 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3020 if (is_array($urls) && sizeof($urls) > 0)
3023 foreach ($urls as $arg)
3025 if (is_a($arg, 'SimplePie'))
3027 $items = array_merge($items, $arg->get_items(0, $limit));
3031 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3036 foreach ($items as $item)
3038 if (!$item->get_date('U'))
3047 usort($items, array('SimplePie', 'sort_items'));
3052 return array_slice($items, $start);
3056 return array_slice($items, $start, $end);
3061 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3067 class SimplePie_Item
3070 var $data = array();
3072 function SimplePie_Item($feed, $data)
3074 $this->feed = $feed;
3075 $this->data = $data;
3078 function __toString()
3080 return md5(serialize($this->data));
3084 * Remove items that link back to this before destroying this object
3086 function __destruct()
3088 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3094 function get_item_tags($namespace, $tag)
3096 if (isset($this->data['child'][$namespace][$tag]))
3098 return $this->data['child'][$namespace][$tag];
3106 function get_base($element = array())
3108 return $this->feed->get_base($element);
3111 function sanitize($data, $type, $base = '')
3113 return $this->feed->sanitize($data, $type, $base);
3121 function get_id($hash = false)
3125 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3127 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3129 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3131 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3133 elseif ($return = $this->get_item_tags('', 'guid'))
3135 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3137 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3139 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3141 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3143 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3145 elseif (($return = $this->get_permalink()) !== null)
3149 elseif (($return = $this->get_title()) !== null)
3154 if ($this->get_permalink() !== null || $this->get_title() !== null)
3156 return md5($this->get_permalink() . $this->get_title());
3160 return md5(serialize($this->data));
3164 function get_title()
3166 if (!isset($this->data['title']))
3168 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3170 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3172 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3174 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3176 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3178 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3180 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3182 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3184 elseif ($return = $this->get_item_tags('', 'title'))
3186 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3188 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3190 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3192 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3194 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3198 $this->data['title'] = null;
3201 return $this->data['title'];
3204 function get_description($description_only = false)
3206 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3208 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3210 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3212 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3214 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3216 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3218 elseif ($return = $this->get_item_tags('', 'description'))
3220 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3222 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3224 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3226 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3228 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3232 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3236 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3238 elseif (!$description_only)
3240 return $this->get_content(true);
3248 function get_content($content_only = false)
3250 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3252 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3254 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3256 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3258 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3260 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3262 elseif (!$content_only)
3264 return $this->get_description(true);
3272 function get_category($key = 0)
3274 $categories = $this->get_categories();
3275 if (isset($categories[$key]))
3277 return $categories[$key];
3285 function get_categories()
3287 $categories = array();
3289 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3294 if (isset($category['attribs']['']['term']))
3296 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3298 if (isset($category['attribs']['']['scheme']))
3300 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3302 if (isset($category['attribs']['']['label']))
3304 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3306 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3308 foreach ((array) $this->get_item_tags('', 'category') as $category)
3310 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3312 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3314 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3316 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3318 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3321 if (!empty($categories))
3323 return SimplePie_Misc::array_unique($categories);
3331 function get_author($key = 0)
3333 $authors = $this->get_authors();
3334 if (isset($authors[$key]))
3336 return $authors[$key];
3344 function get_contributor($key = 0)
3346 $contributors = $this->get_contributors();
3347 if (isset($contributors[$key]))
3349 return $contributors[$key];
3357 function get_contributors()
3359 $contributors = array();
3360 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3365 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3367 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3369 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3371 $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]));
3373 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3375 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3377 if ($name !== null || $email !== null || $uri !== null)
3379 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3382 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3387 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3389 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3391 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3393 $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]));
3395 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3397 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3399 if ($name !== null || $email !== null || $url !== null)
3401 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3405 if (!empty($contributors))
3407 return SimplePie_Misc::array_unique($contributors);
3416 * @todo Atom inheritance (item author, source author, feed author)
3418 function get_authors()
3421 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3426 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3428 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3430 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3432 $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]));
3434 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3436 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3438 if ($name !== null || $email !== null || $uri !== null)
3440 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3443 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3448 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3450 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3452 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3454 $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]));
3456 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3458 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3460 if ($name !== null || $email !== null || $url !== null)
3462 $authors[] =& new $this->feed->author_class($name, $url, $email);
3465 if ($author = $this->get_item_tags('', 'author'))
3467 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3469 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3471 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3473 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3475 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3477 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3479 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3482 if (!empty($authors))
3484 return SimplePie_Misc::array_unique($authors);
3486 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3490 elseif ($authors = $this->feed->get_authors())
3500 function get_copyright()
3502 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3504 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3506 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3508 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3510 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3512 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3520 function get_date($date_format = 'j F Y, g:i a')
3522 if (!isset($this->data['date']))
3524 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3526 $this->data['date']['raw'] = $return[0]['data'];
3528 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3530 $this->data['date']['raw'] = $return[0]['data'];
3532 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3534 $this->data['date']['raw'] = $return[0]['data'];
3536 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3538 $this->data['date']['raw'] = $return[0]['data'];
3540 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3542 $this->data['date']['raw'] = $return[0]['data'];
3544 elseif ($return = $this->get_item_tags('', 'pubDate'))
3546 $this->data['date']['raw'] = $return[0]['data'];
3548 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3550 $this->data['date']['raw'] = $return[0]['data'];
3552 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3554 $this->data['date']['raw'] = $return[0]['data'];
3557 if (!empty($this->data['date']['raw']))
3559 $parser = SimplePie_Parse_Date::get();
3560 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3564 $this->data['date'] = null;
3567 if ($this->data['date'])
3569 $date_format = (string) $date_format;
3570 switch ($date_format)
3573 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3576 return $this->data['date']['parsed'];
3579 return date($date_format, $this->data['date']['parsed']);
3588 function get_local_date($date_format = '%c')
3592 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3594 elseif (($date = $this->get_date('U')) !== null)
3596 return strftime($date_format, $date);
3604 function get_permalink()
3606 $link = $this->get_link();
3607 $enclosure = $this->get_enclosure(0);
3612 elseif ($enclosure !== null)
3614 return $enclosure->get_link();
3622 function get_link($key = 0, $rel = 'alternate')
3624 $links = $this->get_links($rel);
3625 if ($links[$key] !== null)
3627 return $links[$key];
3635 function get_links($rel = 'alternate')
3637 if (!isset($this->data['links']))
3639 $this->data['links'] = array();
3640 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3642 if (isset($link['attribs']['']['href']))
3644 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3645 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3649 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3651 if (isset($link['attribs']['']['href']))
3653 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3654 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3657 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3659 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3661 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3663 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3665 if ($links = $this->get_item_tags('', 'link'))
3667 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3669 if ($links = $this->get_item_tags('', 'guid'))
3671 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3673 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3677 $keys = array_keys($this->data['links']);
3678 foreach ($keys as $key)
3680 if (SimplePie_Misc::is_isegment_nz_nc($key))
3682 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3684 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3685 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3689 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3692 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3694 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3696 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3699 if (isset($this->data['links'][$rel]))
3701 return $this->data['links'][$rel];
3710 * @todo Add ability to prefer one type of content over another (in a media group).
3712 function get_enclosure($key = 0, $prefer = null)
3714 $enclosures = $this->get_enclosures();
3715 if (isset($enclosures[$key]))
3717 return $enclosures[$key];
3726 * Grabs all available enclosures (podcasts, etc.)
3728 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3730 * 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.
3732 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3733 * @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).
3735 function get_enclosures()
3737 if (!isset($this->data['enclosures']))
3739 $this->data['enclosures'] = array();
3742 $captions_parent = null;
3743 $categories_parent = null;
3744 $copyrights_parent = null;
3745 $credits_parent = null;
3746 $description_parent = null;
3747 $duration_parent = null;
3748 $hashes_parent = null;
3749 $keywords_parent = null;
3750 $player_parent = null;
3751 $ratings_parent = null;
3752 $restrictions_parent = null;
3753 $thumbnails_parent = null;
3754 $title_parent = null;
3756 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3757 $parent = $this->get_feed();
3760 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3762 foreach ($captions as $caption)
3764 $caption_type = null;
3765 $caption_lang = null;
3766 $caption_startTime = null;
3767 $caption_endTime = null;
3768 $caption_text = null;
3769 if (isset($caption['attribs']['']['type']))
3771 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3773 if (isset($caption['attribs']['']['lang']))
3775 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3777 if (isset($caption['attribs']['']['start']))
3779 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3781 if (isset($caption['attribs']['']['end']))
3783 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3785 if (isset($caption['data']))
3787 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3789 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3792 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3794 foreach ($captions as $caption)
3796 $caption_type = null;
3797 $caption_lang = null;
3798 $caption_startTime = null;
3799 $caption_endTime = null;
3800 $caption_text = null;
3801 if (isset($caption['attribs']['']['type']))
3803 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3805 if (isset($caption['attribs']['']['lang']))
3807 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3809 if (isset($caption['attribs']['']['start']))
3811 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3813 if (isset($caption['attribs']['']['end']))
3815 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3817 if (isset($caption['data']))
3819 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3821 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3824 if (is_array($captions_parent))
3826 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3830 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3835 if (isset($category['data']))
3837 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3839 if (isset($category['attribs']['']['scheme']))
3841 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3845 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3847 if (isset($category['attribs']['']['label']))
3849 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3851 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3853 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3858 if (isset($category['data']))
3860 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3862 if (isset($category['attribs']['']['scheme']))
3864 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3868 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3870 if (isset($category['attribs']['']['label']))
3872 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3874 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3876 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3879 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3881 if (isset($category['attribs']['']['text']))
3883 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3885 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3887 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3889 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3891 if (isset($subcategory['attribs']['']['text']))
3893 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3895 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3899 if (is_array($categories_parent))
3901 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3905 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3907 $copyright_url = null;
3908 $copyright_label = null;
3909 if (isset($copyright[0]['attribs']['']['url']))
3911 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3913 if (isset($copyright[0]['data']))
3915 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3917 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3919 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3921 $copyright_url = null;
3922 $copyright_label = null;
3923 if (isset($copyright[0]['attribs']['']['url']))
3925 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3927 if (isset($copyright[0]['data']))
3929 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3931 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3935 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3937 foreach ($credits as $credit)
3939 $credit_role = null;
3940 $credit_scheme = null;
3941 $credit_name = null;
3942 if (isset($credit['attribs']['']['role']))
3944 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3946 if (isset($credit['attribs']['']['scheme']))
3948 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3952 $credit_scheme = 'urn:ebu';
3954 if (isset($credit['data']))
3956 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3958 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3961 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3963 foreach ($credits as $credit)
3965 $credit_role = null;
3966 $credit_scheme = null;
3967 $credit_name = null;
3968 if (isset($credit['attribs']['']['role']))
3970 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 if (isset($credit['attribs']['']['scheme']))
3974 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3978 $credit_scheme = 'urn:ebu';
3980 if (isset($credit['data']))
3982 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3984 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3987 if (is_array($credits_parent))
3989 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3993 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3995 if (isset($description_parent[0]['data']))
3997 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4000 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4002 if (isset($description_parent[0]['data']))
4004 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4009 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4014 if (isset($duration_parent[0]['data']))
4016 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4017 if (sizeof($temp) > 0)
4019 (int) $seconds = array_pop($temp);
4021 if (sizeof($temp) > 0)
4023 (int) $minutes = array_pop($temp);
4024 $seconds += $minutes * 60;
4026 if (sizeof($temp) > 0)
4028 (int) $hours = array_pop($temp);
4029 $seconds += $hours * 3600;
4032 $duration_parent = $seconds;
4037 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4039 foreach ($hashes_iterator as $hash)
4043 if (isset($hash['data']))
4045 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4047 if (isset($hash['attribs']['']['algo']))
4049 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4055 $hashes_parent[] = $algo.':'.$value;
4058 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4060 foreach ($hashes_iterator as $hash)
4064 if (isset($hash['data']))
4066 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4068 if (isset($hash['attribs']['']['algo']))
4070 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4076 $hashes_parent[] = $algo.':'.$value;
4079 if (is_array($hashes_parent))
4081 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4085 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4087 if (isset($keywords[0]['data']))
4089 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4090 foreach ($temp as $word)
4092 $keywords_parent[] = trim($word);
4097 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4099 if (isset($keywords[0]['data']))
4101 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4102 foreach ($temp as $word)
4104 $keywords_parent[] = trim($word);
4109 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4111 if (isset($keywords[0]['data']))
4113 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4114 foreach ($temp as $word)
4116 $keywords_parent[] = trim($word);
4121 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4123 if (isset($keywords[0]['data']))
4125 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4126 foreach ($temp as $word)
4128 $keywords_parent[] = trim($word);
4133 if (is_array($keywords_parent))
4135 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4139 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4141 if (isset($player_parent[0]['attribs']['']['url']))
4143 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4146 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4148 if (isset($player_parent[0]['attribs']['']['url']))
4150 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4155 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4157 foreach ($ratings as $rating)
4159 $rating_scheme = null;
4160 $rating_value = null;
4161 if (isset($rating['attribs']['']['scheme']))
4163 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4167 $rating_scheme = 'urn:simple';
4169 if (isset($rating['data']))
4171 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4173 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4176 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4178 foreach ($ratings as $rating)
4180 $rating_scheme = 'urn:itunes';
4181 $rating_value = null;
4182 if (isset($rating['data']))
4184 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4186 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4189 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4191 foreach ($ratings as $rating)
4193 $rating_scheme = null;
4194 $rating_value = null;
4195 if (isset($rating['attribs']['']['scheme']))
4197 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4201 $rating_scheme = 'urn:simple';
4203 if (isset($rating['data']))
4205 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4207 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4210 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4212 foreach ($ratings as $rating)
4214 $rating_scheme = 'urn:itunes';
4215 $rating_value = null;
4216 if (isset($rating['data']))
4218 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4220 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4223 if (is_array($ratings_parent))
4225 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4229 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4231 foreach ($restrictions as $restriction)
4233 $restriction_relationship = null;
4234 $restriction_type = null;
4235 $restriction_value = null;
4236 if (isset($restriction['attribs']['']['relationship']))
4238 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4240 if (isset($restriction['attribs']['']['type']))
4242 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4244 if (isset($restriction['data']))
4246 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4248 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4251 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4253 foreach ($restrictions as $restriction)
4255 $restriction_relationship = 'allow';
4256 $restriction_type = null;
4257 $restriction_value = 'itunes';
4258 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4260 $restriction_relationship = 'deny';
4262 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4265 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4267 foreach ($restrictions as $restriction)
4269 $restriction_relationship = null;
4270 $restriction_type = null;
4271 $restriction_value = null;
4272 if (isset($restriction['attribs']['']['relationship']))
4274 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4276 if (isset($restriction['attribs']['']['type']))
4278 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4280 if (isset($restriction['data']))
4282 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4284 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4287 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4289 foreach ($restrictions as $restriction)
4291 $restriction_relationship = 'allow';
4292 $restriction_type = null;
4293 $restriction_value = 'itunes';
4294 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4296 $restriction_relationship = 'deny';
4298 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4301 if (is_array($restrictions_parent))
4303 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4307 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4309 foreach ($thumbnails as $thumbnail)
4311 if (isset($thumbnail['attribs']['']['url']))
4313 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4317 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4319 foreach ($thumbnails as $thumbnail)
4321 if (isset($thumbnail['attribs']['']['url']))
4323 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4329 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4331 if (isset($title_parent[0]['data']))
4333 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4336 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4338 if (isset($title_parent[0]['data']))
4340 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4358 $samplingrate = null;
4368 $description = null;
4373 $restrictions = null;
4377 // If we have media:group tags, loop through them.
4378 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4380 // If we have media:content tags, loop through them.
4381 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4383 if (isset($content['attribs']['']['url']))
4396 $samplingrate = null;
4406 $description = null;
4411 $restrictions = null;
4415 // Start checking the attributes of media:content
4416 if (isset($content['attribs']['']['bitrate']))
4418 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4420 if (isset($content['attribs']['']['channels']))
4422 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4424 if (isset($content['attribs']['']['duration']))
4426 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4430 $duration = $duration_parent;
4432 if (isset($content['attribs']['']['expression']))
4434 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4436 if (isset($content['attribs']['']['framerate']))
4438 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4440 if (isset($content['attribs']['']['height']))
4442 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4444 if (isset($content['attribs']['']['lang']))
4446 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4448 if (isset($content['attribs']['']['fileSize']))
4450 $length = ceil($content['attribs']['']['fileSize']);
4452 if (isset($content['attribs']['']['medium']))
4454 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4456 if (isset($content['attribs']['']['samplingrate']))
4458 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4460 if (isset($content['attribs']['']['type']))
4462 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4464 if (isset($content['attribs']['']['width']))
4466 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4468 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4470 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4473 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4475 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4477 $caption_type = null;
4478 $caption_lang = null;
4479 $caption_startTime = null;
4480 $caption_endTime = null;
4481 $caption_text = null;
4482 if (isset($caption['attribs']['']['type']))
4484 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4486 if (isset($caption['attribs']['']['lang']))
4488 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4490 if (isset($caption['attribs']['']['start']))
4492 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4494 if (isset($caption['attribs']['']['end']))
4496 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4498 if (isset($caption['data']))
4500 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4502 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4504 if (is_array($captions))
4506 $captions = array_values(SimplePie_Misc::array_unique($captions));
4509 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4511 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4513 $caption_type = null;
4514 $caption_lang = null;
4515 $caption_startTime = null;
4516 $caption_endTime = null;
4517 $caption_text = null;
4518 if (isset($caption['attribs']['']['type']))
4520 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4522 if (isset($caption['attribs']['']['lang']))
4524 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4526 if (isset($caption['attribs']['']['start']))
4528 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4530 if (isset($caption['attribs']['']['end']))
4532 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4534 if (isset($caption['data']))
4536 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4538 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4540 if (is_array($captions))
4542 $captions = array_values(SimplePie_Misc::array_unique($captions));
4547 $captions = $captions_parent;
4551 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4553 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4558 if (isset($category['data']))
4560 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4562 if (isset($category['attribs']['']['scheme']))
4564 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4568 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4570 if (isset($category['attribs']['']['label']))
4572 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4574 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4577 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4579 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4584 if (isset($category['data']))
4586 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4588 if (isset($category['attribs']['']['scheme']))
4590 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4594 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4596 if (isset($category['attribs']['']['label']))
4598 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4600 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4603 if (is_array($categories) && is_array($categories_parent))
4605 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4607 elseif (is_array($categories))
4609 $categories = array_values(SimplePie_Misc::array_unique($categories));
4611 elseif (is_array($categories_parent))
4613 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4617 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4619 $copyright_url = null;
4620 $copyright_label = null;
4621 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4623 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4625 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4627 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4629 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4631 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4633 $copyright_url = null;
4634 $copyright_label = null;
4635 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4637 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4639 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4641 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4643 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4647 $copyrights = $copyrights_parent;
4651 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4653 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4655 $credit_role = null;
4656 $credit_scheme = null;
4657 $credit_name = null;
4658 if (isset($credit['attribs']['']['role']))
4660 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4662 if (isset($credit['attribs']['']['scheme']))
4664 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4668 $credit_scheme = 'urn:ebu';
4670 if (isset($credit['data']))
4672 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4674 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4676 if (is_array($credits))
4678 $credits = array_values(SimplePie_Misc::array_unique($credits));
4681 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4683 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4685 $credit_role = null;
4686 $credit_scheme = null;
4687 $credit_name = null;
4688 if (isset($credit['attribs']['']['role']))
4690 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4692 if (isset($credit['attribs']['']['scheme']))
4694 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4698 $credit_scheme = 'urn:ebu';
4700 if (isset($credit['data']))
4702 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4704 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4706 if (is_array($credits))
4708 $credits = array_values(SimplePie_Misc::array_unique($credits));
4713 $credits = $credits_parent;
4717 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4719 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4721 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4723 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4727 $description = $description_parent;
4731 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4733 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4737 if (isset($hash['data']))
4739 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4741 if (isset($hash['attribs']['']['algo']))
4743 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4749 $hashes[] = $algo.':'.$value;
4751 if (is_array($hashes))
4753 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4756 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4758 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4762 if (isset($hash['data']))
4764 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4766 if (isset($hash['attribs']['']['algo']))
4768 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4774 $hashes[] = $algo.':'.$value;
4776 if (is_array($hashes))
4778 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4783 $hashes = $hashes_parent;
4787 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4789 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4791 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4792 foreach ($temp as $word)
4794 $keywords[] = trim($word);
4798 if (is_array($keywords))
4800 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4803 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4805 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4807 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4808 foreach ($temp as $word)
4810 $keywords[] = trim($word);
4814 if (is_array($keywords))
4816 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4821 $keywords = $keywords_parent;
4825 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4827 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4829 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4831 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4835 $player = $player_parent;
4839 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4841 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4843 $rating_scheme = null;
4844 $rating_value = null;
4845 if (isset($rating['attribs']['']['scheme']))
4847 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4851 $rating_scheme = 'urn:simple';
4853 if (isset($rating['data']))
4855 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4857 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4859 if (is_array($ratings))
4861 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4864 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4866 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4868 $rating_scheme = null;
4869 $rating_value = null;
4870 if (isset($rating['attribs']['']['scheme']))
4872 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4876 $rating_scheme = 'urn:simple';
4878 if (isset($rating['data']))
4880 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4882 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4884 if (is_array($ratings))
4886 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4891 $ratings = $ratings_parent;
4895 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4897 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4899 $restriction_relationship = null;
4900 $restriction_type = null;
4901 $restriction_value = null;
4902 if (isset($restriction['attribs']['']['relationship']))
4904 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4906 if (isset($restriction['attribs']['']['type']))
4908 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4910 if (isset($restriction['data']))
4912 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4914 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4916 if (is_array($restrictions))
4918 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4921 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4923 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4925 $restriction_relationship = null;
4926 $restriction_type = null;
4927 $restriction_value = null;
4928 if (isset($restriction['attribs']['']['relationship']))
4930 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4932 if (isset($restriction['attribs']['']['type']))
4934 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4936 if (isset($restriction['data']))
4938 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4940 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4942 if (is_array($restrictions))
4944 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4949 $restrictions = $restrictions_parent;
4953 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4955 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4957 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4959 if (is_array($thumbnails))
4961 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4964 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4966 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4968 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4970 if (is_array($thumbnails))
4972 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4977 $thumbnails = $thumbnails_parent;
4981 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4983 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4985 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4987 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4991 $title = $title_parent;
4994 $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);
4999 // If we have standalone media:content tags, loop through them.
5000 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5002 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5004 if (isset($content['attribs']['']['url']))
5017 $samplingrate = null;
5027 $description = null;
5032 $restrictions = null;
5036 // Start checking the attributes of media:content
5037 if (isset($content['attribs']['']['bitrate']))
5039 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5041 if (isset($content['attribs']['']['channels']))
5043 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5045 if (isset($content['attribs']['']['duration']))
5047 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5051 $duration = $duration_parent;
5053 if (isset($content['attribs']['']['expression']))
5055 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5057 if (isset($content['attribs']['']['framerate']))
5059 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5061 if (isset($content['attribs']['']['height']))
5063 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5065 if (isset($content['attribs']['']['lang']))
5067 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5069 if (isset($content['attribs']['']['fileSize']))
5071 $length = ceil($content['attribs']['']['fileSize']);
5073 if (isset($content['attribs']['']['medium']))
5075 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5077 if (isset($content['attribs']['']['samplingrate']))
5079 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5081 if (isset($content['attribs']['']['type']))
5083 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5085 if (isset($content['attribs']['']['width']))
5087 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5089 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5091 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5094 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5096 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5098 $caption_type = null;
5099 $caption_lang = null;
5100 $caption_startTime = null;
5101 $caption_endTime = null;
5102 $caption_text = null;
5103 if (isset($caption['attribs']['']['type']))
5105 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5107 if (isset($caption['attribs']['']['lang']))
5109 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5111 if (isset($caption['attribs']['']['start']))
5113 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5115 if (isset($caption['attribs']['']['end']))
5117 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5119 if (isset($caption['data']))
5121 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5123 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5125 if (is_array($captions))
5127 $captions = array_values(SimplePie_Misc::array_unique($captions));
5132 $captions = $captions_parent;
5136 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5138 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5143 if (isset($category['data']))
5145 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5147 if (isset($category['attribs']['']['scheme']))
5149 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5153 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5155 if (isset($category['attribs']['']['label']))
5157 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5159 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5162 if (is_array($categories) && is_array($categories_parent))
5164 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5166 elseif (is_array($categories))
5168 $categories = array_values(SimplePie_Misc::array_unique($categories));
5170 elseif (is_array($categories_parent))
5172 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5180 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5182 $copyright_url = null;
5183 $copyright_label = null;
5184 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5186 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5188 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5190 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5192 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5196 $copyrights = $copyrights_parent;
5200 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5202 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5204 $credit_role = null;
5205 $credit_scheme = null;
5206 $credit_name = null;
5207 if (isset($credit['attribs']['']['role']))
5209 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5211 if (isset($credit['attribs']['']['scheme']))
5213 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5217 $credit_scheme = 'urn:ebu';
5219 if (isset($credit['data']))
5221 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5223 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5225 if (is_array($credits))
5227 $credits = array_values(SimplePie_Misc::array_unique($credits));
5232 $credits = $credits_parent;
5236 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5238 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5242 $description = $description_parent;
5246 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5248 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5252 if (isset($hash['data']))
5254 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5256 if (isset($hash['attribs']['']['algo']))
5258 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5264 $hashes[] = $algo.':'.$value;
5266 if (is_array($hashes))
5268 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5273 $hashes = $hashes_parent;
5277 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5279 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5281 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5282 foreach ($temp as $word)
5284 $keywords[] = trim($word);
5288 if (is_array($keywords))
5290 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5295 $keywords = $keywords_parent;
5299 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5301 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5305 $player = $player_parent;
5309 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5311 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5313 $rating_scheme = null;
5314 $rating_value = null;
5315 if (isset($rating['attribs']['']['scheme']))
5317 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5321 $rating_scheme = 'urn:simple';
5323 if (isset($rating['data']))
5325 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5327 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5329 if (is_array($ratings))
5331 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5336 $ratings = $ratings_parent;
5340 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5342 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5344 $restriction_relationship = null;
5345 $restriction_type = null;
5346 $restriction_value = null;
5347 if (isset($restriction['attribs']['']['relationship']))
5349 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5351 if (isset($restriction['attribs']['']['type']))
5353 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5355 if (isset($restriction['data']))
5357 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5359 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5361 if (is_array($restrictions))
5363 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5368 $restrictions = $restrictions_parent;
5372 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5374 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5376 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5378 if (is_array($thumbnails))
5380 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5385 $thumbnails = $thumbnails_parent;
5389 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5391 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5395 $title = $title_parent;
5398 $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);
5403 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5405 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5418 $samplingrate = null;
5423 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5424 if (isset($link['attribs']['']['type']))
5426 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5428 if (isset($link['attribs']['']['length']))
5430 $length = ceil($link['attribs']['']['length']);
5433 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5434 $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);
5438 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5440 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5453 $samplingrate = null;
5458 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5459 if (isset($link['attribs']['']['type']))
5461 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5463 if (isset($link['attribs']['']['length']))
5465 $length = ceil($link['attribs']['']['length']);
5468 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5469 $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);
5473 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5475 if (isset($enclosure[0]['attribs']['']['url']))
5488 $samplingrate = null;
5493 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5494 if (isset($enclosure[0]['attribs']['']['type']))
5496 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5498 if (isset($enclosure[0]['attribs']['']['length']))
5500 $length = ceil($enclosure[0]['attribs']['']['length']);
5503 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5504 $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 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))
5510 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5511 $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);
5514 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5516 if (!empty($this->data['enclosures']))
5518 return $this->data['enclosures'];
5526 function get_latitude()
5528 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5530 return (float) $return[0]['data'];
5532 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5534 return (float) $match[1];
5542 function get_longitude()
5544 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5546 return (float) $return[0]['data'];
5548 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5550 return (float) $return[0]['data'];
5552 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5554 return (float) $match[2];
5562 function get_source()
5564 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5566 return new $this->feed->source_class($this, $return[0]);
5575 * Creates the add_to_* methods' return data
5578 * @param string $item_url String to prefix to the item permalink
5579 * @param string $title_url String to prefix to the item title
5580 * (and suffix to the item permalink)
5581 * @return mixed URL if feed exists, false otherwise
5583 function add_to_service($item_url, $title_url = null, $summary_url = null)
5585 if ($this->get_permalink() !== null)
5587 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5588 if ($title_url !== null && $this->get_title() !== null)
5590 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5592 if ($summary_url !== null && $this->get_description() !== null)
5594 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5604 function add_to_blinklist()
5606 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5609 function add_to_blogmarks()
5611 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5614 function add_to_delicious()
5616 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5619 function add_to_digg()
5621 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5624 function add_to_furl()
5626 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5629 function add_to_magnolia()
5631 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5634 function add_to_myweb20()
5636 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5639 function add_to_newsvine()
5641 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5644 function add_to_reddit()
5646 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5649 function add_to_segnalo()
5651 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5654 function add_to_simpy()
5656 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5659 function add_to_spurl()
5661 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5664 function add_to_wists()
5666 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5669 function search_technorati()
5671 return $this->add_to_service('http://www.technorati.com/search/');
5675 class SimplePie_Source
5678 var $data = array();
5680 function SimplePie_Source($item, $data)
5682 $this->item = $item;
5683 $this->data = $data;
5686 function __toString()
5688 return md5(serialize($this->data));
5691 function get_source_tags($namespace, $tag)
5693 if (isset($this->data['child'][$namespace][$tag]))
5695 return $this->data['child'][$namespace][$tag];
5703 function get_base($element = array())
5705 return $this->item->get_base($element);
5708 function sanitize($data, $type, $base = '')
5710 return $this->item->sanitize($data, $type, $base);
5718 function get_title()
5720 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5722 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5724 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5726 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5728 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5730 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5732 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5734 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5736 elseif ($return = $this->get_source_tags('', 'title'))
5738 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5740 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5742 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5744 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5746 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5754 function get_category($key = 0)
5756 $categories = $this->get_categories();
5757 if (isset($categories[$key]))
5759 return $categories[$key];
5767 function get_categories()
5769 $categories = array();
5771 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5776 if (isset($category['attribs']['']['term']))
5778 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5780 if (isset($category['attribs']['']['scheme']))
5782 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5784 if (isset($category['attribs']['']['label']))
5786 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5788 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5790 foreach ((array) $this->get_source_tags('', 'category') as $category)
5792 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5794 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5796 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5798 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5800 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5803 if (!empty($categories))
5805 return SimplePie_Misc::array_unique($categories);
5813 function get_author($key = 0)
5815 $authors = $this->get_authors();
5816 if (isset($authors[$key]))
5818 return $authors[$key];
5826 function get_authors()
5829 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5834 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5836 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5838 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5840 $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]));
5842 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5844 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5846 if ($name !== null || $email !== null || $uri !== null)
5848 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5851 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5856 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5858 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5860 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5862 $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]));
5864 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5866 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5868 if ($name !== null || $email !== null || $url !== null)
5870 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5873 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5875 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5877 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5879 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5881 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5883 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5886 if (!empty($authors))
5888 return SimplePie_Misc::array_unique($authors);
5896 function get_contributor($key = 0)
5898 $contributors = $this->get_contributors();
5899 if (isset($contributors[$key]))
5901 return $contributors[$key];
5909 function get_contributors()
5911 $contributors = array();
5912 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5917 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5919 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5921 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5923 $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]));
5925 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5927 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5929 if ($name !== null || $email !== null || $uri !== null)
5931 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5934 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5939 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5941 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5943 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5945 $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]));
5947 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5949 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5951 if ($name !== null || $email !== null || $url !== null)
5953 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5957 if (!empty($contributors))
5959 return SimplePie_Misc::array_unique($contributors);
5967 function get_link($key = 0, $rel = 'alternate')
5969 $links = $this->get_links($rel);
5970 if (isset($links[$key]))
5972 return $links[$key];
5981 * Added for parity between the parent-level and the item/entry-level.
5983 function get_permalink()
5985 return $this->get_link(0);
5988 function get_links($rel = 'alternate')
5990 if (!isset($this->data['links']))
5992 $this->data['links'] = array();
5993 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5995 foreach ($links as $link)
5997 if (isset($link['attribs']['']['href']))
5999 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6000 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6004 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6006 foreach ($links as $link)
6008 if (isset($link['attribs']['']['href']))
6010 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6011 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6016 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6018 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6020 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6022 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6024 if ($links = $this->get_source_tags('', 'link'))
6026 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6029 $keys = array_keys($this->data['links']);
6030 foreach ($keys as $key)
6032 if (SimplePie_Misc::is_isegment_nz_nc($key))
6034 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6036 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6037 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6041 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6044 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6046 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6048 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6052 if (isset($this->data['links'][$rel]))
6054 return $this->data['links'][$rel];
6062 function get_description()
6064 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6066 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6068 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6070 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6072 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6074 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6076 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6078 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6080 elseif ($return = $this->get_source_tags('', 'description'))
6082 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6084 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6086 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6088 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6090 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6092 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6094 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6096 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6098 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6106 function get_copyright()
6108 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6110 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6112 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6114 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6116 elseif ($return = $this->get_source_tags('', 'copyright'))
6118 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6120 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6122 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6124 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6126 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6134 function get_language()
6136 if ($return = $this->get_source_tags('', 'language'))
6138 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6140 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6142 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6144 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6146 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6148 elseif (isset($this->data['xml_lang']))
6150 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6158 function get_latitude()
6160 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6162 return (float) $return[0]['data'];
6164 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6166 return (float) $match[1];
6174 function get_longitude()
6176 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6178 return (float) $return[0]['data'];
6180 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6182 return (float) $return[0]['data'];
6184 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6186 return (float) $match[2];
6194 function get_image_url()
6196 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6198 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6200 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6202 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6204 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6206 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6215 class SimplePie_Author
6221 // Constructor, used to input the data
6222 function SimplePie_Author($name = null, $link = null, $email = null)
6224 $this->name = $name;
6225 $this->link = $link;
6226 $this->email = $email;
6229 function __toString()
6231 // There is no $this->data here
6232 return md5(serialize($this));
6237 if ($this->name !== null)
6249 if ($this->link !== null)
6259 function get_email()
6261 if ($this->email !== null)
6263 return $this->email;
6272 class SimplePie_Category
6278 // Constructor, used to input the data
6279 function SimplePie_Category($term = null, $scheme = null, $label = null)
6281 $this->term = $term;
6282 $this->scheme = $scheme;
6283 $this->label = $label;
6286 function __toString()
6288 // There is no $this->data here
6289 return md5(serialize($this));
6294 if ($this->term !== null)
6304 function get_scheme()
6306 if ($this->scheme !== null)
6308 return $this->scheme;
6316 function get_label()
6318 if ($this->label !== null)
6320 return $this->label;
6324 return $this->get_term();
6329 class SimplePie_Enclosure
6359 // Constructor, used to input the data
6360 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)
6362 $this->bitrate = $bitrate;
6363 $this->captions = $captions;
6364 $this->categories = $categories;
6365 $this->channels = $channels;
6366 $this->copyright = $copyright;
6367 $this->credits = $credits;
6368 $this->description = $description;
6369 $this->duration = $duration;
6370 $this->expression = $expression;
6371 $this->framerate = $framerate;
6372 $this->hashes = $hashes;
6373 $this->height = $height;
6374 $this->javascript = $javascript;
6375 $this->keywords = $keywords;
6376 $this->lang = $lang;
6377 $this->length = $length;
6378 $this->link = $link;
6379 $this->medium = $medium;
6380 $this->player = $player;
6381 $this->ratings = $ratings;
6382 $this->restrictions = $restrictions;
6383 $this->samplingrate = $samplingrate;
6384 $this->thumbnails = $thumbnails;
6385 $this->title = $title;
6386 $this->type = $type;
6387 $this->width = $width;
6388 if (class_exists('idna_convert'))
6390 $idn =& new idna_convert;
6391 $parsed = SimplePie_Misc::parse_url($link);
6392 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6394 $this->handler = $this->get_handler(); // Needs to load last
6397 function __toString()
6399 // There is no $this->data here
6400 return md5(serialize($this));
6403 function get_bitrate()
6405 if ($this->bitrate !== null)
6407 return $this->bitrate;
6415 function get_caption($key = 0)
6417 $captions = $this->get_captions();
6418 if (isset($captions[$key]))
6420 return $captions[$key];
6428 function get_captions()
6430 if ($this->captions !== null)
6432 return $this->captions;
6440 function get_category($key = 0)
6442 $categories = $this->get_categories();
6443 if (isset($categories[$key]))
6445 return $categories[$key];
6453 function get_categories()
6455 if ($this->categories !== null)
6457 return $this->categories;
6465 function get_channels()
6467 if ($this->channels !== null)
6469 return $this->channels;
6477 function get_copyright()
6479 if ($this->copyright !== null)
6481 return $this->copyright;
6489 function get_credit($key = 0)
6491 $credits = $this->get_credits();
6492 if (isset($credits[$key]))
6494 return $credits[$key];
6502 function get_credits()
6504 if ($this->credits !== null)
6506 return $this->credits;
6514 function get_description()
6516 if ($this->description !== null)
6518 return $this->description;
6526 function get_duration($convert = false)
6528 if ($this->duration !== null)
6532 $time = SimplePie_Misc::time_hms($this->duration);
6537 return $this->duration;
6546 function get_expression()
6548 if ($this->expression !== null)
6550 return $this->expression;
6558 function get_extension()
6560 if ($this->link !== null)
6562 $url = SimplePie_Misc::parse_url($this->link);
6563 if ($url['path'] !== '')
6565 return pathinfo($url['path'], PATHINFO_EXTENSION);
6571 function get_framerate()
6573 if ($this->framerate !== null)
6575 return $this->framerate;
6583 function get_handler()
6585 return $this->get_real_type(true);
6588 function get_hash($key = 0)
6590 $hashes = $this->get_hashes();
6591 if (isset($hashes[$key]))
6593 return $hashes[$key];
6601 function get_hashes()
6603 if ($this->hashes !== null)
6605 return $this->hashes;
6613 function get_height()
6615 if ($this->height !== null)
6617 return $this->height;
6625 function get_language()
6627 if ($this->lang !== null)
6637 function get_keyword($key = 0)
6639 $keywords = $this->get_keywords();
6640 if (isset($keywords[$key]))
6642 return $keywords[$key];
6650 function get_keywords()
6652 if ($this->keywords !== null)
6654 return $this->keywords;
6662 function get_length()
6664 if ($this->length !== null)
6666 return $this->length;
6676 if ($this->link !== null)
6678 return urldecode($this->link);
6686 function get_medium()
6688 if ($this->medium !== null)
6690 return $this->medium;
6698 function get_player()
6700 if ($this->player !== null)
6702 return $this->player;
6710 function get_rating($key = 0)
6712 $ratings = $this->get_ratings();
6713 if (isset($ratings[$key]))
6715 return $ratings[$key];
6723 function get_ratings()
6725 if ($this->ratings !== null)
6727 return $this->ratings;
6735 function get_restriction($key = 0)
6737 $restrictions = $this->get_restrictions();
6738 if (isset($restrictions[$key]))
6740 return $restrictions[$key];
6748 function get_restrictions()
6750 if ($this->restrictions !== null)
6752 return $this->restrictions;
6760 function get_sampling_rate()
6762 if ($this->samplingrate !== null)
6764 return $this->samplingrate;
6774 $length = $this->get_length();
6775 if ($length !== null)
6777 return round($length/1048576, 2);
6785 function get_thumbnail($key = 0)
6787 $thumbnails = $this->get_thumbnails();
6788 if (isset($thumbnails[$key]))
6790 return $thumbnails[$key];
6798 function get_thumbnails()
6800 if ($this->thumbnails !== null)
6802 return $this->thumbnails;
6810 function get_title()
6812 if ($this->title !== null)
6814 return $this->title;
6824 if ($this->type !== null)
6834 function get_width()
6836 if ($this->width !== null)
6838 return $this->width;
6846 function native_embed($options='')
6848 return $this->embed($options, true);
6852 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6854 function embed($options = '', $native = false)
6864 $bgcolor = '#ffffff';
6866 $widescreen = false;
6867 $handler = $this->get_handler();
6868 $type = $this->get_real_type();
6870 // Process options and reassign values as necessary
6871 if (is_array($options))
6877 $options = explode(',', $options);
6878 foreach($options as $option)
6880 $opt = explode(':', $option, 2);
6881 if (isset($opt[0], $opt[1]))
6883 $opt[0] = trim($opt[0]);
6884 $opt[1] = trim($opt[1]);
6900 $altclass = $opt[1];
6920 $mediaplayer = $opt[1];
6924 $widescreen = $opt[1];
6931 $mime = explode('/', $type, 2);
6934 // Process values for 'auto'
6935 if ($width == 'auto')
6937 if ($mime == 'video')
6939 if ($height == 'auto')
6943 elseif ($widescreen)
6945 $width = round((intval($height)/9)*16);
6949 $width = round((intval($height)/3)*4);
6958 if ($height == 'auto')
6960 if ($mime == 'audio')
6964 elseif ($mime == 'video')
6966 if ($width == 'auto')
6977 elseif ($widescreen)
6979 $height = round((intval($width)/16)*9);
6983 $height = round((intval($width)/4)*3);
6991 elseif ($mime == 'audio')
6996 // Set proper placeholder value
6997 if ($mime == 'audio')
6999 $placeholder = $audio;
7001 elseif ($mime == 'video')
7003 $placeholder = $video;
7008 // Make sure the JS library is included
7011 static $javascript_outputted = null;
7012 if (!$javascript_outputted && $this->javascript)
7014 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7015 $javascript_outputted = true;
7020 if ($handler == 'odeo')
7024 $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>';
7028 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7033 elseif ($handler == 'flash')
7037 $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>";
7041 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7045 // Flash Media Player file types.
7046 // Preferred handler for MP3 file types.
7047 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7052 $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>";
7056 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7060 // QuickTime 7 file types. Need to test with QuickTime 6.
7061 // Only handle MP3's if the Flash Media Player is not present.
7062 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7067 if ($placeholder != ""){
7068 $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>";
7071 $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>";
7076 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7081 elseif ($handler == 'wmedia')
7086 $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>";
7090 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7095 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7100 function get_real_type($find_handler = false)
7102 // If it's Odeo, let's get it out of the way.
7103 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7108 // Mime-types by handler.
7109 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7110 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7111 $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
7112 $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
7113 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7115 if ($this->get_type() !== null)
7117 $type = strtolower($this->type);
7124 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7125 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7127 switch (strtolower($this->get_extension()))
7132 $type = 'audio/acc';
7139 $type = 'audio/aiff';
7143 $type = 'audio/wav';
7150 $type = 'audio/midi';
7154 $type = 'audio/x-m4a';
7159 $type = 'audio/mp3';
7163 $type = 'audio/wav';
7167 $type = 'audio/x-ms-wax';
7171 $type = 'audio/x-ms-wma';
7177 $type = 'video/3gpp';
7182 $type = 'video/3gpp2';
7186 $type = 'video/x-ms-asf';
7190 $type = 'video/x-flv';
7204 $type = 'video/mpeg';
7208 $type = 'video/x-m4v';
7213 $type = 'video/quicktime';
7218 $type = 'video/mp4';
7222 $type = 'video/sd-video';
7226 $type = 'video/x-ms-wm';
7230 $type = 'video/x-ms-wmv';
7234 $type = 'video/x-ms-wvx';
7239 $type = 'application/futuresplash';
7243 $type = 'application/x-shockwave-flash';
7250 if (in_array($type, $types_flash))
7254 elseif (in_array($type, $types_fmedia))
7258 elseif (in_array($type, $types_quicktime))
7262 elseif (in_array($type, $types_wmedia))
7266 elseif (in_array($type, $types_mp3))
7282 class SimplePie_Caption
7290 // Constructor, used to input the data
7291 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7293 $this->type = $type;
7294 $this->lang = $lang;
7295 $this->startTime = $startTime;
7296 $this->endTime = $endTime;
7297 $this->text = $text;
7300 function __toString()
7302 // There is no $this->data here
7303 return md5(serialize($this));
7306 function get_endtime()
7308 if ($this->endTime !== null)
7310 return $this->endTime;
7318 function get_language()
7320 if ($this->lang !== null)
7330 function get_starttime()
7332 if ($this->startTime !== null)
7334 return $this->startTime;
7344 if ($this->text !== null)
7356 if ($this->type !== null)
7367 class SimplePie_Credit
7373 // Constructor, used to input the data
7374 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7376 $this->role = $role;
7377 $this->scheme = $scheme;
7378 $this->name = $name;
7381 function __toString()
7383 // There is no $this->data here
7384 return md5(serialize($this));
7389 if ($this->role !== null)
7399 function get_scheme()
7401 if ($this->scheme !== null)
7403 return $this->scheme;
7413 if ($this->name !== null)
7424 class SimplePie_Copyright
7429 // Constructor, used to input the data
7430 function SimplePie_Copyright($url = null, $label = null)
7433 $this->label = $label;
7436 function __toString()
7438 // There is no $this->data here
7439 return md5(serialize($this));
7444 if ($this->url !== null)
7454 function get_attribution()
7456 if ($this->label !== null)
7458 return $this->label;
7467 class SimplePie_Rating
7472 // Constructor, used to input the data
7473 function SimplePie_Rating($scheme = null, $value = null)
7475 $this->scheme = $scheme;
7476 $this->value = $value;
7479 function __toString()
7481 // There is no $this->data here
7482 return md5(serialize($this));
7485 function get_scheme()
7487 if ($this->scheme !== null)
7489 return $this->scheme;
7497 function get_value()
7499 if ($this->value !== null)
7501 return $this->value;
7510 class SimplePie_Restriction
7516 // Constructor, used to input the data
7517 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7519 $this->relationship = $relationship;
7520 $this->type = $type;
7521 $this->value = $value;
7524 function __toString()
7526 // There is no $this->data here
7527 return md5(serialize($this));
7530 function get_relationship()
7532 if ($this->relationship !== null)
7534 return $this->relationship;
7544 if ($this->type !== null)
7554 function get_value()
7556 if ($this->value !== null)
7558 return $this->value;
7568 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7570 class SimplePie_File
7574 var $success = true;
7575 var $headers = array();
7580 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7582 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7584 if (class_exists('idna_convert'))
7586 $idn =& new idna_convert;
7587 $parsed = SimplePie_Misc::parse_url($url);
7588 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7591 $this->useragent = $useragent;
7592 if (preg_match('/^http(s)?:\/\//i', $url))
7594 if ($useragent === null)
7596 $useragent = ini_get('user_agent');
7597 $this->useragent = $useragent;
7599 if (!is_array($headers))
7603 if (!$force_fsockopen && function_exists('curl_exec'))
7605 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7607 $headers2 = array();
7608 foreach ($headers as $key => $value)
7610 $headers2[] = "$key: $value";
7612 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7614 curl_setopt($fp, CURLOPT_ENCODING, '');
7616 curl_setopt($fp, CURLOPT_URL, $url);
7617 curl_setopt($fp, CURLOPT_HEADER, 1);
7618 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7619 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7620 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7621 curl_setopt($fp, CURLOPT_REFERER, $url);
7622 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7623 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7624 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7626 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7627 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7630 $this->headers = curl_exec($fp);
7631 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7633 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7634 $this->headers = curl_exec($fp);
7636 if (curl_errno($fp))
7638 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7639 $this->success = false;
7643 $info = curl_getinfo($fp);
7645 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7646 $this->headers = array_pop($this->headers);
7647 $parser =& new SimplePie_HTTP_Parser($this->headers);
7648 if ($parser->parse())
7650 $this->headers = $parser->headers;
7651 $this->body = $parser->body;
7652 $this->status_code = $parser->status_code;
7653 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)
7656 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7657 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7664 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7665 $url_parts = parse_url($url);
7666 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7668 $url_parts['host'] = "ssl://$url_parts[host]";
7669 $url_parts['port'] = 443;
7671 if (!isset($url_parts['port']))
7673 $url_parts['port'] = 80;
7675 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7678 $this->error = 'fsockopen error: ' . $errstr;
7679 $this->success = false;
7683 stream_set_timeout($fp, $timeout);
7684 if (isset($url_parts['path']))
7686 if (isset($url_parts['query']))
7688 $get = "$url_parts[path]?$url_parts[query]";
7692 $get = $url_parts['path'];
7699 $out = "GET $get HTTP/1.0\r\n";
7700 $out .= "Host: $url_parts[host]\r\n";
7701 $out .= "User-Agent: $useragent\r\n";
7702 if (extension_loaded('zlib'))
7704 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7707 if (isset($url_parts['user']) && isset($url_parts['pass']))
7709 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7711 foreach ($headers as $key => $value)
7713 $out .= "$key: $value\r\n";
7715 $out .= "Connection: Close\r\n\r\n";
7718 $info = stream_get_meta_data($fp);
7720 $this->headers = '';
7721 while (!$info['eof'] && !$info['timed_out'])
7723 $this->headers .= fread($fp, 1160);
7724 $info = stream_get_meta_data($fp);
7726 if (!$info['timed_out'])
7728 $parser =& new SimplePie_HTTP_Parser($this->headers);
7729 if ($parser->parse())
7731 $this->headers = $parser->headers;
7732 $this->body = $parser->body;
7733 $this->status_code = $parser->status_code;
7734 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)
7737 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7738 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7740 if (isset($this->headers['content-encoding']))
7742 // Hey, we act dumb elsewhere, so let's do that here too
7743 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7747 $decoder =& new SimplePie_gzdecode($this->body);
7748 if (!$decoder->parse())
7750 $this->error = 'Unable to decode HTTP "gzip" stream';
7751 $this->success = false;
7755 $this->body = $decoder->data;
7760 if (($body = gzuncompress($this->body)) === false)
7762 if (($body = gzinflate($this->body)) === false)
7764 $this->error = 'Unable to decode HTTP "deflate" stream';
7765 $this->success = false;
7768 $this->body = $body;
7772 $this->error = 'Unknown content coding';
7773 $this->success = false;
7780 $this->error = 'fsocket timed out';
7781 $this->success = false;
7789 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7790 if (!$this->body = file_get_contents($url))
7792 $this->error = 'file_get_contents could not read the file';
7793 $this->success = false;
7800 * HTTP Response Parser
7802 * @package SimplePie
7804 class SimplePie_HTTP_Parser
7812 var $http_version = 0.0;
7820 var $status_code = 0;
7831 * Key/value pairs of the headers
7836 var $headers = array();
7839 * Body of the response
7847 * Current state of the state machine
7852 var $state = 'http_version';
7863 * Input data length (to avoid calling strlen() everytime this is needed)
7868 var $data_length = 0;
7871 * Current position of the pointer
7879 * Name of the hedaer currently being parsed
7887 * Value of the hedaer currently being parsed
7895 * Create an instance of the class with the input data
7898 * @param string $data Input data
7900 function SimplePie_HTTP_Parser($data)
7902 $this->data = $data;
7903 $this->data_length = strlen($this->data);
7907 * Parse the input data
7910 * @return bool true on success, false on failure
7914 while ($this->state && $this->state !== 'emit' && $this->has_data())
7916 $state = $this->state;
7920 if ($this->state === 'emit' || $this->state === 'body')
7926 $this->http_version = '';
7927 $this->status_code = '';
7929 $this->headers = array();
7936 * Check whether there is data beyond the pointer
7939 * @return bool true if there is further data, false if not
7943 return (bool) ($this->position < $this->data_length);
7947 * See if the next character is LWS
7950 * @return bool true if the next character is LWS, false if not
7952 function is_linear_whitespace()
7954 return (bool) ($this->data[$this->position] === "\x09"
7955 || $this->data[$this->position] === "\x20"
7956 || ($this->data[$this->position] === "\x0A"
7957 && isset($this->data[$this->position + 1])
7958 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7962 * Parse the HTTP version
7966 function http_version()
7968 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7970 $len = strspn($this->data, '0123456789.', 5);
7971 $this->http_version = substr($this->data, 5, $len);
7972 $this->position += 5 + $len;
7973 if (substr_count($this->http_version, '.') <= 1)
7975 $this->http_version = (float) $this->http_version;
7976 $this->position += strspn($this->data, "\x09\x20", $this->position);
7977 $this->state = 'status';
7981 $this->state = false;
7986 $this->state = false;
7991 * Parse the status code
7997 if ($len = strspn($this->data, '0123456789', $this->position))
7999 $this->status_code = (int) substr($this->data, $this->position, $len);
8000 $this->position += $len;
8001 $this->state = 'reason';
8005 $this->state = false;
8010 * Parse the reason phrase
8016 $len = strcspn($this->data, "\x0A", $this->position);
8017 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8018 $this->position += $len + 1;
8019 $this->state = 'new_line';
8023 * Deal with a new line, shifting data around as needed
8029 $this->value = trim($this->value, "\x0D\x20");
8030 if ($this->name !== '' && $this->value !== '')
8032 $this->name = strtolower($this->name);
8033 if (isset($this->headers[$this->name]))
8035 $this->headers[$this->name] .= ', ' . $this->value;
8039 $this->headers[$this->name] = $this->value;
8044 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8046 $this->position += 2;
8047 $this->state = 'body';
8049 elseif ($this->data[$this->position] === "\x0A")
8052 $this->state = 'body';
8056 $this->state = 'name';
8061 * Parse a header name
8067 $len = strcspn($this->data, "\x0A:", $this->position);
8068 if (isset($this->data[$this->position + $len]))
8070 if ($this->data[$this->position + $len] === "\x0A")
8072 $this->position += $len;
8073 $this->state = 'new_line';
8077 $this->name = substr($this->data, $this->position, $len);
8078 $this->position += $len + 1;
8079 $this->state = 'value';
8084 $this->state = false;
8089 * Parse LWS, replacing consecutive LWS characters with a single space
8093 function linear_whitespace()
8097 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8099 $this->position += 2;
8101 elseif ($this->data[$this->position] === "\x0A")
8105 $this->position += strspn($this->data, "\x09\x20", $this->position);
8106 } while ($this->has_data() && $this->is_linear_whitespace());
8107 $this->value .= "\x20";
8111 * See what state to move to while within non-quoted header values
8117 if ($this->is_linear_whitespace())
8119 $this->linear_whitespace();
8123 switch ($this->data[$this->position])
8127 $this->state = 'quote';
8132 $this->state = 'new_line';
8136 $this->state = 'value_char';
8143 * Parse a header value while outside quotes
8147 function value_char()
8149 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8150 $this->value .= substr($this->data, $this->position, $len);
8151 $this->position += $len;
8152 $this->state = 'value';
8156 * See what state to move to while within quoted header values
8162 if ($this->is_linear_whitespace())
8164 $this->linear_whitespace();
8168 switch ($this->data[$this->position])
8172 $this->state = 'value';
8177 $this->state = 'new_line';
8182 $this->state = 'quote_escaped';
8186 $this->state = 'quote_char';
8193 * Parse a header value while within quotes
8197 function quote_char()
8199 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8200 $this->value .= substr($this->data, $this->position, $len);
8201 $this->position += $len;
8202 $this->state = 'value';
8206 * Parse an escaped character within quotes
8210 function quote_escaped()
8212 $this->value .= $this->data[$this->position];
8214 $this->state = 'quote';
8224 $this->body = substr($this->data, $this->position);
8225 $this->state = 'emit';
8232 * @package SimplePie
8234 class SimplePie_gzdecode
8240 * @see gzdecode::$data
8242 var $compressed_data;
8245 * Size of compressed data
8249 var $compressed_size;
8252 * Minimum size of a valid gzip string
8256 var $min_compressed_size = 18;
8259 * Current position of pointer
8276 * @see gzdecode::$compressed_data
8305 * @see gzdecode::$extra_field
8306 * @see gzdecode::$SI2
8314 * @see gzdecode::$extra_field
8315 * @see gzdecode::$SI1
8320 * Extra field content
8323 * @see gzdecode::$SI1
8324 * @see gzdecode::$SI2
8336 * Human readable comment
8343 * Don't allow anything to be set
8347 function __set($name, $value)
8349 trigger_error("Cannot write property $name", E_USER_ERROR);
8353 * Set the compressed string and related properties
8357 function SimplePie_gzdecode($data)
8359 $this->compressed_data = $data;
8360 $this->compressed_size = strlen($data);
8364 * Decode the GZIP stream
8370 if ($this->compressed_size >= $this->min_compressed_size)
8372 // Check ID1, ID2, and CM
8373 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8378 // Get the FLG (FLaGs)
8379 $this->flags = ord($this->compressed_data[3]);
8381 // FLG bits above (1 << 4) are reserved
8382 if ($this->flags > 0x1F)
8387 // Advance the pointer after the above
8388 $this->position += 4;
8391 $mtime = substr($this->compressed_data, $this->position, 4);
8392 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8393 if (current(unpack('S', "\x00\x01")) === 1)
8395 $mtime = strrev($mtime);
8397 $this->MTIME = current(unpack('l', $mtime));
8398 $this->position += 4;
8400 // Get the XFL (eXtra FLags)
8401 $this->XFL = ord($this->compressed_data[$this->position++]);
8403 // Get the OS (Operating System)
8404 $this->OS = ord($this->compressed_data[$this->position++]);
8407 if ($this->flags & 4)
8409 // Read subfield IDs
8410 $this->SI1 = $this->compressed_data[$this->position++];
8411 $this->SI2 = $this->compressed_data[$this->position++];
8413 // SI2 set to zero is reserved for future use
8414 if ($this->SI2 === "\x00")
8419 // Get the length of the extra field
8420 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8423 // Check the length of the string is still valid
8424 $this->min_compressed_size += $len + 4;
8425 if ($this->compressed_size >= $this->min_compressed_size)
8427 // Set the extra field to the given data
8428 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8429 $this->position += $len;
8438 if ($this->flags & 8)
8440 // Get the length of the filename
8441 $len = strspn($this->compressed_data, "\x00", $this->position);
8443 // Check the length of the string is still valid
8444 $this->min_compressed_size += $len + 1;
8445 if ($this->compressed_size >= $this->min_compressed_size)
8447 // Set the original filename to the given string
8448 $this->filename = substr($this->compressed_data, $this->position, $len);
8449 $this->position += $len + 1;
8457 // Parse the FCOMMENT
8458 if ($this->flags & 16)
8460 // Get the length of the comment
8461 $len = strspn($this->compressed_data, "\x00", $this->position);
8463 // Check the length of the string is still valid
8464 $this->min_compressed_size += $len + 1;
8465 if ($this->compressed_size >= $this->min_compressed_size)
8467 // Set the original comment to the given string
8468 $this->comment = substr($this->compressed_data, $this->position, $len);
8469 $this->position += $len + 1;
8478 if ($this->flags & 2)
8480 // Check the length of the string is still valid
8481 $this->min_compressed_size += $len + 2;
8482 if ($this->compressed_size >= $this->min_compressed_size)
8485 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8487 // Check the CRC matches
8488 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8490 $this->position += 2;
8503 // Decompress the actual data
8504 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8510 $this->position = $this->compressed_size - 8;
8513 // Check CRC of data
8514 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8515 $this->position += 4;
8516 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8521 // Check ISIZE of data
8522 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8523 $this->position += 4;
8524 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8529 // Wow, against all odds, we've actually got a valid gzip string
8539 class SimplePie_Cache
8542 * Don't call the constructor. Please.
8546 function SimplePie_Cache()
8548 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8552 * Create a new SimplePie_Cache object
8557 function create($location, $filename, $extension)
8559 return new SimplePie_Cache_File($location, $filename, $extension);
8563 class SimplePie_Cache_File
8570 function SimplePie_Cache_File($location, $filename, $extension)
8572 $this->location = $location;
8573 $this->filename = rawurlencode($filename);
8574 $this->extension = rawurlencode($extension);
8575 $this->name = "$location/$this->filename.$this->extension";
8578 function save($data)
8580 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8582 if (is_a($data, 'SimplePie'))
8584 $data = $data->data;
8587 $data = serialize($data);
8589 if (function_exists('file_put_contents'))
8591 return (bool) file_put_contents($this->name, $data);
8595 $fp = fopen($this->name, 'wb');
8609 if (file_exists($this->name) && is_readable($this->name))
8611 return unserialize(file_get_contents($this->name));
8618 if (file_exists($this->name))
8620 return filemtime($this->name);
8627 if (file_exists($this->name))
8629 return touch($this->name);
8636 if (file_exists($this->name))
8638 return unlink($this->name);
8644 class SimplePie_Misc
8646 function time_hms($seconds)
8650 $hours = floor($seconds / 3600);
8651 $remainder = $seconds % 3600;
8654 $time .= $hours.':';
8657 $minutes = floor($remainder / 60);
8658 $seconds = $remainder % 60;
8659 if ($minutes < 10 && $hours > 0)
8661 $minutes = '0' . $minutes;
8665 $seconds = '0' . $seconds;
8668 $time .= $minutes.':';
8674 function absolutize_url($relative, $base)
8676 if ($relative !== '')
8678 $relative = SimplePie_Misc::parse_url($relative);
8679 if ($relative['scheme'] !== '')
8681 $target = $relative;
8683 elseif ($base !== '')
8685 $base = SimplePie_Misc::parse_url($base);
8686 $target = SimplePie_Misc::parse_url('');
8687 if ($relative['authority'] !== '')
8689 $target = $relative;
8690 $target['scheme'] = $base['scheme'];
8694 $target['scheme'] = $base['scheme'];
8695 $target['authority'] = $base['authority'];
8696 if ($relative['path'] !== '')
8698 if (strpos($relative['path'], '/') === 0)
8700 $target['path'] = $relative['path'];
8702 elseif ($base['authority'] !== '' && $base['path'] === '')
8704 $target['path'] = '/' . $relative['path'];
8706 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8708 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8712 $target['path'] = $relative['path'];
8714 $target['query'] = $relative['query'];
8718 $target['path'] = $base['path'];
8719 if ($relative['query'] !== '')
8721 $target['query'] = $relative['query'];
8723 elseif ($base['query'] !== '')
8725 $target['query'] = $base['query'];
8729 $target['fragment'] = $relative['fragment'];
8733 // No base URL, just return the relative URL
8734 $target = $relative;
8736 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8742 $return = SimplePie_Misc::normalize_url($return);
8746 function remove_dot_segments($input)
8749 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8751 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8752 if (strpos($input, '../') === 0)
8754 $input = substr($input, 3);
8756 elseif (strpos($input, './') === 0)
8758 $input = substr($input, 2);
8760 // 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,
8761 elseif (strpos($input, '/./') === 0)
8763 $input = substr_replace($input, '/', 0, 3);
8765 elseif ($input == '/.')
8769 // 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,
8770 elseif (strpos($input, '/../') === 0)
8772 $input = substr_replace($input, '/', 0, 4);
8773 $output = substr_replace($output, '', strrpos($output, '/'));
8775 elseif ($input == '/..')
8778 $output = substr_replace($output, '', strrpos($output, '/'));
8780 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8781 elseif ($input == '.' || $input == '..')
8785 // 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
8786 elseif (($pos = strpos($input, '/', 1)) !== false)
8788 $output .= substr($input, 0, $pos);
8789 $input = substr_replace($input, '', 0, $pos);
8797 return $output . $input;
8800 function get_element($realname, $string)
8803 $name = preg_quote($realname, '/');
8804 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8806 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8808 $return[$i]['tag'] = $realname;
8809 $return[$i]['full'] = $matches[$i][0][0];
8810 $return[$i]['offset'] = $matches[$i][0][1];
8811 if (strlen($matches[$i][3][0]) <= 2)
8813 $return[$i]['self_closing'] = true;
8817 $return[$i]['self_closing'] = false;
8818 $return[$i]['content'] = $matches[$i][4][0];
8820 $return[$i]['attribs'] = array();
8821 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))
8823 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8825 if (count($attribs[$j]) == 2)
8827 $attribs[$j][2] = $attribs[$j][1];
8829 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8837 function element_implode($element)
8839 $full = "<$element[tag]";
8840 foreach ($element['attribs'] as $key => $value)
8842 $key = strtolower($key);
8843 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8845 if ($element['self_closing'])
8851 $full .= ">$element[content]</$element[tag]>";
8856 function error($message, $level, $file, $line)
8861 $note = 'PHP Error';
8863 case E_USER_WARNING:
8864 $note = 'PHP Warning';
8867 $note = 'PHP Notice';
8870 $note = 'Unknown Error';
8873 error_log("$note: $message in $file on line $line", 0);
8878 * If a file has been cached, retrieve and display it.
8880 * This is most useful for caching images (get_favicon(), etc.),
8881 * however it works for all cached files. This WILL NOT display ANY
8882 * file/image/page/whatever, but rather only display what has already
8883 * been cached by SimplePie.
8886 * @see SimplePie::get_favicon()
8887 * @param str $identifier_url URL that is used to identify the content.
8888 * This may or may not be the actual URL of the live content.
8889 * @param str $cache_location Location of SimplePie's cache. Defaults
8891 * @param str $cache_extension The file extension that the file was
8892 * cached with. Defaults to 'spc'.
8893 * @param str $cache_class Name of the cache-handling class being used
8894 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8895 * as-is unless you've overloaded the class.
8896 * @param str $cache_name_function Obsolete. Exists for backwards
8897 * compatibility reasons only.
8899 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8901 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8903 if ($file = $cache->load())
8905 if (isset($file['headers']['content-type']))
8907 header('Content-type:' . $file['headers']['content-type']);
8911 header('Content-type: application/octet-stream');
8913 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8918 die('Cached file for ' . $identifier_url . ' cannot be found.');
8921 function fix_protocol($url, $http = 1)
8923 $url = SimplePie_Misc::normalize_url($url);
8924 $parsed = SimplePie_Misc::parse_url($url);
8925 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8927 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8930 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8932 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8935 if ($http == 2 && $parsed['scheme'] !== '')
8939 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8941 return substr_replace($url, 'podcast', 0, 4);
8943 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8945 return substr_replace($url, 'itpc', 0, 4);
8953 function parse_url($url)
8955 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match);
8956 for ($i = count($match); $i <= 9; $i++)
8960 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8963 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8968 $return .= "$scheme:";
8970 if ($authority !== '')
8972 $return .= "//$authority";
8980 $return .= "?$query";
8982 if ($fragment !== '')
8984 $return .= "#$fragment";
8989 function normalize_url($url)
8991 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8992 $url = SimplePie_Misc::parse_url($url);
8993 $url['scheme'] = strtolower($url['scheme']);
8994 if ($url['authority'] !== '')
8996 $url['authority'] = strtolower($url['authority']);
8997 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8999 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
9002 function percent_encoding_normalization($match)
9004 $integer = hexdec($match[1]);
9005 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
9007 return chr($integer);
9011 return strtoupper($match[0]);
9016 * Remove bad UTF-8 bytes
9018 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9019 * FAQ: Multilingual Forms (modified to include full ASCII range)
9021 * @author Geoffrey Sneddon
9022 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9023 * @param string $str String to remove bad UTF-8 bytes from
9024 * @return string UTF-8 string
9026 function utf8_bad_replace($str)
9028 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9032 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9036 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))
9038 return implode("\xEF\xBF\xBD", $matches[0]);
9040 elseif ($str !== '')
9042 return "\xEF\xBF\xBD";
9051 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9055 * @param string $string Windows-1252 encoded string
9056 * @return string UTF-8 encoded string
9058 function windows_1252_to_utf8($string)
9060 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");
9062 return strtr($string, $convert_table);
9065 function change_encoding($data, $input, $output)
9067 $input = SimplePie_Misc::encoding($input);
9068 $output = SimplePie_Misc::encoding($output);
9070 // We fail to fail on non US-ASCII bytes
9071 if ($input === 'US-ASCII')
9073 static $non_ascii_octects = '';
9074 if (!$non_ascii_octects)
9076 for ($i = 0x80; $i <= 0xFF; $i++)
9078 $non_ascii_octects .= chr($i);
9081 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9084 // This is first, as behaviour of this is completely predictable
9085 if ($input === 'Windows-1252' && $output === 'UTF-8')
9087 return SimplePie_Misc::windows_1252_to_utf8($data);
9089 // This is second, as behaviour of this varies only with PHP version
9090 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
9094 // This is last, as behaviour of this varies with OS userland and PHP version
9095 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9099 // If we can't do anything, just fail
9106 function encoding($charset)
9108 /* Character sets are case-insensitive, and also need some further
9109 normalization in the real world (though we'll return them in the form given
9110 in their registration). */
9111 switch (strtolower(preg_replace('/[\x09-\x0D\x20-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', '', $charset)))
9113 case 'adobestandardencoding':
9114 case 'csadobestandardencoding':
9115 return 'Adobe-Standard-Encoding';
9117 case 'adobesymbolencoding':
9119 return 'Adobe-Symbol-Encoding';
9125 return 'Amiga-1251';
9127 case 'ansix31101983':
9129 case 'csiso99naplps':
9132 return 'ANSI_X3.110-1983';
9136 case 'csiso89asmo449':
9147 return 'Big5-HKSCS';
9158 case 'csiso4unitedkingdom':
9166 case 'csiso47bsviewdata':
9168 return 'BS_viewdata';
9176 case 'csaz243419851':
9177 case 'csiso121canadian1':
9180 return 'CSA_Z243.4-1985-1';
9183 case 'csaz243419852':
9184 case 'csiso122canadian2':
9187 return 'CSA_Z243.4-1985-2';
9189 case 'csaz24341985gr':
9190 case 'csiso123csaz24341985gr':
9192 return 'CSA_Z243.4-1985-gr';
9194 case 'csiso139csn369103':
9197 return 'CSN_369103';
9204 case 'csiso21german':
9215 case 'csiso646danish':
9222 case 'csibmebcdicatde':
9224 return 'EBCDIC-AT-DE';
9226 case 'csebcdicatdea':
9228 return 'EBCDIC-AT-DE-A';
9230 case 'csebcdiccafr':
9232 return 'EBCDIC-CA-FR';
9234 case 'csebcdicdkno':
9236 return 'EBCDIC-DK-NO';
9238 case 'csebcdicdknoa':
9240 return 'EBCDIC-DK-NO-A';
9248 return 'EBCDIC-ES-A';
9252 return 'EBCDIC-ES-S';
9254 case 'csebcdicfise':
9256 return 'EBCDIC-FI-SE';
9258 case 'csebcdicfisea':
9260 return 'EBCDIC-FI-SE-A';
9282 case 'csiso111ecmacyrillic':
9283 case 'ecmacyrillic':
9286 return 'ECMA-cyrillic';
9288 case 'csiso17spanish':
9294 case 'csiso85spanish2':
9300 case 'cseucfixwidjapanese':
9301 case 'extendedunixcodefixedwidthforjapanese':
9302 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9304 case 'cseucpkdfmtjapanese':
9306 case 'extendedunixcodepackedformatforjapanese':
9307 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9319 case 'csiso58gb231280':
9325 case 'csiso57gb1988':
9329 return 'GB_1988-80';
9331 case 'csiso153gost1976874':
9335 return 'GOST_19768-74';
9338 case 'csiso150greekccitt':
9341 return 'greek-ccitt';
9343 case 'csiso88greek7':
9348 case 'csiso18greek7old':
9351 return 'greek7-old';
9355 return 'HP-DeskTop';
9367 return 'HP-Pi-font';
9376 return 'HZ-GB-2312';
9378 case 'csibmsymbols':
9380 return 'IBM-Symbols';
9389 case 'pcmultilingual850euro':
9394 case 'ebcdiclatin9euro':
9400 case 'ebcdicus37euro':
9406 case 'ebcdicde273euro':
9412 case 'ebcdicdk277euro':
9413 case 'ebcdicno277euro':
9419 case 'ebcdicfi278euro':
9420 case 'ebcdicse278euro':
9426 case 'ebcdicit280euro':
9432 case 'ebcdices284euro':
9438 case 'ebcdicgb285euro':
9444 case 'ebcdicfr297euro':
9450 case 'ebcdicinternational500euro':
9456 case 'ebcdicis871euro':
9531 case 'ebcdicjpkana':
9561 case 'cspc8codepage437':
9573 case 'cspc775baltic':
9579 case 'cspc850multilingual':
9622 case 'cspc862latinhebrew':
9664 case 'ebcdiccproece':
9677 case 'ebcdiccyrillic':
9718 case 'csiso143iecp271':
9728 case 'csiso50inis8':
9733 case 'csiso51iniscyrillic':
9734 case 'iniscyrillic':
9736 return 'INIS-cyrillic';
9743 return 'ISO-2022-CN';
9745 case 'iso2022cnext':
9746 return 'ISO-2022-CN-EXT';
9750 return 'ISO-2022-JP';
9752 case 'csiso2022jp2':
9754 return 'ISO-2022-JP-2';
9758 return 'ISO-2022-KR';
9760 case 'cswindows30latin1':
9761 case 'iso88591windows30latin1':
9762 return 'ISO-8859-1-Windows-3.0-Latin-1';
9764 case 'cswindows31latin1':
9765 case 'iso88591windows31latin1':
9766 return 'ISO-8859-1-Windows-3.1-Latin-1';
9772 case 'iso885921987':
9775 return 'ISO-8859-2';
9777 case 'cswindows31latin2':
9778 case 'iso88592windowslatin2':
9779 return 'ISO-8859-2-Windows-Latin-2';
9785 case 'iso885931988':
9788 return 'ISO-8859-3';
9794 case 'iso885941988':
9797 return 'ISO-8859-4';
9799 case 'csisolatincyrillic':
9804 case 'iso885951988':
9805 return 'ISO-8859-5';
9809 case 'csisolatinarabic':
9814 case 'iso885961987':
9815 return 'ISO-8859-6';
9820 return 'ISO-8859-6-E';
9825 return 'ISO-8859-6-I';
9827 case 'csisolatingreek':
9835 case 'iso885971987':
9836 return 'ISO-8859-7';
9838 case 'csisolatinhebrew':
9843 case 'iso885981988':
9844 return 'ISO-8859-8';
9849 return 'ISO-8859-8-E';
9854 return 'ISO-8859-8-I';
9856 case 'cswindows31latin5':
9857 case 'iso88599windowslatin5':
9858 return 'ISO-8859-9-Windows-Latin-5';
9863 case 'iso8859101992':
9866 return 'ISO-8859-10';
9869 return 'ISO-8859-13';
9875 case 'iso8859141998':
9878 return 'ISO-8859-14';
9883 return 'ISO-8859-15';
9888 case 'iso8859162001':
9891 return 'ISO-8859-16';
9894 return 'ISO-10646-J-1';
9897 case 'iso10646ucs2':
9898 return 'ISO-10646-UCS-2';
9901 case 'iso10646ucs4':
9902 return 'ISO-10646-UCS-4';
9904 case 'csunicodeascii':
9905 case 'iso10646ucsbasic':
9906 return 'ISO-10646-UCS-Basic';
9908 case 'csunicodelatin1':
9910 case 'iso10646unicodelatin1':
9911 return 'ISO-10646-Unicode-Latin1';
9913 case 'csiso10646utf1':
9914 case 'iso10646utf1':
9915 return 'ISO-10646-UTF-1';
9921 return 'ISO-11548-1';
9927 case 'csunicodeibm1261':
9928 case 'isounicodeibm1261':
9929 return 'ISO-Unicode-IBM-1261';
9931 case 'csunicodeibm1264':
9932 case 'isounicodeibm1264':
9933 return 'ISO-Unicode-IBM-1264';
9935 case 'csunicodeibm1265':
9936 case 'isounicodeibm1265':
9937 return 'ISO-Unicode-IBM-1265';
9939 case 'csunicodeibm1268':
9940 case 'isounicodeibm1268':
9941 return 'ISO-Unicode-IBM-1268';
9943 case 'csunicodeibm1276':
9944 case 'isounicodeibm1276':
9945 return 'ISO-Unicode-IBM-1276';
9947 case 'csiso646basic1983':
9948 case 'iso646basic1983':
9950 return 'ISO_646.basic:1983';
9952 case 'csiso2intlrefversion':
9955 case 'iso646irv1983':
9956 return 'ISO_646.irv:1983';
9962 return 'ISO_2033-1983';
9964 case 'csiso5427cyrillic':
9970 case 'iso5427cyrillic1981':
9972 return 'ISO_5427:1981';
9974 case 'csiso5428greek':
9977 return 'ISO_5428:1980';
9979 case 'csiso6937add':
9982 return 'ISO_6937-2-25';
9984 case 'csisotextcomm':
9987 return 'ISO_6937-2-add';
9989 case 'csiso8859supp':
9993 return 'ISO_8859-supp';
9995 case 'csiso10367box':
9998 return 'ISO_10367-box';
10000 case 'csiso15italian':
10006 case 'csiso13jisc6220jp':
10008 case 'jisc62201969':
10009 case 'jisc62201969jp':
10012 return 'JIS_C6220-1969-jp';
10014 case 'csiso14jisc6220ro':
10017 case 'jisc62201969ro':
10019 return 'JIS_C6220-1969-ro';
10021 case 'csiso42jisc62261978':
10023 case 'jisc62261978':
10024 return 'JIS_C6226-1978';
10026 case 'csiso87jisx0208':
10028 case 'jisc62261983':
10029 case 'jisx02081983':
10031 return 'JIS_C6226-1983';
10033 case 'csiso91jisc62291984a':
10035 case 'jisc62291984a':
10037 return 'JIS_C6229-1984-a';
10039 case 'csiso92jisc62991984b':
10041 case 'iso646jpocrb':
10042 case 'jisc62291984b':
10044 return 'JIS_C6229-1984-b';
10046 case 'csiso93jis62291984badd':
10048 case 'jisc62291984badd':
10050 return 'JIS_C6229-1984-b-add';
10052 case 'csiso94jis62291984hand':
10054 case 'jisc62291984hand':
10056 return 'JIS_C6229-1984-hand';
10058 case 'csiso95jis62291984handadd':
10060 case 'jisc62291984handadd':
10061 case 'jpocrhandadd':
10062 return 'JIS_C6229-1984-hand-add';
10064 case 'csiso96jisc62291984kana':
10066 case 'jisc62291984kana':
10067 return 'JIS_C6229-1984-kana';
10069 case 'csjisencoding':
10070 case 'jisencoding':
10071 return 'JIS_Encoding';
10073 case 'cshalfwidthkatakana':
10076 return 'JIS_X0201';
10078 case 'csiso159jisx02121990':
10080 case 'jisx02121990':
10082 return 'JIS_X0212-1990';
10084 case 'csiso141jusib1002':
10090 return 'JUS_I.B1.002';
10092 case 'csiso147macedonian':
10094 case 'jusib1003mac':
10096 return 'JUS_I.B1.003-mac';
10098 case 'csiso146serbian':
10100 case 'jusib1003serb':
10102 return 'JUS_I.B1.003-serb';
10104 case 'koi7switched':
10105 return 'KOI7-switched';
10122 case 'strk10482002':
10125 case 'csiso19latingreek':
10128 return 'latin-greek';
10130 case 'csiso27latingreek1':
10132 case 'latingreek1':
10133 return 'Latin-greek-1';
10135 case 'csiso158lap':
10139 return 'latin-lap';
10141 case 'csmacintosh':
10144 return 'macintosh';
10146 case 'csmicrosoftpublishing':
10147 case 'microsoftpublishing':
10148 return 'Microsoft-Publishing';
10158 case 'csiso86hungarian':
10163 return 'MSZ_7795.3';
10168 return 'NATS-DANO';
10170 case 'csnatsdanoadd':
10172 case 'natsdanoadd':
10173 return 'NATS-DANO-ADD';
10178 return 'NATS-SEFI';
10180 case 'csnatssefiadd':
10182 case 'natssefiadd':
10183 return 'NATS-SEFI-ADD';
10185 case 'csiso151cuba':
10190 return 'NC_NC00-10:81';
10192 case 'csiso69french':
10197 return 'NF_Z_62-010';
10199 case 'csiso25french':
10202 case 'nfz620101973':
10203 return 'NF_Z_62-010_(1973)';
10205 case 'csiso60danishnorwegian':
10206 case 'csiso60norwegian1':
10211 return 'NS_4551-1';
10213 case 'csiso61norwegian2':
10218 return 'NS_4551-2';
10220 case 'osdebcdicdf03irv':
10221 return 'OSD_EBCDIC_DF03_IRV';
10223 case 'osdebcdicdf041':
10224 return 'OSD_EBCDIC_DF04_1';
10226 case 'osdebcdicdf0415':
10227 return 'OSD_EBCDIC_DF04_15';
10229 case 'cspc8danishnorwegian':
10230 case 'pc8danishnorwegian':
10231 return 'PC8-Danish-Norwegian';
10233 case 'cspc8turkish':
10235 return 'PC8-Turkish';
10237 case 'csiso16portuguese':
10243 case 'csiso84portuguese2':
10251 case 'cyrillicasian':
10259 case 'csiso10swedish':
10266 return 'SEN_850200_B';
10268 case 'csiso11swedishfornames':
10273 return 'SEN_850200_C';
10278 return 'Shift_JIS';
10280 case 'csiso102t617bit':
10283 return 'T.61-7bit';
10285 case 'csiso103t618bit':
10289 return 'T.61-8bit';
10291 case 'csiso128t101g2':
10300 case 'csunicode11':
10302 return 'UNICODE-1-1';
10304 case 'csunicode11utf7':
10305 case 'unicode11utf7':
10306 return 'UNICODE-1-1-UTF-7';
10308 case 'csunknown8bit':
10309 case 'unknown8bit':
10310 return 'UNKNOWN-8BIT';
10312 case 'ansix341968':
10313 case 'ansix341986':
10320 case 'iso646irv1991':
10353 case 'csventurainternational':
10354 case 'venturainternational':
10355 return 'Ventura-International';
10357 case 'csventuramath':
10358 case 'venturamath':
10359 return 'Ventura-Math';
10361 case 'csventuraus':
10363 return 'Ventura-US';
10365 case 'csiso70videotexsupp1':
10367 case 'videotexsuppl':
10368 return 'videotex-suppl';
10378 case 'cswindows31j':
10380 return 'Windows-31J';
10384 return 'Windows-874';
10389 case 'csksc56011987':
10393 case 'ksc56011987':
10394 case 'ksc56011989':
10395 return 'Windows-949';
10397 case 'windows1250':
10398 return 'windows-1250';
10400 case 'windows1251':
10401 return 'windows-1251';
10404 case 'csisolatin1':
10408 case 'iso885911987':
10411 case 'windows1252':
10412 return 'Windows-1252';
10414 case 'windows1252':
10415 return 'windows-1252';
10417 case 'windows1253':
10418 return 'windows-1253';
10420 case 'csisolatin5':
10423 case 'iso885991989':
10426 case 'windows1254':
10427 return 'Windows-1254';
10429 case 'windows1254':
10430 return 'windows-1254';
10432 case 'windows1255':
10433 return 'windows-1255';
10435 case 'windows1256':
10436 return 'windows-1256';
10438 case 'windows1257':
10439 return 'windows-1257';
10441 case 'windows1258':
10442 return 'windows-1258';
10449 function get_curl_version()
10451 if (is_array($curl = curl_version()))
10453 $curl = $curl['version'];
10455 elseif (substr($curl, 0, 5) == 'curl/')
10457 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10459 elseif (substr($curl, 0, 8) == 'libcurl/')
10461 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10470 function is_subclass_of($class1, $class2)
10472 if (func_num_args() != 2)
10474 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10476 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10478 return is_subclass_of($class1, $class2);
10480 elseif (is_string($class1) && is_string($class2))
10482 if (class_exists($class1))
10484 if (class_exists($class2))
10486 $class2 = strtolower($class2);
10487 while ($class1 = strtolower(get_parent_class($class1)))
10489 if ($class1 == $class2)
10498 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10505 * Strip HTML comments
10508 * @param string $data Data to strip comments from
10509 * @return string Comment stripped string
10511 function strip_comments($data)
10514 while (($start = strpos($data, '<!--')) !== false)
10516 $output .= substr($data, 0, $start);
10517 if (($end = strpos($data, '-->', $start)) !== false)
10519 $data = substr_replace($data, '', 0, $end + 3);
10526 return $output . $data;
10529 function parse_date($dt)
10531 $parser = SimplePie_Parse_Date::get();
10532 return $parser->parse($dt);
10536 * Decode HTML entities
10540 * @param string $data Input data
10541 * @return string Output data
10543 function entities_decode($data)
10545 $decoder =& new SimplePie_Decode_HTML_Entities($data);
10546 return $decoder->parse();
10550 * Remove RFC822 comments
10553 * @param string $data Data to strip comments from
10554 * @return string Comment stripped string
10556 function uncomment_rfc822($string)
10558 $string = (string) $string;
10560 $length = strlen($string);
10565 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10567 $output .= substr($string, $position, $pos - $position);
10568 $position = $pos + 1;
10569 if ($string[$pos - 1] !== '\\')
10572 while ($depth && $position < $length)
10574 $position += strcspn($string, '()', $position);
10575 if ($string[$position - 1] === '\\')
10580 elseif (isset($string[$position]))
10582 switch ($string[$position])
10605 $output .= substr($string, $position);
10610 function parse_mime($mime)
10612 if (($pos = strpos($mime, ';')) === false)
10614 return trim($mime);
10618 return trim(substr($mime, 0, $pos));
10622 function htmlspecialchars_decode($string, $quote_style)
10624 if (function_exists('htmlspecialchars_decode'))
10626 return htmlspecialchars_decode($string, $quote_style);
10630 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10634 function atom_03_construct_type($attribs)
10636 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10638 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10642 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10644 if (isset($attribs['']['type']))
10646 switch (strtolower(trim($attribs['']['type'])))
10650 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10654 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10657 case 'application/xhtml+xml':
10658 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10661 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10666 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10670 function atom_10_construct_type($attribs)
10672 if (isset($attribs['']['type']))
10674 switch (strtolower(trim($attribs['']['type'])))
10677 return SIMPLEPIE_CONSTRUCT_TEXT;
10680 return SIMPLEPIE_CONSTRUCT_HTML;
10683 return SIMPLEPIE_CONSTRUCT_XHTML;
10686 return SIMPLEPIE_CONSTRUCT_NONE;
10689 return SIMPLEPIE_CONSTRUCT_TEXT;
10692 function atom_10_content_construct_type($attribs)
10694 if (isset($attribs['']['type']))
10696 $type = strtolower(trim($attribs['']['type']));
10700 return SIMPLEPIE_CONSTRUCT_TEXT;
10703 return SIMPLEPIE_CONSTRUCT_HTML;
10706 return SIMPLEPIE_CONSTRUCT_XHTML;
10708 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10710 return SIMPLEPIE_CONSTRUCT_NONE;
10714 return SIMPLEPIE_CONSTRUCT_BASE64;
10719 return SIMPLEPIE_CONSTRUCT_TEXT;
10723 function is_isegment_nz_nc($string)
10725 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);
10728 function space_seperated_tokens($string)
10730 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10731 $string_length = strlen($string);
10733 $position = strspn($string, $space_characters);
10736 while ($position < $string_length)
10738 $len = strcspn($string, $space_characters, $position);
10739 $tokens[] = substr($string, $position, $len);
10741 $position += strspn($string, $space_characters, $position);
10747 function array_unique($array)
10749 if (version_compare(PHP_VERSION, '5.2', '>='))
10751 return array_unique($array);
10755 $array = (array) $array;
10756 $new_array = array();
10757 $new_array_strings = array();
10758 foreach ($array as $key => $value)
10760 if (is_object($value))
10762 if (method_exists($value, '__toString'))
10764 $cmp = $value->__toString();
10768 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10771 elseif (is_array($value))
10773 $cmp = (string) reset($value);
10777 $cmp = (string) $value;
10779 if (!in_array($cmp, $new_array_strings))
10781 $new_array[$key] = $value;
10782 $new_array_strings[] = $cmp;
10790 * Converts a unicode codepoint to a UTF-8 character
10794 * @param int $codepoint Unicode codepoint
10795 * @return string UTF-8 character
10797 function codepoint_to_utf8($codepoint)
10799 $codepoint = (int) $codepoint;
10800 if ($codepoint < 0)
10804 else if ($codepoint <= 0x7f)
10806 return chr($codepoint);
10808 else if ($codepoint <= 0x7ff)
10810 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10812 else if ($codepoint <= 0xffff)
10814 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10816 else if ($codepoint <= 0x10ffff)
10818 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10822 // U+FFFD REPLACEMENT CHARACTER
10823 return "\xEF\xBF\xBD";
10828 * Re-implementation of PHP 5's stripos()
10830 * Returns the numeric position of the first occurrence of needle in the
10835 * @param object $haystack
10836 * @param string $needle Note that the needle may be a string of one or more
10837 * characters. If needle is not a string, it is converted to an integer
10838 * and applied as the ordinal value of a character.
10839 * @param int $offset The optional offset parameter allows you to specify which
10840 * character in haystack to start searching. The position returned is still
10841 * relative to the beginning of haystack.
10842 * @return bool If needle is not found, stripos() will return boolean false.
10844 function stripos($haystack, $needle, $offset = 0)
10846 if (function_exists('stripos'))
10848 return stripos($haystack, $needle, $offset);
10852 if (is_string($needle))
10854 $needle = strtolower($needle);
10856 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10858 $needle = strtolower(chr($needle));
10862 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10866 return strpos(strtolower($haystack), $needle, $offset);
10871 * Similar to parse_str()
10873 * Returns an associative array of name/value pairs, where the value is an
10874 * array of values that have used the same name
10878 * @param string $str The input string.
10881 function parse_str($str)
10884 $str = explode('&', $str);
10886 foreach ($str as $section)
10888 if (strpos($section, '=') !== false)
10890 list($name, $value) = explode('=', $section, 2);
10891 $return[urldecode($name)][] = urldecode($value);
10895 $return[urldecode($section)][] = null;
10903 * Detect XML encoding, as per XML 1.0 Appendix F.1
10905 * @todo Add support for EBCDIC
10906 * @param string $data XML data
10907 * @return array Possible encodings
10909 function xml_encoding($data)
10911 // UTF-32 Big Endian BOM
10912 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10914 $encoding[] = 'UTF-32BE';
10916 // UTF-32 Little Endian BOM
10917 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10919 $encoding[] = 'UTF-32LE';
10921 // UTF-16 Big Endian BOM
10922 elseif (substr($data, 0, 2) === "\xFE\xFF")
10924 $encoding[] = 'UTF-16BE';
10926 // UTF-16 Little Endian BOM
10927 elseif (substr($data, 0, 2) === "\xFF\xFE")
10929 $encoding[] = 'UTF-16LE';
10932 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10934 $encoding[] = 'UTF-8';
10936 // UTF-32 Big Endian Without BOM
10937 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")
10939 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10941 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10942 if ($parser->parse())
10944 $encoding[] = $parser->encoding;
10947 $encoding[] = 'UTF-32BE';
10949 // UTF-32 Little Endian Without BOM
10950 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")
10952 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10954 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10955 if ($parser->parse())
10957 $encoding[] = $parser->encoding;
10960 $encoding[] = 'UTF-32LE';
10962 // UTF-16 Big Endian Without BOM
10963 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10965 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10967 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10968 if ($parser->parse())
10970 $encoding[] = $parser->encoding;
10973 $encoding[] = 'UTF-16BE';
10975 // UTF-16 Little Endian Without BOM
10976 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10978 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10980 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10981 if ($parser->parse())
10983 $encoding[] = $parser->encoding;
10986 $encoding[] = 'UTF-16LE';
10988 // US-ASCII (or superset)
10989 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10991 if ($pos = strpos($data, "\x3F\x3E"))
10993 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10994 if ($parser->parse())
10996 $encoding[] = $parser->encoding;
10999 $encoding[] = 'UTF-8';
11001 // Fallback to UTF-8
11004 $encoding[] = 'UTF-8';
11011 * Decode HTML Entities
11013 * This implements HTML5 as of revision 967 (2007-06-28)
11015 * @package SimplePie
11017 class SimplePie_Decode_HTML_Entities
11020 * Data to be parsed
11028 * Currently consumed bytes
11033 var $consumed = '';
11036 * Position of the current byte being parsed
11044 * Create an instance of the class with the input data
11047 * @param string $data Input data
11049 function SimplePie_Decode_HTML_Entities($data)
11051 $this->data = $data;
11055 * Parse the input data
11058 * @return string Output data
11062 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11066 $this->consumed = '';
11068 return $this->data;
11072 * Consume the next byte
11075 * @return mixed The next byte, or false, if there is no more data
11079 if (isset($this->data[$this->position]))
11081 $this->consumed .= $this->data[$this->position];
11082 return $this->data[$this->position++];
11086 $this->consumed = false;
11092 * Consume a range of characters
11095 * @param string $chars Characters to consume
11096 * @return mixed A series of characters that match the range, or false
11098 function consume_range($chars)
11100 if ($len = strspn($this->data, $chars, $this->position))
11102 $data = substr($this->data, $this->position, $len);
11103 $this->consumed .= $data;
11104 $this->position += $len;
11109 $this->consumed = false;
11115 * Unconsume one byte
11119 function unconsume()
11121 $this->consumed = substr($this->consumed, 0, -1);
11132 switch ($this->consume())
11146 switch ($this->consume())
11150 $range = '0123456789ABCDEFabcdef';
11155 $range = '0123456789';
11157 $this->unconsume();
11161 if ($codepoint = $this->consume_range($range))
11163 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");
11167 $codepoint = hexdec($codepoint);
11171 $codepoint = intval($codepoint);
11174 if (isset($windows_1252_specials[$codepoint]))
11176 $replacement = $windows_1252_specials[$codepoint];
11180 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11183 if ($this->consume() != ';')
11185 $this->unconsume();
11188 $consumed_length = strlen($this->consumed);
11189 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11190 $this->position += strlen($replacement) - $consumed_length;
11195 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");
11197 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11199 $consumed = substr($this->consumed, 1);
11200 if (isset($entities[$consumed]))
11202 $match = $consumed;
11206 if ($match !== null)
11208 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11209 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11219 * @package SimplePie
11221 class SimplePie_Parse_Date
11226 * @access protected
11232 * List of days, calendar day name => ordinal day number in the week
11234 * @access protected
11297 'keskiviikko' => 3,
11321 * List of months, calendar month name => calendar month number
11323 * @access protected
11326 var $month = array(
11337 // No long form of May
11466 * List of timezones, abbreviation => offset from UTC
11468 * @access protected
11471 var $timezone = array(
11674 * Cached PCRE for SimplePie_Parse_Date::$day
11676 * @access protected
11682 * Cached PCRE for SimplePie_Parse_Date::$month
11684 * @access protected
11690 * Array of user-added callback methods
11695 var $built_in = array();
11698 * Array of user-added callback methods
11703 var $user = array();
11706 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11707 * self::month_pcre, and self::built_in
11711 function SimplePie_Parse_Date()
11713 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11714 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11717 if (!isset($cache[get_class($this)]))
11719 $all_methods = get_class_methods($this);
11721 foreach ($all_methods as $method)
11723 if (strtolower(substr($method, 0, 5)) === 'date_')
11725 $cache[get_class($this)][] = $method;
11730 foreach ($cache[get_class($this)] as $method)
11732 $this->built_in[] = $method;
11746 $object =& new SimplePie_Parse_Date;
11756 * @param string $date Date to parse
11757 * @return int Timestamp corresponding to date string, or false on failure
11759 function parse($date)
11761 foreach ($this->user as $method)
11763 if (($returned = call_user_func($method, $date)) !== false)
11769 foreach ($this->built_in as $method)
11771 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11781 * Add a callback method to parse a date
11785 * @param callback $callback
11787 function add_callback($callback)
11789 if (is_callable($callback))
11791 $this->user[] = $callback;
11795 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11800 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11801 * well as allowing any of upper or lower case "T", horizontal tabs, or
11802 * spaces to be used as the time seperator (including more than one))
11804 * @access protected
11805 * @return int Timestamp
11807 function date_w3cdtf($date)
11812 $year = '([0-9]{4})';
11813 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11814 $decimal = '([0-9]*)';
11815 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11816 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11818 if (preg_match($pcre, $date, $match))
11821 Capturing subpatterns:
11828 7: Decimal fraction of a second
11832 11: Timezone minutes
11835 // Fill in empty matches
11836 for ($i = count($match); $i <= 3; $i++)
11841 for ($i = count($match); $i <= 7; $i++)
11846 // Numeric timezone
11847 if (isset($match[9]) && $match[9] !== '')
11849 $timezone = $match[10] * 3600;
11850 $timezone += $match[11] * 60;
11851 if ($match[9] === '-')
11853 $timezone = 0 - $timezone;
11861 // Convert the number of seconds to an integer, taking decimals into account
11862 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11864 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11873 * Remove RFC822 comments
11875 * @access protected
11876 * @param string $data Data to strip comments from
11877 * @return string Comment stripped string
11879 function remove_rfc2822_comments($string)
11881 $string = (string) $string;
11883 $length = strlen($string);
11888 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11890 $output .= substr($string, $position, $pos - $position);
11891 $position = $pos + 1;
11892 if ($string[$pos - 1] !== '\\')
11895 while ($depth && $position < $length)
11897 $position += strcspn($string, '()', $position);
11898 if ($string[$position - 1] === '\\')
11903 elseif (isset($string[$position]))
11905 switch ($string[$position])
11928 $output .= substr($string, $position);
11934 * Parse RFC2822's date format
11936 * @access protected
11937 * @return int Timestamp
11939 function date_rfc2822($date)
11944 $wsp = '[\x09\x20]';
11945 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11946 $optional_fws = $fws . '?';
11947 $day_name = $this->day_pcre;
11948 $month = $this->month_pcre;
11949 $day = '([0-9]{1,2})';
11950 $hour = $minute = $second = '([0-9]{2})';
11951 $year = '([0-9]{2,4})';
11952 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11953 $character_zone = '([A-Z]{1,5})';
11954 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11955 $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';
11957 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11960 Capturing subpatterns:
11970 10: Timezone minutes
11971 11: Alphabetic timezone
11974 // Find the month number
11975 $month = $this->month[strtolower($match[3])];
11977 // Numeric timezone
11978 if ($match[8] !== '')
11980 $timezone = $match[9] * 3600;
11981 $timezone += $match[10] * 60;
11982 if ($match[8] === '-')
11984 $timezone = 0 - $timezone;
11987 // Character timezone
11988 elseif (isset($this->timezone[strtoupper($match[11])]))
11990 $timezone = $this->timezone[strtoupper($match[11])];
11992 // Assume everything else to be -0000
11998 // Deal with 2/3 digit years
11999 if ($match[4] < 50)
12003 elseif ($match[4] < 1000)
12008 // Second is optional, if it is empty set it to zero
12009 if ($match[7] !== '')
12011 $second = $match[7];
12018 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12027 * Parse RFC850's date format
12029 * @access protected
12030 * @return int Timestamp
12032 function date_rfc850($date)
12037 $space = '[\x09\x20]+';
12038 $day_name = $this->day_pcre;
12039 $month = $this->month_pcre;
12040 $day = '([0-9]{1,2})';
12041 $year = $hour = $minute = $second = '([0-9]{2})';
12042 $zone = '([A-Z]{1,5})';
12043 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12045 if (preg_match($pcre, $date, $match))
12048 Capturing subpatterns:
12060 $month = $this->month[strtolower($match[3])];
12062 // Character timezone
12063 if (isset($this->timezone[strtoupper($match[8])]))
12065 $timezone = $this->timezone[strtoupper($match[8])];
12067 // Assume everything else to be -0000
12073 // Deal with 2 digit year
12074 if ($match[4] < 50)
12083 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12092 * Parse C99's asctime()'s date format
12094 * @access protected
12095 * @return int Timestamp
12097 function date_asctime($date)
12102 $space = '[\x09\x20]+';
12103 $wday_name = $this->day_pcre;
12104 $mon_name = $this->month_pcre;
12105 $day = '([0-9]{1,2})';
12106 $hour = $sec = $min = '([0-9]{2})';
12107 $year = '([0-9]{4})';
12108 $terminator = '\x0A?\x00?';
12109 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12111 if (preg_match($pcre, $date, $match))
12114 Capturing subpatterns:
12124 $month = $this->month[strtolower($match[2])];
12125 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12134 * Parse dates using strtotime()
12136 * @access protected
12137 * @return int Timestamp
12139 function date_strtotime($date)
12141 $strtotime = strtotime($date);
12142 if ($strtotime === -1 || $strtotime === false)
12154 * Content-type sniffing
12156 * @package SimplePie
12158 class SimplePie_Content_Type_Sniffer
12163 * @var SimplePie_File
12169 * Create an instance of the class with the input file
12172 * @param SimplePie_Content_Type_Sniffer $file Input file
12174 function SimplePie_Content_Type_Sniffer($file)
12176 $this->file = $file;
12180 * Get the Content-Type of the specified file
12183 * @return string Actual Content-Type
12185 function get_type()
12187 if (isset($this->file->headers['content-type']))
12189 if (!isset($this->file->headers['content-encoding'])
12190 && ($this->file->headers['content-type'] === 'text/plain'
12191 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
12192 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
12194 return $this->text_or_binary();
12197 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
12199 $official = substr($this->file->headers['content-type'], 0, $pos);
12203 $official = $this->file->headers['content-type'];
12205 $official = strtolower($official);
12207 if ($official === 'unknown/unknown'
12208 || $official === 'application/unknown')
12210 return $this->unknown();
12212 elseif (substr($official, -4) === '+xml'
12213 || $official === 'text/xml'
12214 || $official === 'application/xml')
12218 elseif (substr($official, 0, 6) === 'image/')
12220 if ($return = $this->image())
12229 elseif ($official === 'text/html')
12231 return $this->feed_or_html();
12240 return $this->unknown();
12245 * Sniff text or binary
12248 * @return string Actual Content-Type
12250 function text_or_binary()
12252 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
12253 || substr($this->file->body, 0, 2) === "\xFF\xFE"
12254 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
12255 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
12257 return 'text/plain';
12259 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
12261 return 'application/octect-stream';
12265 return 'text/plain';
12273 * @return string Actual Content-Type
12277 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
12278 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
12279 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
12280 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
12282 return 'text/html';
12284 elseif (substr($this->file->body, 0, 5) === '%PDF-')
12286 return 'application/pdf';
12288 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
12290 return 'application/postscript';
12292 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
12293 || substr($this->file->body, 0, 6) === 'GIF89a')
12295 return 'image/gif';
12297 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12299 return 'image/png';
12301 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12303 return 'image/jpeg';
12305 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12307 return 'image/bmp';
12311 return $this->text_or_binary();
12319 * @return string Actual Content-Type
12323 if (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';
12350 * @return string Actual Content-Type
12352 function feed_or_html()
12354 $len = strlen($this->file->body);
12355 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12357 while ($pos < $len)
12359 switch ($this->file->body[$pos])
12365 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12373 return 'text/html';
12376 if (substr($this->file->body, $pos, 3) === '!--')
12379 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12385 return 'text/html';
12388 elseif (substr($this->file->body, $pos, 1) === '!')
12390 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12396 return 'text/html';
12399 elseif (substr($this->file->body, $pos, 1) === '?')
12401 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12407 return 'text/html';
12410 elseif (substr($this->file->body, $pos, 3) === 'rss'
12411 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12413 return 'application/rss+xml';
12415 elseif (substr($this->file->body, $pos, 4) === 'feed')
12417 return 'application/atom+xml';
12421 return 'text/html';
12425 return 'text/html';
12430 * Parses the XML Declaration
12432 * @package SimplePie
12434 class SimplePie_XML_Declaration_Parser
12442 var $version = '1.0';
12450 var $encoding = 'UTF-8';
12458 var $standalone = false;
12461 * Current state of the state machine
12466 var $state = 'before_version_name';
12477 * Input data length (to avoid calling strlen() everytime this is needed)
12482 var $data_length = 0;
12485 * Current position of the pointer
12493 * Create an instance of the class with the input data
12496 * @param string $data Input data
12498 function SimplePie_XML_Declaration_Parser($data)
12500 $this->data = $data;
12501 $this->data_length = strlen($this->data);
12505 * Parse the input data
12508 * @return bool true on success, false on failure
12512 while ($this->state && $this->state !== 'emit' && $this->has_data())
12514 $state = $this->state;
12518 if ($this->state === 'emit')
12524 $this->version = '';
12525 $this->encoding = '';
12526 $this->standalone = '';
12532 * Check whether there is data beyond the pointer
12535 * @return bool true if there is further data, false if not
12537 function has_data()
12539 return (bool) ($this->position < $this->data_length);
12543 * Advance past any whitespace
12545 * @return int Number of whitespace characters passed
12547 function skip_whitespace()
12549 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12550 $this->position += $whitespace;
12551 return $whitespace;
12557 function get_value()
12559 $quote = substr($this->data, $this->position, 1);
12560 if ($quote === '"' || $quote === "'")
12563 $len = strcspn($this->data, $quote, $this->position);
12564 if ($this->has_data())
12566 $value = substr($this->data, $this->position, $len);
12567 $this->position += $len + 1;
12574 function before_version_name()
12576 if ($this->skip_whitespace())
12578 $this->state = 'version_name';
12582 $this->state = false;
12586 function version_name()
12588 if (substr($this->data, $this->position, 7) === 'version')
12590 $this->position += 7;
12591 $this->skip_whitespace();
12592 $this->state = 'version_equals';
12596 $this->state = false;
12600 function version_equals()
12602 if (substr($this->data, $this->position, 1) === '=')
12605 $this->skip_whitespace();
12606 $this->state = 'version_value';
12610 $this->state = false;
12614 function version_value()
12616 if ($this->version = $this->get_value())
12618 $this->skip_whitespace();
12619 if ($this->has_data())
12621 $this->state = 'encoding_name';
12625 $this->state = 'emit';
12630 $this->state = 'standalone_name';
12634 function encoding_name()
12636 if (substr($this->data, $this->position, 8) === 'encoding')
12638 $this->position += 8;
12639 $this->skip_whitespace();
12640 $this->state = 'encoding_equals';
12644 $this->state = false;
12648 function encoding_equals()
12650 if (substr($this->data, $this->position, 1) === '=')
12653 $this->skip_whitespace();
12654 $this->state = 'encoding_value';
12658 $this->state = false;
12662 function encoding_value()
12664 if ($this->encoding = $this->get_value())
12666 $this->skip_whitespace();
12667 if ($this->has_data())
12669 $this->state = 'standalone_name';
12673 $this->state = 'emit';
12678 $this->state = false;
12682 function standalone_name()
12684 if (substr($this->data, $this->position, 10) === 'standalone')
12686 $this->position += 10;
12687 $this->skip_whitespace();
12688 $this->state = 'standalone_equals';
12692 $this->state = false;
12696 function standalone_equals()
12698 if (substr($this->data, $this->position, 1) === '=')
12701 $this->skip_whitespace();
12702 $this->state = 'standalone_value';
12706 $this->state = false;
12710 function standalone_value()
12712 if ($standalone = $this->get_value())
12714 switch ($standalone)
12717 $this->standalone = true;
12721 $this->standalone = false;
12725 $this->state = false;
12729 $this->skip_whitespace();
12730 if ($this->has_data())
12732 $this->state = false;
12736 $this->state = 'emit';
12741 $this->state = false;
12746 class SimplePie_Locator
12751 var $local = array();
12752 var $elsewhere = array();
12753 var $file_class = 'SimplePie_File';
12754 var $cached_entities = array();
12757 var $base_location = 0;
12758 var $checked_feeds = 0;
12759 var $max_checked_feeds = 10;
12760 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12762 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12764 $this->file =& $file;
12765 $this->file_class = $file_class;
12766 $this->useragent = $useragent;
12767 $this->timeout = $timeout;
12768 $this->max_checked_feeds = $max_checked_feeds;
12769 $this->content_type_sniffer_class = $content_type_sniffer_class;
12772 function find($type = SIMPLEPIE_LOCATOR_ALL)
12774 if ($this->is_feed($this->file))
12776 return $this->file;
12779 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12781 $sniffer =& new $this->content_type_sniffer_class($this->file);
12782 if ($sniffer->get_type() !== 'text/html')
12788 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12793 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12798 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12800 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12805 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12810 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12815 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12823 function is_feed(&$file)
12825 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12827 $sniffer =& new $this->content_type_sniffer_class($file);
12828 $sniffed = $sniffer->get_type();
12829 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
12838 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12848 function get_base()
12850 $this->http_base = $this->file->url;
12851 $this->base = $this->http_base;
12852 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12853 foreach ($elements as $element)
12855 if ($element['attribs']['href']['data'] !== '')
12857 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12858 $this->base_location = $element['offset'];
12864 function autodiscovery()
12866 $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));
12868 foreach ($links as $link)
12870 if ($this->checked_feeds == $this->max_checked_feeds)
12874 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12876 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12878 if ($this->base_location < $link['offset'])
12880 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12884 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12887 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'))))
12889 $this->checked_feeds++;
12890 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12891 if ($this->is_feed($feed))
12902 function get_links()
12904 $links = SimplePie_Misc::get_element('a', $this->file->body);
12905 foreach ($links as $link)
12907 if (isset($link['attribs']['href']['data']))
12909 $href = trim($link['attribs']['href']['data']);
12910 $parsed = SimplePie_Misc::parse_url($href);
12911 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12913 if ($this->base_location < $link['offset'])
12915 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12919 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12922 $current = SimplePie_Misc::parse_url($this->file->url);
12924 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12926 $this->local[] = $href;
12930 $this->elsewhere[] = $href;
12935 $this->local = array_unique($this->local);
12936 $this->elsewhere = array_unique($this->elsewhere);
12937 if (!empty($this->local) || !empty($this->elsewhere))
12944 function extension(&$array)
12946 foreach ($array as $key => $value)
12948 if ($this->checked_feeds == $this->max_checked_feeds)
12952 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12954 $this->checked_feeds++;
12955 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12956 if ($this->is_feed($feed))
12962 unset($array[$key]);
12969 function body(&$array)
12971 foreach ($array as $key => $value)
12973 if ($this->checked_feeds == $this->max_checked_feeds)
12977 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12979 $this->checked_feeds++;
12980 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12981 if ($this->is_feed($feed))
12987 unset($array[$key]);
12995 class SimplePie_Parser
13000 var $current_column;
13002 var $separator = ' ';
13004 var $namespace = array('');
13005 var $element = array('');
13006 var $xml_base = array('');
13007 var $xml_base_explicit = array(false);
13008 var $xml_lang = array('');
13009 var $data = array();
13010 var $datas = array(array());
13011 var $current_xhtml_construct = -1;
13014 function parse(&$data, $encoding)
13016 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13017 if (strtoupper($encoding) == 'US-ASCII')
13019 $this->encoding = 'UTF-8';
13023 $this->encoding = $encoding;
13027 // UTF-32 Big Endian BOM
13028 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13030 $data = substr($data, 4);
13032 // UTF-32 Little Endian BOM
13033 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13035 $data = substr($data, 4);
13037 // UTF-16 Big Endian BOM
13038 elseif (substr($data, 0, 2) === "\xFE\xFF")
13040 $data = substr($data, 2);
13042 // UTF-16 Little Endian BOM
13043 elseif (substr($data, 0, 2) === "\xFF\xFE")
13045 $data = substr($data, 2);
13048 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13050 $data = substr($data, 3);
13053 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13055 $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13056 if ($declaration->parse())
13058 $data = substr($data, $pos + 2);
13059 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
13063 $this->error_string = 'SimplePie bug! Please report this!';
13068 // Work around libxml bug
13069 $data = str_replace('<', '<', $data);
13070 $data = str_replace('>', '>', $data);
13071 $data = str_replace('&', '&', $data);
13072 $data = str_replace(''', ''', $data);
13073 $data = str_replace('"', '"', $data);
13077 // Create the parser
13078 $xml = xml_parser_create_ns($this->encoding, $this->separator);
13079 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
13080 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
13081 xml_set_object($xml, $this);
13082 xml_set_character_data_handler($xml, 'cdata');
13083 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13086 if (!xml_parse($xml, $data, true))
13088 $this->error_code = xml_get_error_code($xml);
13089 $this->error_string = xml_error_string($this->error_code);
13092 $this->current_line = xml_get_current_line_number($xml);
13093 $this->current_column = xml_get_current_column_number($xml);
13094 $this->current_byte = xml_get_current_byte_index($xml);
13095 xml_parser_free($xml);
13099 function get_error_code()
13101 return $this->error_code;
13104 function get_error_string()
13106 return $this->error_string;
13109 function get_current_line()
13111 return $this->current_line;
13114 function get_current_column()
13116 return $this->current_column;
13119 function get_current_byte()
13121 return $this->current_byte;
13124 function get_data()
13126 return $this->data;
13129 function tag_open($parser, $tag, $attributes)
13131 if ($this->feed === 0)
13135 elseif ($this->feed == false)
13137 if (in_array($tag, array(
13138 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
13139 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
13141 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
13152 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
13154 $attribs = array();
13155 foreach ($attributes as $name => $value)
13157 list($attrib_namespace, $attribute) = $this->split_ns($name);
13158 $attribs[$attrib_namespace][$attribute] = $value;
13161 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
13163 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
13164 $this->xml_base_explicit[] = true;
13168 $this->xml_base[] = end($this->xml_base);
13169 $this->xml_base_explicit[] = end($this->xml_base_explicit);
13172 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
13174 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
13178 $this->xml_lang[] = end($this->xml_lang);
13181 if ($this->current_xhtml_construct >= 0)
13183 $this->current_xhtml_construct++;
13184 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
13186 $this->data['data'] .= '<' . end($this->element);
13187 if (isset($attribs['']))
13189 foreach ($attribs[''] as $name => $value)
13191 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
13194 $this->data['data'] .= '>';
13199 $this->datas[] =& $this->data;
13200 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
13201 $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));
13202 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')
13203 || (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'))
13205 $this->current_xhtml_construct = 0;
13210 function cdata($parser, $cdata)
13212 if ($this->current_xhtml_construct >= 0)
13214 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
13216 elseif ($this->feed > 1)
13218 $this->data['data'] .= $cdata;
13222 function tag_close($parser, $tag)
13229 if ($this->current_xhtml_construct >= 0)
13231 $this->current_xhtml_construct--;
13232 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')))
13234 $this->data['data'] .= '</' . end($this->element) . '>';
13237 if ($this->current_xhtml_construct == -1)
13239 $this->data =& $this->datas[$this->feed];
13240 array_pop($this->datas);
13243 array_pop($this->element);
13244 array_pop($this->namespace);
13245 array_pop($this->xml_base);
13246 array_pop($this->xml_base_explicit);
13247 array_pop($this->xml_lang);
13251 function split_ns($string)
13253 static $cache = array();
13254 if (!isset($cache[$string]))
13256 if ($pos = strpos($string, $this->separator))
13258 static $separator_length;
13259 if (!$separator_length)
13261 $separator_length = strlen($this->separator);
13263 $namespace = substr($string, 0, $pos);
13264 $local_name = substr($string, $pos + $separator_length);
13265 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
13267 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
13270 // Normalize the Media RSS namespaces
13271 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
13273 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
13275 $cache[$string] = array($namespace, $local_name);
13279 $cache[$string] = array('', $string);
13282 return $cache[$string];
13287 * @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
13289 class SimplePie_Sanitize
13295 var $remove_div = true;
13296 var $image_handler = '';
13297 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
13298 var $encode_instead_of_strip = false;
13299 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
13300 var $strip_comments = false;
13301 var $output_encoding = 'UTF-8';
13302 var $enable_cache = true;
13303 var $cache_location = './cache';
13304 var $cache_name_function = 'md5';
13305 var $cache_class = 'SimplePie_Cache';
13306 var $file_class = 'SimplePie_File';
13308 var $useragent = '';
13309 var $force_fsockopen = false;
13311 var $replace_url_attributes = array(
13314 'blockquote' => 'cite',
13316 'form' => 'action',
13317 'img' => array('longdesc', 'src'),
13323 function remove_div($enable = true)
13325 $this->remove_div = (bool) $enable;
13328 function set_image_handler($page = false)
13332 $this->image_handler = (string) $page;
13336 $this->image_handler = false;
13340 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13342 if (isset($enable_cache))
13344 $this->enable_cache = (bool) $enable_cache;
13347 if ($cache_location)
13349 $this->cache_location = (string) $cache_location;
13352 if ($cache_name_function)
13354 $this->cache_name_function = (string) $cache_name_function;
13359 $this->cache_class = (string) $cache_class;
13363 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13367 $this->file_class = (string) $file_class;
13372 $this->timeout = (string) $timeout;
13377 $this->useragent = (string) $useragent;
13380 if ($force_fsockopen)
13382 $this->force_fsockopen = (string) $force_fsockopen;
13386 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13390 if (is_array($tags))
13392 $this->strip_htmltags = $tags;
13396 $this->strip_htmltags = explode(',', $tags);
13401 $this->strip_htmltags = false;
13405 function encode_instead_of_strip($encode = false)
13407 $this->encode_instead_of_strip = (bool) $encode;
13410 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13414 if (is_array($attribs))
13416 $this->strip_attributes = $attribs;
13420 $this->strip_attributes = explode(',', $attribs);
13425 $this->strip_attributes = false;
13429 function strip_comments($strip = false)
13431 $this->strip_comments = (bool) $strip;
13434 function set_output_encoding($encoding = 'UTF-8')
13436 $this->output_encoding = (string) $encoding;
13440 * Set element/attribute key/value pairs of HTML attributes
13441 * containing URLs that need to be resolved relative to the feed
13445 * @param array $element_attribute Element/attribute key/value pairs
13447 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'))
13449 $this->replace_url_attributes = (array) $element_attribute;
13452 function sanitize($data, $type, $base = '')
13454 $data = trim($data);
13455 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13457 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13459 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))
13461 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13465 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13469 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13471 $data = base64_decode($data);
13474 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13476 if ($this->remove_div)
13478 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13479 $data = preg_replace('/<\/div>$/', '', $data);
13483 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13487 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13490 if ($this->strip_comments)
13492 $data = SimplePie_Misc::strip_comments($data);
13495 // Strip out HTML tags and attributes that might cause various security problems.
13496 // Based on recommendations by Mark Pilgrim at:
13497 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13498 if ($this->strip_htmltags)
13500 foreach ($this->strip_htmltags as $tag)
13502 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13503 while (preg_match($pcre, $data))
13505 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13510 if ($this->strip_attributes)
13512 foreach ($this->strip_attributes as $attrib)
13514 $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);
13518 // Replace relative URLs
13519 $this->base = $base;
13520 foreach ($this->replace_url_attributes as $element => $attributes)
13522 $data = $this->replace_urls($data, $element, $attributes);
13525 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13526 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13528 $images = SimplePie_Misc::get_element('img', $data);
13529 foreach ($images as $img)
13531 if (isset($img['attribs']['src']['data']))
13533 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13534 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13536 if ($cache->load())
13538 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13539 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13543 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13544 $headers = $file->headers;
13546 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13548 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13550 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13551 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13555 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13563 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13564 $data = trim($data);
13567 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13569 $data = SimplePie_Misc::absolutize_url($data, $base);
13572 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13574 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13577 if ($this->output_encoding != 'UTF-8')
13579 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13585 function replace_urls($data, $tag, $attributes)
13587 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13589 $elements = SimplePie_Misc::get_element($tag, $data);
13590 foreach ($elements as $element)
13592 if (is_array($attributes))
13594 foreach ($attributes as $attribute)
13596 if (isset($element['attribs'][$attribute]['data']))
13598 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13599 $new_element = SimplePie_Misc::element_implode($element);
13600 $data = str_replace($element['full'], $new_element, $data);
13601 $element['full'] = $new_element;
13605 elseif (isset($element['attribs'][$attributes]['data']))
13607 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13608 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13615 function do_strip_htmltags($match)
13617 if ($this->encode_instead_of_strip)
13619 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13621 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13622 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13623 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13627 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13630 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))