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-2009, 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-2009 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.2.1-dev');
58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
60 define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::parse_date(substr('$Date$', 7, 25)) ? SimplePie_Misc::parse_date(substr('$Date$', 7, 25)) : filemtime(__FILE__)));
63 * SimplePie Website URL
65 define('SIMPLEPIE_URL', 'http://simplepie.org');
69 * @see SimplePie::set_useragent()
71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
80 * @see SimplePie::set_autodiscovery_level()
82 define('SIMPLEPIE_LOCATOR_NONE', 0);
85 * Feed Link Element Autodiscovery
86 * @see SimplePie::set_autodiscovery_level()
88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
91 * Local Feed Extension Autodiscovery
92 * @see SimplePie::set_autodiscovery_level()
94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
97 * Local Feed Body Autodiscovery
98 * @see SimplePie::set_autodiscovery_level()
100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
103 * Remote Feed Extension Autodiscovery
104 * @see SimplePie::set_autodiscovery_level()
106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
109 * Remote Feed Body Autodiscovery
110 * @see SimplePie::set_autodiscovery_level()
112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
115 * All Feed Autodiscovery
116 * @see SimplePie::set_autodiscovery_level()
118 define('SIMPLEPIE_LOCATOR_ALL', 31);
123 define('SIMPLEPIE_TYPE_NONE', 0);
128 define('SIMPLEPIE_TYPE_RSS_090', 1);
131 * RSS 0.91 (Netscape)
133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
136 * RSS 0.91 (Userland)
138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
141 * RSS 0.91 (both Netscape and Userland)
143 define('SIMPLEPIE_TYPE_RSS_091', 6);
148 define('SIMPLEPIE_TYPE_RSS_092', 8);
153 define('SIMPLEPIE_TYPE_RSS_093', 16);
158 define('SIMPLEPIE_TYPE_RSS_094', 32);
163 define('SIMPLEPIE_TYPE_RSS_10', 64);
168 define('SIMPLEPIE_TYPE_RSS_20', 128);
173 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
176 * Non-RDF-based RSS (truly intended as syndication format)
178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
183 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
188 define('SIMPLEPIE_TYPE_ATOM_03', 256);
193 define('SIMPLEPIE_TYPE_ATOM_10', 512);
198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
203 define('SIMPLEPIE_TYPE_ALL', 1023);
208 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
218 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
226 * base64-encoded construct
228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
233 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
236 * A construct that might be HTML
238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
243 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
248 define('SIMPLEPIE_SAME_CASE', 1);
251 * Change to lowercase
253 define('SIMPLEPIE_LOWERCASE', 2);
256 * Change to uppercase
258 define('SIMPLEPIE_UPPERCASE', 4);
261 * PCRE for HTML attributes
263 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]*');
266 * PCRE for XML attributes
268 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
273 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
278 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
283 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
288 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
293 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
298 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
301 * RSS 1.0 Content Module Namespace
303 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
307 * (Stupid, I know, but I'm certain it will confuse people less with support.)
309 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
314 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
319 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
322 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
324 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
329 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
332 * Media RSS Namespace
334 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
337 * Wrong Media RSS Namespace
339 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
342 * iTunes RSS Namespace
344 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
349 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
352 * IANA Link Relations Registry
354 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
357 * Whether we're running on PHP5
359 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
364 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
369 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
374 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
377 * fsockopen() file source
379 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
384 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
387 * file_get_contents() file source
389 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
399 * @var array Raw data
405 * @var mixed Error string
411 * @var object Instance of SimplePie_Sanitize (or other class)
412 * @see SimplePie::set_sanitize_class()
418 * @var string SimplePie Useragent
419 * @see SimplePie::set_useragent()
422 var $useragent = SIMPLEPIE_USERAGENT;
425 * @var string Feed URL
426 * @see SimplePie::set_feed_url()
432 * @var object Instance of SimplePie_File to use as a feed
433 * @see SimplePie::set_file()
439 * @var string Raw feed data
440 * @see SimplePie::set_raw_data()
446 * @var int Timeout for fetching remote files
447 * @see SimplePie::set_timeout()
453 * @var bool Forces fsockopen() to be used for remote files instead
454 * of cURL, even if a new enough version is installed
455 * @see SimplePie::force_fsockopen()
458 var $force_fsockopen = false;
461 * @var bool Force the given data/URL to be treated as a feed no matter what
463 * @see SimplePie::force_feed()
466 var $force_feed = false;
469 * @var bool Enable/Disable XML dump
470 * @see SimplePie::enable_xml_dump()
473 var $xml_dump = false;
476 * @var bool Enable/Disable Caching
477 * @see SimplePie::enable_cache()
483 * @var int Cache duration (in seconds)
484 * @see SimplePie::set_cache_duration()
487 var $cache_duration = 3600;
490 * @var int Auto-discovery cache duration (in seconds)
491 * @see SimplePie::set_autodiscovery_cache_duration()
494 var $autodiscovery_cache_duration = 604800; // 7 Days.
497 * @var string Cache location (relative to executing script)
498 * @see SimplePie::set_cache_location()
501 var $cache_location = './cache';
504 * @var string Function that creates the cache filename
505 * @see SimplePie::set_cache_name_function()
508 var $cache_name_function = 'md5';
511 * @var bool Reorder feed by date descending
512 * @see SimplePie::enable_order_by_date()
515 var $order_by_date = true;
518 * @var mixed Force input encoding to be set to the follow value
519 * (false, or anything type-cast to false, disables this feature)
520 * @see SimplePie::set_input_encoding()
523 var $input_encoding = false;
526 * @var int Feed Autodiscovery Level
527 * @see SimplePie::set_autodiscovery_level()
530 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
533 * @var string Class used for caching feeds
534 * @see SimplePie::set_cache_class()
537 var $cache_class = 'SimplePie_Cache';
540 * @var string Class used for locating feeds
541 * @see SimplePie::set_locator_class()
544 var $locator_class = 'SimplePie_Locator';
547 * @var string Class used for parsing feeds
548 * @see SimplePie::set_parser_class()
551 var $parser_class = 'SimplePie_Parser';
554 * @var string Class used for fetching feeds
555 * @see SimplePie::set_file_class()
558 var $file_class = 'SimplePie_File';
561 * @var string Class used for items
562 * @see SimplePie::set_item_class()
565 var $item_class = 'SimplePie_Item';
568 * @var string Class used for authors
569 * @see SimplePie::set_author_class()
572 var $author_class = 'SimplePie_Author';
575 * @var string Class used for categories
576 * @see SimplePie::set_category_class()
579 var $category_class = 'SimplePie_Category';
582 * @var string Class used for enclosures
583 * @see SimplePie::set_enclosures_class()
586 var $enclosure_class = 'SimplePie_Enclosure';
589 * @var string Class used for Media RSS <media:text> captions
590 * @see SimplePie::set_caption_class()
593 var $caption_class = 'SimplePie_Caption';
596 * @var string Class used for Media RSS <media:copyright>
597 * @see SimplePie::set_copyright_class()
600 var $copyright_class = 'SimplePie_Copyright';
603 * @var string Class used for Media RSS <media:credit>
604 * @see SimplePie::set_credit_class()
607 var $credit_class = 'SimplePie_Credit';
610 * @var string Class used for Media RSS <media:rating>
611 * @see SimplePie::set_rating_class()
614 var $rating_class = 'SimplePie_Rating';
617 * @var string Class used for Media RSS <media:restriction>
618 * @see SimplePie::set_restriction_class()
621 var $restriction_class = 'SimplePie_Restriction';
624 * @var string Class used for content-type sniffing
625 * @see SimplePie::set_content_type_sniffer_class()
628 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
631 * @var string Class used for item sources.
632 * @see SimplePie::set_source_class()
635 var $source_class = 'SimplePie_Source';
638 * @var mixed Set javascript query string parameter (false, or
639 * anything type-cast to false, disables this feature)
640 * @see SimplePie::set_javascript()
643 var $javascript = 'js';
646 * @var int Maximum number of feeds to check with autodiscovery
647 * @see SimplePie::set_max_checked_feeds()
650 var $max_checked_feeds = 10;
653 * @var array All the feeds found during the autodiscovery process
654 * @see SimplePie::get_all_discovered_feeds()
657 var $all_discovered_feeds = array();
660 * @var string Web-accessible path to the handler_favicon.php file.
661 * @see SimplePie::set_favicon_handler()
664 var $favicon_handler = '';
667 * @var string Web-accessible path to the handler_image.php file.
668 * @see SimplePie::set_image_handler()
671 var $image_handler = '';
674 * @var array Stores the URLs when multiple feeds are being initialized.
675 * @see SimplePie::set_feed_url()
678 var $multifeed_url = array();
681 * @var array Stores SimplePie objects when multiple feeds initialized.
684 var $multifeed_objects = array();
687 * @var array Stores the get_object_vars() array for use with multifeeds.
688 * @see SimplePie::set_feed_url()
691 var $config_settings = null;
694 * @var integer Stores the number of items to return per-feed with multifeeds.
695 * @see SimplePie::set_item_limit()
701 * @var array Stores the default attributes to be stripped by strip_attributes().
702 * @see SimplePie::strip_attributes()
705 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
708 * @var array Stores the default tags to be stripped by strip_htmltags().
709 * @see SimplePie::strip_htmltags()
712 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
715 * The SimplePie class contains feed level data and options
717 * There are two ways that you can create a new SimplePie object. The first
718 * is by passing a feed URL as a parameter to the SimplePie constructor
719 * (as well as optionally setting the cache location and cache expiry). This
720 * will initialise the whole feed with all of the default settings, and you
721 * can begin accessing methods and properties immediately.
723 * The second way is to create the SimplePie object with no parameters
724 * at all. This will enable you to set configuration options. After setting
725 * them, you must initialise the feed using $feed->init(). At that point the
726 * object's methods and properties will be available to you. This format is
727 * what is used throughout this documentation.
730 * @since 1.0 Preview Release
731 * @param string $feed_url This is the URL you want to parse.
732 * @param string $cache_location This is where you want the cache to be stored.
733 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
735 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
737 // Other objects, instances created here so we can set options on them
738 $this->sanitize = new SimplePie_Sanitize;
740 // Set options if they're passed to the constructor
741 if ($cache_location !== null)
743 $this->set_cache_location($cache_location);
746 if ($cache_duration !== null)
748 $this->set_cache_duration($cache_duration);
751 // Only init the script if we're passed a feed URL
752 if ($feed_url !== null)
754 $this->set_feed_url($feed_url);
760 * Used for converting object to a string
762 function __toString()
764 return md5(serialize($this->data));
768 * Remove items that link back to this before destroying this object
770 function __destruct()
772 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
774 if (!empty($this->data['items']))
776 foreach ($this->data['items'] as $item)
780 unset($item, $this->data['items']);
782 if (!empty($this->data['ordered_items']))
784 foreach ($this->data['ordered_items'] as $item)
788 unset($item, $this->data['ordered_items']);
794 * Force the given data/URL to be treated as a feed no matter what it
799 * @param bool $enable Force the given data/URL to be treated as a feed
801 function force_feed($enable = false)
803 $this->force_feed = (bool) $enable;
807 * This is the URL of the feed you want to parse.
809 * This allows you to enter the URL of the feed you want to parse, or the
810 * website you want to try to use auto-discovery on. This takes priority
811 * over any set raw data.
813 * You can set multiple feeds to mash together by passing an array instead
814 * of a string for the $url. Remember that with each additional feed comes
815 * additional processing and resources.
818 * @since 1.0 Preview Release
819 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
820 * @see SimplePie::set_raw_data()
822 function set_feed_url($url)
826 $this->multifeed_url = array();
827 foreach ($url as $value)
829 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
834 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
839 * Provides an instance of SimplePie_File to use as a feed
842 * @param object &$file Instance of SimplePie_File (or subclass)
843 * @return bool True on success, false on failure
845 function set_file(&$file)
847 if (is_a($file, 'SimplePie_File'))
849 $this->feed_url = $file->url;
850 $this->file =& $file;
857 * Allows you to use a string of RSS/Atom data instead of a remote feed.
859 * If you have a feed available as a string in PHP, you can tell SimplePie
860 * to parse that data string instead of a remote feed. Any set feed URL
865 * @param string $data RSS or Atom data as a string.
866 * @see SimplePie::set_feed_url()
868 function set_raw_data($data)
870 $this->raw_data = $data;
874 * Allows you to override the default timeout for fetching remote feeds.
876 * This allows you to change the maximum time the feed's server to respond
877 * and send the feed back.
881 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
883 function set_timeout($timeout = 10)
885 $this->timeout = (int) $timeout;
889 * Forces SimplePie to use fsockopen() instead of the preferred cURL
894 * @param bool $enable Force fsockopen() to be used
896 function force_fsockopen($enable = false)
898 $this->force_fsockopen = (bool) $enable;
902 * Outputs the raw XML content of the feed, after it has gone through
903 * SimplePie's filters.
905 * Used only for debugging, this function will output the XML content as
906 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
907 * before trying to parse it. Many parts of the feed are re-written in
908 * memory, and in the end, you have a parsable feed. XML dump shows you the
909 * actual XML that SimplePie tries to parse, which may or may not be very
910 * different from the original feed.
913 * @since 1.0 Preview Release
914 * @param bool $enable Enable XML dump
916 function enable_xml_dump($enable = false)
918 $this->xml_dump = (bool) $enable;
922 * Enables/disables caching in SimplePie.
924 * This option allows you to disable caching all-together in SimplePie.
925 * However, disabling the cache can lead to longer load times.
928 * @since 1.0 Preview Release
929 * @param bool $enable Enable caching
931 function enable_cache($enable = true)
933 $this->cache = (bool) $enable;
937 * Set the length of time (in seconds) that the contents of a feed
941 * @param int $seconds The feed content cache duration.
943 function set_cache_duration($seconds = 3600)
945 $this->cache_duration = (int) $seconds;
949 * Set the length of time (in seconds) that the autodiscovered feed
950 * URL will be cached.
953 * @param int $seconds The autodiscovered feed URL cache duration.
955 function set_autodiscovery_cache_duration($seconds = 604800)
957 $this->autodiscovery_cache_duration = (int) $seconds;
961 * Set the file system location where the cached files should be stored.
964 * @param string $location The file system location.
966 function set_cache_location($location = './cache')
968 $this->cache_location = (string) $location;
972 * Determines whether feed items should be sorted into reverse chronological order.
975 * @param bool $enable Sort as reverse chronological order.
977 function enable_order_by_date($enable = true)
979 $this->order_by_date = (bool) $enable;
983 * Allows you to override the character encoding reported by the feed.
986 * @param string $encoding Character encoding.
988 function set_input_encoding($encoding = false)
992 $this->input_encoding = (string) $encoding;
996 $this->input_encoding = false;
1001 * Set how much feed autodiscovery to do
1004 * @see SIMPLEPIE_LOCATOR_NONE
1005 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1006 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1007 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1008 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1009 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1010 * @see SIMPLEPIE_LOCATOR_ALL
1011 * @param int $level Feed Autodiscovery Level (level can be a
1012 * combination of the above constants, see bitwise OR operator)
1014 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1016 $this->autodiscovery = (int) $level;
1020 * Allows you to change which class SimplePie uses for caching.
1021 * Useful when you are overloading or extending SimplePie's default classes.
1024 * @param string $class Name of custom class.
1025 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1026 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1028 function set_cache_class($class = 'SimplePie_Cache')
1030 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1032 $this->cache_class = $class;
1039 * Allows you to change which class SimplePie uses for auto-discovery.
1040 * Useful when you are overloading or extending SimplePie's default classes.
1043 * @param string $class Name of custom class.
1044 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1045 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1047 function set_locator_class($class = 'SimplePie_Locator')
1049 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1051 $this->locator_class = $class;
1058 * Allows you to change which class SimplePie uses for XML parsing.
1059 * Useful when you are overloading or extending SimplePie's default classes.
1062 * @param string $class Name of custom class.
1063 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1064 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1066 function set_parser_class($class = 'SimplePie_Parser')
1068 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1070 $this->parser_class = $class;
1077 * Allows you to change which class SimplePie uses for remote file fetching.
1078 * Useful when you are overloading or extending SimplePie's default classes.
1081 * @param string $class Name of custom class.
1082 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1083 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1085 function set_file_class($class = 'SimplePie_File')
1087 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1089 $this->file_class = $class;
1096 * Allows you to change which class SimplePie uses for data sanitization.
1097 * Useful when you are overloading or extending SimplePie's default classes.
1100 * @param string $class Name of custom class.
1101 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1102 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1104 function set_sanitize_class($class = 'SimplePie_Sanitize')
1106 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1108 $this->sanitize = new $class;
1115 * Allows you to change which class SimplePie uses for handling feed items.
1116 * Useful when you are overloading or extending SimplePie's default classes.
1119 * @param string $class Name of custom class.
1120 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1121 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1123 function set_item_class($class = 'SimplePie_Item')
1125 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1127 $this->item_class = $class;
1134 * Allows you to change which class SimplePie uses for handling author data.
1135 * Useful when you are overloading or extending SimplePie's default classes.
1138 * @param string $class Name of custom class.
1139 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1140 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1142 function set_author_class($class = 'SimplePie_Author')
1144 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1146 $this->author_class = $class;
1153 * Allows you to change which class SimplePie uses for handling category data.
1154 * Useful when you are overloading or extending SimplePie's default classes.
1157 * @param string $class Name of custom class.
1158 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1159 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1161 function set_category_class($class = 'SimplePie_Category')
1163 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1165 $this->category_class = $class;
1172 * Allows you to change which class SimplePie uses for feed enclosures.
1173 * Useful when you are overloading or extending SimplePie's default classes.
1176 * @param string $class Name of custom class.
1177 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1178 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1180 function set_enclosure_class($class = 'SimplePie_Enclosure')
1182 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1184 $this->enclosure_class = $class;
1191 * Allows you to change which class SimplePie uses for <media:text> captions
1192 * Useful when you are overloading or extending SimplePie's default classes.
1195 * @param string $class Name of custom class.
1196 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1197 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1199 function set_caption_class($class = 'SimplePie_Caption')
1201 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1203 $this->caption_class = $class;
1210 * Allows you to change which class SimplePie uses for <media:copyright>
1211 * Useful when you are overloading or extending SimplePie's default classes.
1214 * @param string $class Name of custom class.
1215 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1216 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1218 function set_copyright_class($class = 'SimplePie_Copyright')
1220 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1222 $this->copyright_class = $class;
1229 * Allows you to change which class SimplePie uses for <media:credit>
1230 * Useful when you are overloading or extending SimplePie's default classes.
1233 * @param string $class Name of custom class.
1234 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1235 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1237 function set_credit_class($class = 'SimplePie_Credit')
1239 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1241 $this->credit_class = $class;
1248 * Allows you to change which class SimplePie uses for <media:rating>
1249 * Useful when you are overloading or extending SimplePie's default classes.
1252 * @param string $class Name of custom class.
1253 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1254 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1256 function set_rating_class($class = 'SimplePie_Rating')
1258 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1260 $this->rating_class = $class;
1267 * Allows you to change which class SimplePie uses for <media:restriction>
1268 * Useful when you are overloading or extending SimplePie's default classes.
1271 * @param string $class Name of custom class.
1272 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1273 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1275 function set_restriction_class($class = 'SimplePie_Restriction')
1277 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1279 $this->restriction_class = $class;
1286 * Allows you to change which class SimplePie uses for content-type sniffing.
1287 * Useful when you are overloading or extending SimplePie's default classes.
1290 * @param string $class Name of custom class.
1291 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1292 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1294 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1296 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1298 $this->content_type_sniffer_class = $class;
1305 * Allows you to change which class SimplePie uses item sources.
1306 * Useful when you are overloading or extending SimplePie's default classes.
1309 * @param string $class Name of custom class.
1310 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1311 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1313 function set_source_class($class = 'SimplePie_Source')
1315 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1317 $this->source_class = $class;
1324 * Allows you to override the default user agent string.
1327 * @param string $ua New user agent string.
1329 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1331 $this->useragent = (string) $ua;
1335 * Set callback function to create cache filename with
1338 * @param mixed $function Callback function
1340 function set_cache_name_function($function = 'md5')
1342 if (is_callable($function))
1344 $this->cache_name_function = $function;
1349 * Set javascript query string parameter
1352 * @param mixed $get Javascript query string parameter
1354 function set_javascript($get = 'js')
1358 $this->javascript = (string) $get;
1362 $this->javascript = false;
1367 * Set options to make SP as fast as possible. Forgoes a
1368 * substantial amount of data sanitization in favor of speed.
1371 * @param bool $set Whether to set them or not
1373 function set_stupidly_fast($set = false)
1377 $this->enable_order_by_date(false);
1378 $this->remove_div(false);
1379 $this->strip_comments(false);
1380 $this->strip_htmltags(false);
1381 $this->strip_attributes(false);
1382 $this->set_image_handler(false);
1387 * Set maximum number of feeds to check with autodiscovery
1390 * @param int $max Maximum number of feeds to check
1392 function set_max_checked_feeds($max = 10)
1394 $this->max_checked_feeds = (int) $max;
1397 function remove_div($enable = true)
1399 $this->sanitize->remove_div($enable);
1402 function strip_htmltags($tags = '', $encode = null)
1406 $tags = $this->strip_htmltags;
1408 $this->sanitize->strip_htmltags($tags);
1409 if ($encode !== null)
1411 $this->sanitize->encode_instead_of_strip($tags);
1415 function encode_instead_of_strip($enable = true)
1417 $this->sanitize->encode_instead_of_strip($enable);
1420 function strip_attributes($attribs = '')
1422 if ($attribs === '')
1424 $attribs = $this->strip_attributes;
1426 $this->sanitize->strip_attributes($attribs);
1429 function set_output_encoding($encoding = 'UTF-8')
1431 $this->sanitize->set_output_encoding($encoding);
1434 function strip_comments($strip = false)
1436 $this->sanitize->strip_comments($strip);
1440 * Set element/attribute key/value pairs of HTML attributes
1441 * containing URLs that need to be resolved relative to the feed
1445 * @param array $element_attribute Element/attribute key/value pairs
1447 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'))
1449 $this->sanitize->set_url_replacements($element_attribute);
1453 * Set the handler to enable the display of cached favicons.
1456 * @param str $page Web-accessible path to the handler_favicon.php file.
1457 * @param str $qs The query string that the value should be passed to.
1459 function set_favicon_handler($page = false, $qs = 'i')
1461 if ($page !== false)
1463 $this->favicon_handler = $page . '?' . $qs . '=';
1467 $this->favicon_handler = '';
1472 * Set the handler to enable the display of cached images.
1475 * @param str $page Web-accessible path to the handler_image.php file.
1476 * @param str $qs The query string that the value should be passed to.
1478 function set_image_handler($page = false, $qs = 'i')
1480 if ($page !== false)
1482 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1486 $this->image_handler = '';
1491 * Set the limit for items returned per-feed with multifeeds.
1494 * @param integer $limit The maximum number of items to return.
1496 function set_item_limit($limit = 0)
1498 $this->item_limit = (int) $limit;
1503 // Check absolute bare minimum requirements.
1504 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1508 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1509 elseif (!extension_loaded('xmlreader'))
1511 static $xml_is_sane = null;
1512 if ($xml_is_sane === null)
1514 $parser_check = xml_parser_create();
1515 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1516 xml_parser_free($parser_check);
1517 $xml_is_sane = isset($values[0]['value']);
1525 if (isset($_GET[$this->javascript]))
1527 SimplePie_Misc::output_javascript();
1531 // Pass whatever was set with config options over to the sanitizer.
1532 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1533 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1535 if ($this->feed_url !== null || $this->raw_data !== null)
1537 $this->data = array();
1538 $this->multifeed_objects = array();
1541 if ($this->feed_url !== null)
1543 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1544 // Decide whether to enable caching
1545 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1547 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1549 // If it's enabled and we don't want an XML dump, use the cache
1550 if ($cache && !$this->xml_dump)
1553 $this->data = $cache->load();
1554 if (!empty($this->data))
1556 // If the cache is for an outdated build of SimplePie
1557 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1560 $this->data = array();
1562 // If we've hit a collision just rerun it with caching disabled
1563 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1566 $this->data = array();
1568 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1569 elseif (isset($this->data['feed_url']))
1571 // If the autodiscovery cache is still valid use it.
1572 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1574 // Do not need to do feed autodiscovery yet.
1575 if ($this->data['feed_url'] === $this->data['url'])
1578 $this->data = array();
1582 $this->set_feed_url($this->data['feed_url']);
1583 return $this->init();
1587 // Check if the cache has been updated
1588 elseif ($cache->mtime() + $this->cache_duration < time())
1590 // If we have last-modified and/or etag set
1591 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1594 if (isset($this->data['headers']['last-modified']))
1596 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1598 if (isset($this->data['headers']['etag']))
1600 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1602 $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1605 if ($file->status_code === 304)
1612 $headers = $file->headers;
1621 // If the cache is still valid, just return true
1627 // If the cache is empty, delete it
1631 $this->data = array();
1634 // 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.
1637 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1639 $file =& $this->file;
1643 $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1646 // If the file connection has an error, set SimplePie::error to that and quit
1647 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1649 $this->error = $file->error;
1650 if (!empty($this->data))
1660 if (!$this->force_feed)
1662 // Check if the supplied URL is a feed, if it isn't, look for it.
1663 $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1664 if (!$locate->is_feed($file))
1666 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1668 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1672 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1673 if (!$cache->save($this))
1675 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1677 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1679 $this->feed_url = $file->url;
1683 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
1684 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1691 $headers = $file->headers;
1692 $data = $file->body;
1693 $sniffer = new $this->content_type_sniffer_class($file);
1694 $sniffed = $sniffer->get_type();
1698 $data = $this->raw_data;
1701 // Set up array of possible encodings
1702 $encodings = array();
1704 // First check to see if input has been overridden.
1705 if ($this->input_encoding !== false)
1707 $encodings[] = $this->input_encoding;
1710 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1711 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1713 // RFC 3023 (only applies to sniffed content)
1714 if (isset($sniffed))
1716 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1718 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1720 $encodings[] = strtoupper($charset[1]);
1722 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1723 $encodings[] = 'UTF-8';
1725 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1727 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1729 $encodings[] = $charset[1];
1731 $encodings[] = 'US-ASCII';
1733 // Text MIME-type default
1734 elseif (substr($sniffed, 0, 5) === 'text/')
1736 $encodings[] = 'US-ASCII';
1740 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1741 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1742 $encodings[] = 'UTF-8';
1743 $encodings[] = 'ISO-8859-1';
1745 // There's no point in trying an encoding twice
1746 $encodings = array_unique($encodings);
1748 // If we want the XML, just output that with the most likely encoding and quit
1749 if ($this->xml_dump)
1751 header('Content-type: text/xml; charset=' . $encodings[0]);
1756 // Loop through each possible encoding, till we return something, or run out of possibilities
1757 foreach ($encodings as $encoding)
1759 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1760 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1762 // Create new parser
1763 $parser = new $this->parser_class();
1765 // If it's parsed fine
1766 if ($parser->parse($utf8_data, 'UTF-8'))
1768 $this->data = $parser->get_data();
1769 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1771 if (isset($headers))
1773 $this->data['headers'] = $headers;
1775 $this->data['build'] = SIMPLEPIE_BUILD;
1777 // Cache the file if caching is enabled
1778 if ($cache && !$cache->save($this))
1780 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1786 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1787 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1795 // We have an error, just set SimplePie_Misc::error to it and quit
1796 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1800 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
1802 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1805 elseif (!empty($this->multifeed_url))
1809 $this->multifeed_objects = array();
1810 foreach ($this->multifeed_url as $url)
1814 // This keyword needs to defy coding standards for PHP4 compatibility
1815 $this->multifeed_objects[$i] = clone($this);
1819 $this->multifeed_objects[$i] = $this;
1821 $this->multifeed_objects[$i]->set_feed_url($url);
1822 $success |= $this->multifeed_objects[$i]->init();
1825 return (bool) $success;
1834 * Return the error message for the occured error
1837 * @return string Error message
1841 return $this->error;
1844 function get_encoding()
1846 return $this->sanitize->output_encoding;
1849 function handle_content_type($mime = 'text/html')
1851 if (!headers_sent())
1853 $header = "Content-type: $mime;";
1854 if ($this->get_encoding())
1856 $header .= ' charset=' . $this->get_encoding();
1860 $header .= ' charset=UTF-8';
1868 if (!isset($this->data['type']))
1870 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1871 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1873 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1875 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1877 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1879 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1881 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1882 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1884 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1886 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1888 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1889 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1891 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1893 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1896 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1898 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1899 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1901 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1904 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1905 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1907 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1921 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1925 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1929 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1933 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1940 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1943 return $this->data['type'];
1947 * Returns the URL for the favicon of the feed's website.
1949 * @todo Cache atom:icon
1953 function get_favicon()
1955 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1957 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1959 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1961 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1963 if ($this->cache && $this->favicon_handler)
1965 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1966 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1970 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1974 $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1976 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1978 $sniffer = new $this->content_type_sniffer_class($file);
1979 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1981 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1983 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1987 trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1988 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2001 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2008 * @todo If we have a perm redirect we should return the new URL
2009 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2010 * @todo Also, |atom:link|@rel=self
2012 function subscribe_url()
2014 if ($this->feed_url !== null)
2016 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2024 function subscribe_feed()
2026 if ($this->feed_url !== null)
2028 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2036 function subscribe_outlook()
2038 if ($this->feed_url !== null)
2040 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2048 function subscribe_podcast()
2050 if ($this->feed_url !== null)
2052 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2060 function subscribe_itunes()
2062 if ($this->feed_url !== null)
2064 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2073 * Creates the subscribe_* methods' return data
2076 * @param string $feed_url String to prefix to the feed URL
2077 * @param string $site_url String to prefix to the site URL (and
2078 * suffix to the feed URL)
2079 * @return mixed URL if feed exists, false otherwise
2081 function subscribe_service($feed_url, $site_url = null)
2083 if ($this->subscribe_url())
2085 $return = $feed_url . rawurlencode($this->feed_url);
2086 if ($site_url !== null && $this->get_link() !== null)
2088 $return .= $site_url . rawurlencode($this->get_link());
2090 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2098 function subscribe_aol()
2100 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2103 function subscribe_bloglines()
2105 return $this->subscribe_service('http://www.bloglines.com/sub/');
2108 function subscribe_eskobo()
2110 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2113 function subscribe_feedfeeds()
2115 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2118 function subscribe_feedster()
2120 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2123 function subscribe_google()
2125 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2128 function subscribe_gritwire()
2130 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2133 function subscribe_msn()
2135 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2138 function subscribe_netvibes()
2140 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2143 function subscribe_newsburst()
2145 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2148 function subscribe_newsgator()
2150 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2153 function subscribe_odeo()
2155 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2158 function subscribe_podnova()
2160 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2163 function subscribe_rojo()
2165 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2168 function subscribe_yahoo()
2170 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2173 function get_feed_tags($namespace, $tag)
2175 $type = $this->get_type();
2176 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2178 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2180 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2183 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2185 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2187 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2190 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2192 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2194 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2197 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2199 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2201 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2207 function get_channel_tags($namespace, $tag)
2209 $type = $this->get_type();
2210 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2212 if ($return = $this->get_feed_tags($namespace, $tag))
2217 if ($type & SIMPLEPIE_TYPE_RSS_10)
2219 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2221 if (isset($channel[0]['child'][$namespace][$tag]))
2223 return $channel[0]['child'][$namespace][$tag];
2227 if ($type & SIMPLEPIE_TYPE_RSS_090)
2229 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2231 if (isset($channel[0]['child'][$namespace][$tag]))
2233 return $channel[0]['child'][$namespace][$tag];
2237 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2239 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2241 if (isset($channel[0]['child'][$namespace][$tag]))
2243 return $channel[0]['child'][$namespace][$tag];
2250 function get_image_tags($namespace, $tag)
2252 $type = $this->get_type();
2253 if ($type & SIMPLEPIE_TYPE_RSS_10)
2255 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2257 if (isset($image[0]['child'][$namespace][$tag]))
2259 return $image[0]['child'][$namespace][$tag];
2263 if ($type & SIMPLEPIE_TYPE_RSS_090)
2265 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2267 if (isset($image[0]['child'][$namespace][$tag]))
2269 return $image[0]['child'][$namespace][$tag];
2273 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2275 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2277 if (isset($image[0]['child'][$namespace][$tag]))
2279 return $image[0]['child'][$namespace][$tag];
2286 function get_base($element = array())
2288 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2290 return $element['xml_base'];
2292 elseif ($this->get_link() !== null)
2294 return $this->get_link();
2298 return $this->subscribe_url();
2302 function sanitize($data, $type, $base = '')
2304 return $this->sanitize->sanitize($data, $type, $base);
2307 function get_title()
2309 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2311 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2313 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2315 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2317 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2319 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2321 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2323 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2325 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2327 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2329 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2331 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2333 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2335 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2343 function get_category($key = 0)
2345 $categories = $this->get_categories();
2346 if (isset($categories[$key]))
2348 return $categories[$key];
2356 function get_categories()
2358 $categories = array();
2360 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2365 if (isset($category['attribs']['']['term']))
2367 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2369 if (isset($category['attribs']['']['scheme']))
2371 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2373 if (isset($category['attribs']['']['label']))
2375 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2377 $categories[] = new $this->category_class($term, $scheme, $label);
2379 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2381 // This is really the label, but keep this as the term also for BC.
2382 // Label will also work on retrieving because that falls back to term.
2383 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2384 if (isset($category['attribs']['']['domain']))
2386 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2392 $categories[] = new $this->category_class($term, $scheme, null);
2394 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2396 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2398 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2400 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2403 if (!empty($categories))
2405 return SimplePie_Misc::array_unique($categories);
2413 function get_author($key = 0)
2415 $authors = $this->get_authors();
2416 if (isset($authors[$key]))
2418 return $authors[$key];
2426 function get_authors()
2429 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2435 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2437 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2439 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2441 $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]));
2443 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2445 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2447 if (isset($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]['data']))
2449 $avatar = $this->sanitize($$author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]));
2451 if ($name !== null || $email !== null || $uri !== null || $avatar !== null)
2453 $authors[] = new $this->author_class($name, $uri, $email, $avatar);
2456 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2461 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2463 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2465 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2467 $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]));
2469 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2471 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2473 if ($name !== null || $email !== null || $url !== null)
2475 $authors[] = new $this->author_class($name, $url, $email);
2478 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2480 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2482 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2484 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2486 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2488 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2491 if (!empty($authors))
2493 return SimplePie_Misc::array_unique($authors);
2501 function get_contributor($key = 0)
2503 $contributors = $this->get_contributors();
2504 if (isset($contributors[$key]))
2506 return $contributors[$key];
2514 function get_contributors()
2516 $contributors = array();
2517 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2522 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2524 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2526 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2528 $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]));
2530 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2532 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2534 if ($name !== null || $email !== null || $uri !== null)
2536 $contributors[] = new $this->author_class($name, $uri, $email);
2539 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2544 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2546 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2548 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2550 $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]));
2552 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2554 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2556 if ($name !== null || $email !== null || $url !== null)
2558 $contributors[] = new $this->author_class($name, $url, $email);
2562 if (!empty($contributors))
2564 return SimplePie_Misc::array_unique($contributors);
2572 function get_link($key = 0, $rel = 'alternate')
2574 $links = $this->get_links($rel);
2575 if (isset($links[$key]))
2577 return $links[$key];
2586 * Added for parity between the parent-level and the item/entry-level.
2588 function get_permalink()
2590 return $this->get_link(0);
2593 function get_links($rel = 'alternate')
2595 if (!isset($this->data['links']))
2597 $this->data['links'] = array();
2598 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2600 foreach ($links as $link)
2602 if (isset($link['attribs']['']['href']))
2604 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2605 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2609 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2611 foreach ($links as $link)
2613 if (isset($link['attribs']['']['href']))
2615 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2616 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2621 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2623 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2625 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2627 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2629 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2631 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2634 $keys = array_keys($this->data['links']);
2635 foreach ($keys as $key)
2637 if (SimplePie_Misc::is_isegment_nz_nc($key))
2639 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2641 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2642 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2646 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2649 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2651 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2653 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2657 if (isset($this->data['links'][$rel]))
2659 return $this->data['links'][$rel];
2667 function get_all_discovered_feeds()
2669 return $this->all_discovered_feeds;
2672 function get_description()
2674 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2676 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2678 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2680 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2684 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2686 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2688 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2690 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2692 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2694 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2698 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2700 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2702 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2704 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2706 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2708 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2716 function get_copyright()
2718 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2720 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2722 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2724 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2726 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2728 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2730 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2732 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2734 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2736 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2744 function get_language()
2746 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2748 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2750 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2752 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2754 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2756 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2758 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2760 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2762 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2764 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2766 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2768 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2770 elseif (isset($this->data['headers']['content-language']))
2772 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2780 function get_latitude()
2783 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2785 return (float) $return[0]['data'];
2787 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2789 return (float) $match[1];
2797 function get_longitude()
2799 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2801 return (float) $return[0]['data'];
2803 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2805 return (float) $return[0]['data'];
2807 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2809 return (float) $match[2];
2817 function get_image_title()
2819 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2821 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2823 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2825 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2827 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2829 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2831 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2833 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2835 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2837 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2845 function get_image_url()
2847 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2849 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2851 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2853 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2855 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2857 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2859 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2861 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2863 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2865 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2867 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2869 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2877 function get_image_link()
2879 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2881 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2883 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2885 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2887 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2889 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2897 function get_image_width()
2899 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2901 return round($return[0]['data']);
2903 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2913 function get_image_height()
2915 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2917 return round($return[0]['data']);
2919 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2929 function get_item_quantity($max = 0)
2932 $qty = count($this->get_items());
2939 return ($qty > $max) ? $max : $qty;
2943 function get_item($key = 0)
2945 $items = $this->get_items();
2946 if (isset($items[$key]))
2948 return $items[$key];
2956 function get_items($start = 0, $end = 0)
2958 if (!isset($this->data['items']))
2960 if (!empty($this->multifeed_objects))
2962 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2966 $this->data['items'] = array();
2967 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2969 $keys = array_keys($items);
2970 foreach ($keys as $key)
2972 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2975 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2977 $keys = array_keys($items);
2978 foreach ($keys as $key)
2980 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2983 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2985 $keys = array_keys($items);
2986 foreach ($keys as $key)
2988 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2991 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2993 $keys = array_keys($items);
2994 foreach ($keys as $key)
2996 $this->data['items'][] = new $this->item_class($this, $items[$key]);
2999 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
3001 $keys = array_keys($items);
3002 foreach ($keys as $key)
3004 $this->data['items'][] = new $this->item_class($this, $items[$key]);
3010 if (!empty($this->data['items']))
3012 // If we want to order it by date, check if all items have a date, and then sort it
3013 if ($this->order_by_date && empty($this->multifeed_objects))
3015 if (!isset($this->data['ordered_items']))
3018 foreach ($this->data['items'] as $item)
3020 if (!$item->get_date('U'))
3027 $this->data['ordered_items'] = $this->data['items'];
3030 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3033 $items = $this->data['ordered_items'];
3037 $items = $this->data['items'];
3040 // Slice the data as desired
3043 return array_slice($items, $start);
3047 return array_slice($items, $start, $end);
3059 function sort_items($a, $b)
3061 return $a->get_date('U') <= $b->get_date('U');
3067 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3069 if (is_array($urls) && sizeof($urls) > 0)
3072 foreach ($urls as $arg)
3074 if (is_a($arg, 'SimplePie'))
3076 $items = array_merge($items, $arg->get_items(0, $limit));
3080 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3085 foreach ($items as $item)
3087 if (!$item->get_date('U'))
3096 usort($items, array('SimplePie', 'sort_items'));
3101 return array_slice($items, $start);
3105 return array_slice($items, $start, $end);
3110 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3116 class SimplePie_Item
3119 var $data = array();
3121 function SimplePie_Item($feed, $data)
3123 $this->feed = $feed;
3124 $this->data = $data;
3127 function __toString()
3129 return md5(serialize($this->data));
3133 * Remove items that link back to this before destroying this object
3135 function __destruct()
3137 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3143 function get_item_tags($namespace, $tag)
3145 if (isset($this->data['child'][$namespace][$tag]))
3147 return $this->data['child'][$namespace][$tag];
3155 function get_base($element = array())
3157 return $this->feed->get_base($element);
3160 function sanitize($data, $type, $base = '')
3162 return $this->feed->sanitize($data, $type, $base);
3170 function get_id($hash = false)
3174 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3176 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3178 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3182 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3184 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3186 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3188 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3190 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3192 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3194 elseif (($return = $this->get_permalink()) !== null)
3198 elseif (($return = $this->get_title()) !== null)
3203 if ($this->get_permalink() !== null || $this->get_title() !== null)
3205 return md5($this->get_permalink() . $this->get_title());
3209 return md5(serialize($this->data));
3213 function get_title()
3215 if (!isset($this->data['title']))
3217 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3219 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3221 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3223 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3225 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3227 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3229 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3231 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3233 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3235 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3237 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3239 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3241 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3243 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3247 $this->data['title'] = null;
3250 return $this->data['title'];
3253 function get_description($description_only = false)
3255 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3257 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3259 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3261 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3263 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3265 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3267 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
3269 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3271 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3273 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3275 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3277 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3279 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3281 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3283 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3285 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3287 elseif (!$description_only)
3289 return $this->get_content(true);
3297 function get_content($content_only = false)
3299 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3301 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3303 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3305 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3307 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3309 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3311 elseif (!$content_only)
3313 return $this->get_description(true);
3321 function get_category($key = 0)
3323 $categories = $this->get_categories();
3324 if (isset($categories[$key]))
3326 return $categories[$key];
3334 function get_categories()
3336 $categories = array();
3338 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3343 if (isset($category['attribs']['']['term']))
3345 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3347 if (isset($category['attribs']['']['scheme']))
3349 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3351 if (isset($category['attribs']['']['label']))
3353 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3355 $categories[] = new $this->feed->category_class($term, $scheme, $label);
3357 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
3359 // This is really the label, but keep this as the term also for BC.
3360 // Label will also work on retrieving because that falls back to term.
3361 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3362 if (isset($category['attribs']['']['domain']))
3364 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
3370 $categories[] = new $this->feed->category_class($term, $scheme, null);
3372 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3374 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3376 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3378 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3381 if (!empty($categories))
3383 return SimplePie_Misc::array_unique($categories);
3391 function get_author($key = 0)
3393 $authors = $this->get_authors();
3394 if (isset($authors[$key]))
3396 return $authors[$key];
3404 function get_contributor($key = 0)
3406 $contributors = $this->get_contributors();
3407 if (isset($contributors[$key]))
3409 return $contributors[$key];
3417 function get_contributors()
3419 $contributors = array();
3420 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3425 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3427 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3429 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3431 $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]));
3433 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3435 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3437 if ($name !== null || $email !== null || $uri !== null)
3439 $contributors[] = new $this->feed->author_class($name, $uri, $email);
3442 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3447 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3449 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3451 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3453 $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]));
3455 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3457 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3459 if ($name !== null || $email !== null || $url !== null)
3461 $contributors[] = new $this->feed->author_class($name, $url, $email);
3465 if (!empty($contributors))
3467 return SimplePie_Misc::array_unique($contributors);
3475 function get_authors()
3478 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3484 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3486 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3488 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3490 $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]));
3492 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3494 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3496 if (isset($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]['data']))
3498 $avatar = $this->sanitize($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]));
3500 if ($name !== null || $email !== null || $uri !== null || $avatar !== null)
3502 $authors[] = new $this->feed->author_class($name, $uri, $email, $avatar);
3506 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3511 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3513 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3515 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3517 $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]));
3519 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3521 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3523 if ($name !== null || $email !== null || $url !== null)
3525 $authors[] = new $this->feed->author_class($name, $url, $email);
3528 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
3530 $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3532 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3534 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3536 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3538 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3540 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3542 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3545 if (!empty($authors))
3547 return SimplePie_Misc::array_unique($authors);
3549 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3553 elseif ($authors = $this->feed->get_authors())
3563 function get_copyright()
3565 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3567 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3569 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3571 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3573 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3575 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3583 function get_date($date_format = 'j F Y, g:i a')
3585 if (!isset($this->data['date']))
3587 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3589 $this->data['date']['raw'] = $return[0]['data'];
3591 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3593 $this->data['date']['raw'] = $return[0]['data'];
3595 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3597 $this->data['date']['raw'] = $return[0]['data'];
3599 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3601 $this->data['date']['raw'] = $return[0]['data'];
3603 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3605 $this->data['date']['raw'] = $return[0]['data'];
3607 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
3609 $this->data['date']['raw'] = $return[0]['data'];
3611 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3613 $this->data['date']['raw'] = $return[0]['data'];
3615 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3617 $this->data['date']['raw'] = $return[0]['data'];
3620 if (!empty($this->data['date']['raw']))
3622 $parser = SimplePie_Parse_Date::get();
3623 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3627 $this->data['date'] = null;
3630 if ($this->data['date'])
3632 $date_format = (string) $date_format;
3633 switch ($date_format)
3636 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3639 return $this->data['date']['parsed'];
3642 return date($date_format, $this->data['date']['parsed']);
3651 function get_local_date($date_format = '%c')
3655 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3657 elseif (($date = $this->get_date('U')) !== null)
3659 return strftime($date_format, $date);
3667 function get_permalink()
3669 $link = $this->get_link();
3670 $enclosure = $this->get_enclosure(0);
3675 elseif ($enclosure !== null)
3677 return $enclosure->get_link();
3685 function get_link($key = 0, $rel = 'alternate')
3687 $links = $this->get_links($rel);
3688 if ($links[$key] !== null)
3690 return $links[$key];
3698 function get_links($rel = 'alternate')
3700 if (!isset($this->data['links']))
3702 $this->data['links'] = array();
3703 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3705 if (isset($link['attribs']['']['href']))
3707 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3708 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3712 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3714 if (isset($link['attribs']['']['href']))
3716 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3717 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3720 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3722 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3724 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3726 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3728 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
3730 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3732 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3734 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
3736 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3740 $keys = array_keys($this->data['links']);
3741 foreach ($keys as $key)
3743 if (SimplePie_Misc::is_isegment_nz_nc($key))
3745 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3747 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3748 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3752 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3755 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3757 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3759 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3762 if (isset($this->data['links'][$rel]))
3764 return $this->data['links'][$rel];
3773 * @todo Add ability to prefer one type of content over another (in a media group).
3775 function get_enclosure($key = 0, $prefer = null)
3777 $enclosures = $this->get_enclosures();
3778 if (isset($enclosures[$key]))
3780 return $enclosures[$key];
3789 * Grabs all available enclosures (podcasts, etc.)
3791 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3793 * 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.
3795 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3796 * @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).
3798 function get_enclosures()
3800 if (!isset($this->data['enclosures']))
3802 $this->data['enclosures'] = array();
3805 $captions_parent = null;
3806 $categories_parent = null;
3807 $copyrights_parent = null;
3808 $credits_parent = null;
3809 $description_parent = null;
3810 $duration_parent = null;
3811 $hashes_parent = null;
3812 $keywords_parent = null;
3813 $player_parent = null;
3814 $ratings_parent = null;
3815 $restrictions_parent = null;
3816 $thumbnails_parent = null;
3817 $title_parent = null;
3819 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3820 $parent = $this->get_feed();
3823 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3825 foreach ($captions as $caption)
3827 $caption_type = null;
3828 $caption_lang = null;
3829 $caption_startTime = null;
3830 $caption_endTime = null;
3831 $caption_text = null;
3832 if (isset($caption['attribs']['']['type']))
3834 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3836 if (isset($caption['attribs']['']['lang']))
3838 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3840 if (isset($caption['attribs']['']['start']))
3842 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3844 if (isset($caption['attribs']['']['end']))
3846 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3848 if (isset($caption['data']))
3850 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3852 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3855 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3857 foreach ($captions as $caption)
3859 $caption_type = null;
3860 $caption_lang = null;
3861 $caption_startTime = null;
3862 $caption_endTime = null;
3863 $caption_text = null;
3864 if (isset($caption['attribs']['']['type']))
3866 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3868 if (isset($caption['attribs']['']['lang']))
3870 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3872 if (isset($caption['attribs']['']['start']))
3874 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3876 if (isset($caption['attribs']['']['end']))
3878 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3880 if (isset($caption['data']))
3882 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3884 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3887 if (is_array($captions_parent))
3889 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3893 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3898 if (isset($category['data']))
3900 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3902 if (isset($category['attribs']['']['scheme']))
3904 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3908 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3910 if (isset($category['attribs']['']['label']))
3912 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3914 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3916 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3921 if (isset($category['data']))
3923 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3925 if (isset($category['attribs']['']['scheme']))
3927 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3931 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3933 if (isset($category['attribs']['']['label']))
3935 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3937 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3939 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3942 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3944 if (isset($category['attribs']['']['text']))
3946 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3948 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3950 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3952 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3954 if (isset($subcategory['attribs']['']['text']))
3956 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3958 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3962 if (is_array($categories_parent))
3964 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3968 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3970 $copyright_url = null;
3971 $copyright_label = null;
3972 if (isset($copyright[0]['attribs']['']['url']))
3974 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3976 if (isset($copyright[0]['data']))
3978 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3980 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3982 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3984 $copyright_url = null;
3985 $copyright_label = null;
3986 if (isset($copyright[0]['attribs']['']['url']))
3988 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3990 if (isset($copyright[0]['data']))
3992 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3994 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3998 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4000 foreach ($credits as $credit)
4002 $credit_role = null;
4003 $credit_scheme = null;
4004 $credit_name = null;
4005 if (isset($credit['attribs']['']['role']))
4007 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4009 if (isset($credit['attribs']['']['scheme']))
4011 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4015 $credit_scheme = 'urn:ebu';
4017 if (isset($credit['data']))
4019 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4021 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4024 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4026 foreach ($credits as $credit)
4028 $credit_role = null;
4029 $credit_scheme = null;
4030 $credit_name = null;
4031 if (isset($credit['attribs']['']['role']))
4033 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4035 if (isset($credit['attribs']['']['scheme']))
4037 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4041 $credit_scheme = 'urn:ebu';
4043 if (isset($credit['data']))
4045 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4047 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4050 if (is_array($credits_parent))
4052 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4056 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4058 if (isset($description_parent[0]['data']))
4060 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4063 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4065 if (isset($description_parent[0]['data']))
4067 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4072 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4077 if (isset($duration_parent[0]['data']))
4079 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4080 if (sizeof($temp) > 0)
4082 (int) $seconds = array_pop($temp);
4084 if (sizeof($temp) > 0)
4086 (int) $minutes = array_pop($temp);
4087 $seconds += $minutes * 60;
4089 if (sizeof($temp) > 0)
4091 (int) $hours = array_pop($temp);
4092 $seconds += $hours * 3600;
4095 $duration_parent = $seconds;
4100 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4102 foreach ($hashes_iterator as $hash)
4106 if (isset($hash['data']))
4108 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4110 if (isset($hash['attribs']['']['algo']))
4112 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4118 $hashes_parent[] = $algo.':'.$value;
4121 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4123 foreach ($hashes_iterator as $hash)
4127 if (isset($hash['data']))
4129 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4131 if (isset($hash['attribs']['']['algo']))
4133 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4139 $hashes_parent[] = $algo.':'.$value;
4142 if (is_array($hashes_parent))
4144 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4148 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4150 if (isset($keywords[0]['data']))
4152 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4153 foreach ($temp as $word)
4155 $keywords_parent[] = trim($word);
4160 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4162 if (isset($keywords[0]['data']))
4164 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4165 foreach ($temp as $word)
4167 $keywords_parent[] = trim($word);
4172 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4174 if (isset($keywords[0]['data']))
4176 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4177 foreach ($temp as $word)
4179 $keywords_parent[] = trim($word);
4184 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4186 if (isset($keywords[0]['data']))
4188 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4189 foreach ($temp as $word)
4191 $keywords_parent[] = trim($word);
4196 if (is_array($keywords_parent))
4198 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4202 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4204 if (isset($player_parent[0]['attribs']['']['url']))
4206 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4209 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4211 if (isset($player_parent[0]['attribs']['']['url']))
4213 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4218 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4220 foreach ($ratings as $rating)
4222 $rating_scheme = null;
4223 $rating_value = null;
4224 if (isset($rating['attribs']['']['scheme']))
4226 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4230 $rating_scheme = 'urn:simple';
4232 if (isset($rating['data']))
4234 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4236 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4239 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4241 foreach ($ratings as $rating)
4243 $rating_scheme = 'urn:itunes';
4244 $rating_value = null;
4245 if (isset($rating['data']))
4247 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4249 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4252 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4254 foreach ($ratings as $rating)
4256 $rating_scheme = null;
4257 $rating_value = null;
4258 if (isset($rating['attribs']['']['scheme']))
4260 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4264 $rating_scheme = 'urn:simple';
4266 if (isset($rating['data']))
4268 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4270 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4273 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4275 foreach ($ratings as $rating)
4277 $rating_scheme = 'urn:itunes';
4278 $rating_value = null;
4279 if (isset($rating['data']))
4281 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4283 $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4286 if (is_array($ratings_parent))
4288 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4292 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4294 foreach ($restrictions as $restriction)
4296 $restriction_relationship = null;
4297 $restriction_type = null;
4298 $restriction_value = null;
4299 if (isset($restriction['attribs']['']['relationship']))
4301 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4303 if (isset($restriction['attribs']['']['type']))
4305 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4307 if (isset($restriction['data']))
4309 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4311 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4314 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4316 foreach ($restrictions as $restriction)
4318 $restriction_relationship = 'allow';
4319 $restriction_type = null;
4320 $restriction_value = 'itunes';
4321 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4323 $restriction_relationship = 'deny';
4325 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4328 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4330 foreach ($restrictions as $restriction)
4332 $restriction_relationship = null;
4333 $restriction_type = null;
4334 $restriction_value = null;
4335 if (isset($restriction['attribs']['']['relationship']))
4337 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4339 if (isset($restriction['attribs']['']['type']))
4341 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4343 if (isset($restriction['data']))
4345 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4347 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4350 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4352 foreach ($restrictions as $restriction)
4354 $restriction_relationship = 'allow';
4355 $restriction_type = null;
4356 $restriction_value = 'itunes';
4357 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4359 $restriction_relationship = 'deny';
4361 $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4364 if (is_array($restrictions_parent))
4366 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4370 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4372 foreach ($thumbnails as $thumbnail)
4374 if (isset($thumbnail['attribs']['']['url']))
4376 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4380 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4382 foreach ($thumbnails as $thumbnail)
4384 if (isset($thumbnail['attribs']['']['url']))
4386 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4392 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4394 if (isset($title_parent[0]['data']))
4396 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4399 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4401 if (isset($title_parent[0]['data']))
4403 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4421 $samplingrate = null;
4431 $description = null;
4436 $restrictions = null;
4440 // If we have media:group tags, loop through them.
4441 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4443 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4445 // If we have media:content tags, loop through them.
4446 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4448 if (isset($content['attribs']['']['url']))
4461 $samplingrate = null;
4471 $description = null;
4476 $restrictions = null;
4480 // Start checking the attributes of media:content
4481 if (isset($content['attribs']['']['bitrate']))
4483 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4485 if (isset($content['attribs']['']['channels']))
4487 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4489 if (isset($content['attribs']['']['duration']))
4491 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4495 $duration = $duration_parent;
4497 if (isset($content['attribs']['']['expression']))
4499 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4501 if (isset($content['attribs']['']['framerate']))
4503 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4505 if (isset($content['attribs']['']['height']))
4507 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4509 if (isset($content['attribs']['']['lang']))
4511 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4513 if (isset($content['attribs']['']['fileSize']))
4515 $length = ceil($content['attribs']['']['fileSize']);
4517 if (isset($content['attribs']['']['medium']))
4519 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4521 if (isset($content['attribs']['']['samplingrate']))
4523 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4525 if (isset($content['attribs']['']['type']))
4527 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4529 if (isset($content['attribs']['']['width']))
4531 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4533 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4535 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4538 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4540 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4542 $caption_type = null;
4543 $caption_lang = null;
4544 $caption_startTime = null;
4545 $caption_endTime = null;
4546 $caption_text = null;
4547 if (isset($caption['attribs']['']['type']))
4549 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4551 if (isset($caption['attribs']['']['lang']))
4553 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4555 if (isset($caption['attribs']['']['start']))
4557 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4559 if (isset($caption['attribs']['']['end']))
4561 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4563 if (isset($caption['data']))
4565 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4567 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4569 if (is_array($captions))
4571 $captions = array_values(SimplePie_Misc::array_unique($captions));
4574 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4576 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4578 $caption_type = null;
4579 $caption_lang = null;
4580 $caption_startTime = null;
4581 $caption_endTime = null;
4582 $caption_text = null;
4583 if (isset($caption['attribs']['']['type']))
4585 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4587 if (isset($caption['attribs']['']['lang']))
4589 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4591 if (isset($caption['attribs']['']['start']))
4593 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4595 if (isset($caption['attribs']['']['end']))
4597 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4599 if (isset($caption['data']))
4601 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4603 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4605 if (is_array($captions))
4607 $captions = array_values(SimplePie_Misc::array_unique($captions));
4612 $captions = $captions_parent;
4616 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4618 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4623 if (isset($category['data']))
4625 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4627 if (isset($category['attribs']['']['scheme']))
4629 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4633 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4635 if (isset($category['attribs']['']['label']))
4637 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4639 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4642 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4644 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4649 if (isset($category['data']))
4651 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4653 if (isset($category['attribs']['']['scheme']))
4655 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4659 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4661 if (isset($category['attribs']['']['label']))
4663 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4665 $categories[] = new $this->feed->category_class($term, $scheme, $label);
4668 if (is_array($categories) && is_array($categories_parent))
4670 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4672 elseif (is_array($categories))
4674 $categories = array_values(SimplePie_Misc::array_unique($categories));
4676 elseif (is_array($categories_parent))
4678 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4682 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4684 $copyright_url = null;
4685 $copyright_label = null;
4686 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4688 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4690 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4692 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4694 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4696 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4698 $copyright_url = null;
4699 $copyright_label = null;
4700 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4702 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4704 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4706 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4708 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4712 $copyrights = $copyrights_parent;
4716 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4718 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4720 $credit_role = null;
4721 $credit_scheme = null;
4722 $credit_name = null;
4723 if (isset($credit['attribs']['']['role']))
4725 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4727 if (isset($credit['attribs']['']['scheme']))
4729 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4733 $credit_scheme = 'urn:ebu';
4735 if (isset($credit['data']))
4737 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4739 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4741 if (is_array($credits))
4743 $credits = array_values(SimplePie_Misc::array_unique($credits));
4746 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4748 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4750 $credit_role = null;
4751 $credit_scheme = null;
4752 $credit_name = null;
4753 if (isset($credit['attribs']['']['role']))
4755 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4757 if (isset($credit['attribs']['']['scheme']))
4759 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4763 $credit_scheme = 'urn:ebu';
4765 if (isset($credit['data']))
4767 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4769 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4771 if (is_array($credits))
4773 $credits = array_values(SimplePie_Misc::array_unique($credits));
4778 $credits = $credits_parent;
4782 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4784 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4786 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4788 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4792 $description = $description_parent;
4796 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4798 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4802 if (isset($hash['data']))
4804 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4806 if (isset($hash['attribs']['']['algo']))
4808 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4814 $hashes[] = $algo.':'.$value;
4816 if (is_array($hashes))
4818 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4821 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4823 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4827 if (isset($hash['data']))
4829 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4831 if (isset($hash['attribs']['']['algo']))
4833 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4839 $hashes[] = $algo.':'.$value;
4841 if (is_array($hashes))
4843 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4848 $hashes = $hashes_parent;
4852 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4854 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4856 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4857 foreach ($temp as $word)
4859 $keywords[] = trim($word);
4863 if (is_array($keywords))
4865 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4868 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4870 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4872 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4873 foreach ($temp as $word)
4875 $keywords[] = trim($word);
4879 if (is_array($keywords))
4881 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4886 $keywords = $keywords_parent;
4890 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4892 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4894 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4896 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4900 $player = $player_parent;
4904 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4906 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4908 $rating_scheme = null;
4909 $rating_value = null;
4910 if (isset($rating['attribs']['']['scheme']))
4912 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4916 $rating_scheme = 'urn:simple';
4918 if (isset($rating['data']))
4920 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4922 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4924 if (is_array($ratings))
4926 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4929 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4931 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4933 $rating_scheme = null;
4934 $rating_value = null;
4935 if (isset($rating['attribs']['']['scheme']))
4937 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4941 $rating_scheme = 'urn:simple';
4943 if (isset($rating['data']))
4945 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4947 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4949 if (is_array($ratings))
4951 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4956 $ratings = $ratings_parent;
4960 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4962 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4964 $restriction_relationship = null;
4965 $restriction_type = null;
4966 $restriction_value = null;
4967 if (isset($restriction['attribs']['']['relationship']))
4969 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4971 if (isset($restriction['attribs']['']['type']))
4973 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4975 if (isset($restriction['data']))
4977 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4979 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4981 if (is_array($restrictions))
4983 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4986 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4988 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4990 $restriction_relationship = null;
4991 $restriction_type = null;
4992 $restriction_value = null;
4993 if (isset($restriction['attribs']['']['relationship']))
4995 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4997 if (isset($restriction['attribs']['']['type']))
4999 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5001 if (isset($restriction['data']))
5003 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5005 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5007 if (is_array($restrictions))
5009 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5014 $restrictions = $restrictions_parent;
5018 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5020 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5022 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5024 if (is_array($thumbnails))
5026 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5029 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5031 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5033 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5035 if (is_array($thumbnails))
5037 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5042 $thumbnails = $thumbnails_parent;
5046 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5048 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5050 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5052 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5056 $title = $title_parent;
5059 $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);
5065 // If we have standalone media:content tags, loop through them.
5066 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5068 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5070 if (isset($content['attribs']['']['url']))
5083 $samplingrate = null;
5093 $description = null;
5098 $restrictions = null;
5102 // Start checking the attributes of media:content
5103 if (isset($content['attribs']['']['bitrate']))
5105 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5107 if (isset($content['attribs']['']['channels']))
5109 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5111 if (isset($content['attribs']['']['duration']))
5113 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5117 $duration = $duration_parent;
5119 if (isset($content['attribs']['']['expression']))
5121 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5123 if (isset($content['attribs']['']['framerate']))
5125 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5127 if (isset($content['attribs']['']['height']))
5129 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5131 if (isset($content['attribs']['']['lang']))
5133 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5135 if (isset($content['attribs']['']['fileSize']))
5137 $length = ceil($content['attribs']['']['fileSize']);
5139 if (isset($content['attribs']['']['medium']))
5141 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5143 if (isset($content['attribs']['']['samplingrate']))
5145 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5147 if (isset($content['attribs']['']['type']))
5149 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5151 if (isset($content['attribs']['']['width']))
5153 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5155 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5157 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5160 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5162 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5164 $caption_type = null;
5165 $caption_lang = null;
5166 $caption_startTime = null;
5167 $caption_endTime = null;
5168 $caption_text = null;
5169 if (isset($caption['attribs']['']['type']))
5171 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5173 if (isset($caption['attribs']['']['lang']))
5175 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5177 if (isset($caption['attribs']['']['start']))
5179 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5181 if (isset($caption['attribs']['']['end']))
5183 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5185 if (isset($caption['data']))
5187 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5189 $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5191 if (is_array($captions))
5193 $captions = array_values(SimplePie_Misc::array_unique($captions));
5198 $captions = $captions_parent;
5202 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5204 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5209 if (isset($category['data']))
5211 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5213 if (isset($category['attribs']['']['scheme']))
5215 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5219 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5221 if (isset($category['attribs']['']['label']))
5223 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5225 $categories[] = new $this->feed->category_class($term, $scheme, $label);
5228 if (is_array($categories) && is_array($categories_parent))
5230 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5232 elseif (is_array($categories))
5234 $categories = array_values(SimplePie_Misc::array_unique($categories));
5236 elseif (is_array($categories_parent))
5238 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5246 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5248 $copyright_url = null;
5249 $copyright_label = null;
5250 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5252 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5254 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5256 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5258 $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
5262 $copyrights = $copyrights_parent;
5266 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5268 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5270 $credit_role = null;
5271 $credit_scheme = null;
5272 $credit_name = null;
5273 if (isset($credit['attribs']['']['role']))
5275 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5277 if (isset($credit['attribs']['']['scheme']))
5279 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5283 $credit_scheme = 'urn:ebu';
5285 if (isset($credit['data']))
5287 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5289 $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5291 if (is_array($credits))
5293 $credits = array_values(SimplePie_Misc::array_unique($credits));
5298 $credits = $credits_parent;
5302 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5304 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5308 $description = $description_parent;
5312 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5314 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5318 if (isset($hash['data']))
5320 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5322 if (isset($hash['attribs']['']['algo']))
5324 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5330 $hashes[] = $algo.':'.$value;
5332 if (is_array($hashes))
5334 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5339 $hashes = $hashes_parent;
5343 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5345 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5347 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5348 foreach ($temp as $word)
5350 $keywords[] = trim($word);
5354 if (is_array($keywords))
5356 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5361 $keywords = $keywords_parent;
5365 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5367 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5371 $player = $player_parent;
5375 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5377 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5379 $rating_scheme = null;
5380 $rating_value = null;
5381 if (isset($rating['attribs']['']['scheme']))
5383 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5387 $rating_scheme = 'urn:simple';
5389 if (isset($rating['data']))
5391 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5393 $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
5395 if (is_array($ratings))
5397 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5402 $ratings = $ratings_parent;
5406 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5408 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5410 $restriction_relationship = null;
5411 $restriction_type = null;
5412 $restriction_value = null;
5413 if (isset($restriction['attribs']['']['relationship']))
5415 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5417 if (isset($restriction['attribs']['']['type']))
5419 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5421 if (isset($restriction['data']))
5423 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5425 $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5427 if (is_array($restrictions))
5429 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5434 $restrictions = $restrictions_parent;
5438 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5440 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5442 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5444 if (is_array($thumbnails))
5446 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5451 $thumbnails = $thumbnails_parent;
5455 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5457 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5461 $title = $title_parent;
5464 $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);
5469 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5471 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5484 $samplingrate = null;
5489 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5490 if (isset($link['attribs']['']['type']))
5492 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5494 if (isset($link['attribs']['']['length']))
5496 $length = ceil($link['attribs']['']['length']);
5499 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5500 $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);
5504 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5506 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5519 $samplingrate = null;
5524 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5525 if (isset($link['attribs']['']['type']))
5527 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5529 if (isset($link['attribs']['']['length']))
5531 $length = ceil($link['attribs']['']['length']);
5534 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5535 $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);
5539 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
5541 if (isset($enclosure[0]['attribs']['']['url']))
5554 $samplingrate = null;
5559 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5560 if (isset($enclosure[0]['attribs']['']['type']))
5562 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5564 if (isset($enclosure[0]['attribs']['']['length']))
5566 $length = ceil($enclosure[0]['attribs']['']['length']);
5569 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5570 $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);
5574 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))
5576 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5577 $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);
5580 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5582 if (!empty($this->data['enclosures']))
5584 return $this->data['enclosures'];
5592 function get_latitude()
5594 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5596 return (float) $return[0]['data'];
5598 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5600 return (float) $match[1];
5608 function get_longitude()
5610 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5612 return (float) $return[0]['data'];
5614 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5616 return (float) $return[0]['data'];
5618 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5620 return (float) $match[2];
5628 function get_source()
5630 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5632 return new $this->feed->source_class($this, $return[0]);
5641 * Creates the add_to_* methods' return data
5644 * @param string $item_url String to prefix to the item permalink
5645 * @param string $title_url String to prefix to the item title
5646 * (and suffix to the item permalink)
5647 * @return mixed URL if feed exists, false otherwise
5649 function add_to_service($item_url, $title_url = null, $summary_url = null)
5651 if ($this->get_permalink() !== null)
5653 $return = $item_url . rawurlencode($this->get_permalink());
5654 if ($title_url !== null && $this->get_title() !== null)
5656 $return .= $title_url . rawurlencode($this->get_title());
5658 if ($summary_url !== null && $this->get_description() !== null)
5660 $return .= $summary_url . rawurlencode($this->get_description());
5662 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
5670 function add_to_blinklist()
5672 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5675 function add_to_blogmarks()
5677 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5680 function add_to_delicious()
5682 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5685 function add_to_digg()
5687 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5690 function add_to_furl()
5692 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5695 function add_to_magnolia()
5697 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5700 function add_to_myweb20()
5702 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5705 function add_to_newsvine()
5707 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5710 function add_to_reddit()
5712 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5715 function add_to_segnalo()
5717 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5720 function add_to_simpy()
5722 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5725 function add_to_spurl()
5727 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5730 function add_to_wists()
5732 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5735 function search_technorati()
5737 return $this->add_to_service('http://www.technorati.com/search/');
5741 class SimplePie_Source
5744 var $data = array();
5746 function SimplePie_Source($item, $data)
5748 $this->item = $item;
5749 $this->data = $data;
5752 function __toString()
5754 return md5(serialize($this->data));
5757 function get_source_tags($namespace, $tag)
5759 if (isset($this->data['child'][$namespace][$tag]))
5761 return $this->data['child'][$namespace][$tag];
5769 function get_base($element = array())
5771 return $this->item->get_base($element);
5774 function sanitize($data, $type, $base = '')
5776 return $this->item->sanitize($data, $type, $base);
5784 function get_title()
5786 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5788 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5790 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5792 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5794 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5796 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5798 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5800 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5802 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
5804 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5806 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5808 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5810 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5812 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5820 function get_category($key = 0)
5822 $categories = $this->get_categories();
5823 if (isset($categories[$key]))
5825 return $categories[$key];
5833 function get_categories()
5835 $categories = array();
5837 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5842 if (isset($category['attribs']['']['term']))
5844 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5846 if (isset($category['attribs']['']['scheme']))
5848 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5850 if (isset($category['attribs']['']['label']))
5852 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5854 $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
5856 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
5858 // This is really the label, but keep this as the term also for BC.
5859 // Label will also work on retrieving because that falls back to term.
5860 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5861 if (isset($category['attribs']['']['domain']))
5863 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
5869 $categories[] = new $this->item->feed->category_class($term, $scheme, null);
5871 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5873 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5875 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5877 $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5880 if (!empty($categories))
5882 return SimplePie_Misc::array_unique($categories);
5890 function get_author($key = 0)
5892 $authors = $this->get_authors();
5893 if (isset($authors[$key]))
5895 return $authors[$key];
5903 function get_authors()
5906 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5912 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5914 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5916 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5918 $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]));
5920 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5922 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5925 $avatar = $this->sanitize($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child']['http://purl.org/macgirvin/dfrn/1.0']['avatar'][0]));
5927 if ($name !== null || $email !== null || $uri !== null || $avatar !== null)
5929 $authors[] = new $this->item->feed->author_class($name, $uri, $email, $avatar);
5933 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5938 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5940 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5942 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5944 $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]));
5946 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5948 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5950 if ($name !== null || $email !== null || $url !== null)
5952 $authors[] = new $this->item->feed->author_class($name, $url, $email);
5955 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5957 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5959 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5961 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5963 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5965 $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5968 if (!empty($authors))
5970 return SimplePie_Misc::array_unique($authors);
5978 function get_contributor($key = 0)
5980 $contributors = $this->get_contributors();
5981 if (isset($contributors[$key]))
5983 return $contributors[$key];
5991 function get_contributors()
5993 $contributors = array();
5994 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5999 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
6001 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6003 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
6005 $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]));
6007 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
6009 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6011 if ($name !== null || $email !== null || $uri !== null)
6013 $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
6016 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
6021 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
6023 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6025 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
6027 $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]));
6029 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
6031 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6033 if ($name !== null || $email !== null || $url !== null)
6035 $contributors[] = new $this->item->feed->author_class($name, $url, $email);
6039 if (!empty($contributors))
6041 return SimplePie_Misc::array_unique($contributors);
6049 function get_link($key = 0, $rel = 'alternate')
6051 $links = $this->get_links($rel);
6052 if (isset($links[$key]))
6054 return $links[$key];
6063 * Added for parity between the parent-level and the item/entry-level.
6065 function get_permalink()
6067 return $this->get_link(0);
6070 function get_links($rel = 'alternate')
6072 if (!isset($this->data['links']))
6074 $this->data['links'] = array();
6075 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6077 foreach ($links as $link)
6079 if (isset($link['attribs']['']['href']))
6081 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6082 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6086 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6088 foreach ($links as $link)
6090 if (isset($link['attribs']['']['href']))
6092 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6093 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6098 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6100 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6102 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6104 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6106 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
6108 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6111 $keys = array_keys($this->data['links']);
6112 foreach ($keys as $key)
6114 if (SimplePie_Misc::is_isegment_nz_nc($key))
6116 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6118 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6119 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6123 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6126 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6128 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6130 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6134 if (isset($this->data['links'][$rel]))
6136 return $this->data['links'][$rel];
6144 function get_description()
6146 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6148 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6150 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6152 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6154 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6156 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6158 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6160 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6162 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
6164 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6166 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6168 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6170 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6172 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6174 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6176 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6178 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6188 function get_copyright()
6190 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6192 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6194 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6196 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6198 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
6200 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6202 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6204 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6206 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6208 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6216 function get_language()
6218 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
6220 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6222 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6224 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6226 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6228 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6230 elseif (isset($this->data['xml_lang']))
6232 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6240 function get_latitude()
6242 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6244 return (float) $return[0]['data'];
6246 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
6248 return (float) $match[1];
6256 function get_longitude()
6258 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6260 return (float) $return[0]['data'];
6262 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6264 return (float) $return[0]['data'];
6266 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
6268 return (float) $match[2];
6276 function get_image_url()
6278 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6280 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6282 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6284 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6286 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6288 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6297 class SimplePie_Author
6304 // Constructor, used to input the data
6305 function SimplePie_Author($name = null, $link = null, $email = null, $avatar = null)
6307 $this->name = $name;
6308 $this->link = $link;
6309 $this->email = $email;
6310 $this->avatar = $avatar;
6313 function __toString()
6315 // There is no $this->data here
6316 return md5(serialize($this));
6321 if ($this->name !== null)
6333 if ($this->link !== null)
6343 function get_email()
6345 if ($this->email !== null)
6347 return $this->email;
6355 function get_avatar()
6357 if ($this->avatar !== null)
6359 return $this->avatar;
6370 class SimplePie_Category
6376 // Constructor, used to input the data
6377 function SimplePie_Category($term = null, $scheme = null, $label = null)
6379 $this->term = $term;
6380 $this->scheme = $scheme;
6381 $this->label = $label;
6384 function __toString()
6386 // There is no $this->data here
6387 return md5(serialize($this));
6392 if ($this->term !== null)
6402 function get_scheme()
6404 if ($this->scheme !== null)
6406 return $this->scheme;
6414 function get_label()
6416 if ($this->label !== null)
6418 return $this->label;
6422 return $this->get_term();
6427 class SimplePie_Enclosure
6457 // Constructor, used to input the data
6458 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)
6460 $this->bitrate = $bitrate;
6461 $this->captions = $captions;
6462 $this->categories = $categories;
6463 $this->channels = $channels;
6464 $this->copyright = $copyright;
6465 $this->credits = $credits;
6466 $this->description = $description;
6467 $this->duration = $duration;
6468 $this->expression = $expression;
6469 $this->framerate = $framerate;
6470 $this->hashes = $hashes;
6471 $this->height = $height;
6472 $this->javascript = $javascript;
6473 $this->keywords = $keywords;
6474 $this->lang = $lang;
6475 $this->length = $length;
6476 $this->link = $link;
6477 $this->medium = $medium;
6478 $this->player = $player;
6479 $this->ratings = $ratings;
6480 $this->restrictions = $restrictions;
6481 $this->samplingrate = $samplingrate;
6482 $this->thumbnails = $thumbnails;
6483 $this->title = $title;
6484 $this->type = $type;
6485 $this->width = $width;
6486 if (class_exists('idna_convert'))
6488 $idn = new idna_convert;
6489 $parsed = SimplePie_Misc::parse_url($link);
6490 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6492 $this->handler = $this->get_handler(); // Needs to load last
6495 function __toString()
6497 // There is no $this->data here
6498 return md5(serialize($this));
6501 function get_bitrate()
6503 if ($this->bitrate !== null)
6505 return $this->bitrate;
6513 function get_caption($key = 0)
6515 $captions = $this->get_captions();
6516 if (isset($captions[$key]))
6518 return $captions[$key];
6526 function get_captions()
6528 if ($this->captions !== null)
6530 return $this->captions;
6538 function get_category($key = 0)
6540 $categories = $this->get_categories();
6541 if (isset($categories[$key]))
6543 return $categories[$key];
6551 function get_categories()
6553 if ($this->categories !== null)
6555 return $this->categories;
6563 function get_channels()
6565 if ($this->channels !== null)
6567 return $this->channels;
6575 function get_copyright()
6577 if ($this->copyright !== null)
6579 return $this->copyright;
6587 function get_credit($key = 0)
6589 $credits = $this->get_credits();
6590 if (isset($credits[$key]))
6592 return $credits[$key];
6600 function get_credits()
6602 if ($this->credits !== null)
6604 return $this->credits;
6612 function get_description()
6614 if ($this->description !== null)
6616 return $this->description;
6624 function get_duration($convert = false)
6626 if ($this->duration !== null)
6630 $time = SimplePie_Misc::time_hms($this->duration);
6635 return $this->duration;
6644 function get_expression()
6646 if ($this->expression !== null)
6648 return $this->expression;
6656 function get_extension()
6658 if ($this->link !== null)
6660 $url = SimplePie_Misc::parse_url($this->link);
6661 if ($url['path'] !== '')
6663 return pathinfo($url['path'], PATHINFO_EXTENSION);
6669 function get_framerate()
6671 if ($this->framerate !== null)
6673 return $this->framerate;
6681 function get_handler()
6683 return $this->get_real_type(true);
6686 function get_hash($key = 0)
6688 $hashes = $this->get_hashes();
6689 if (isset($hashes[$key]))
6691 return $hashes[$key];
6699 function get_hashes()
6701 if ($this->hashes !== null)
6703 return $this->hashes;
6711 function get_height()
6713 if ($this->height !== null)
6715 return $this->height;
6723 function get_language()
6725 if ($this->lang !== null)
6735 function get_keyword($key = 0)
6737 $keywords = $this->get_keywords();
6738 if (isset($keywords[$key]))
6740 return $keywords[$key];
6748 function get_keywords()
6750 if ($this->keywords !== null)
6752 return $this->keywords;
6760 function get_length()
6762 if ($this->length !== null)
6764 return $this->length;
6774 if ($this->link !== null)
6776 return urldecode($this->link);
6784 function get_medium()
6786 if ($this->medium !== null)
6788 return $this->medium;
6796 function get_player()
6798 if ($this->player !== null)
6800 return $this->player;
6808 function get_rating($key = 0)
6810 $ratings = $this->get_ratings();
6811 if (isset($ratings[$key]))
6813 return $ratings[$key];
6821 function get_ratings()
6823 if ($this->ratings !== null)
6825 return $this->ratings;
6833 function get_restriction($key = 0)
6835 $restrictions = $this->get_restrictions();
6836 if (isset($restrictions[$key]))
6838 return $restrictions[$key];
6846 function get_restrictions()
6848 if ($this->restrictions !== null)
6850 return $this->restrictions;
6858 function get_sampling_rate()
6860 if ($this->samplingrate !== null)
6862 return $this->samplingrate;
6872 $length = $this->get_length();
6873 if ($length !== null)
6875 return round($length/1048576, 2);
6883 function get_thumbnail($key = 0)
6885 $thumbnails = $this->get_thumbnails();
6886 if (isset($thumbnails[$key]))
6888 return $thumbnails[$key];
6896 function get_thumbnails()
6898 if ($this->thumbnails !== null)
6900 return $this->thumbnails;
6908 function get_title()
6910 if ($this->title !== null)
6912 return $this->title;
6922 if ($this->type !== null)
6932 function get_width()
6934 if ($this->width !== null)
6936 return $this->width;
6944 function native_embed($options='')
6946 return $this->embed($options, true);
6950 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6952 function embed($options = '', $native = false)
6962 $bgcolor = '#ffffff';
6964 $widescreen = false;
6965 $handler = $this->get_handler();
6966 $type = $this->get_real_type();
6968 // Process options and reassign values as necessary
6969 if (is_array($options))
6975 $options = explode(',', $options);
6976 foreach($options as $option)
6978 $opt = explode(':', $option, 2);
6979 if (isset($opt[0], $opt[1]))
6981 $opt[0] = trim($opt[0]);
6982 $opt[1] = trim($opt[1]);
6998 $altclass = $opt[1];
7018 $mediaplayer = $opt[1];
7022 $widescreen = $opt[1];
7029 $mime = explode('/', $type, 2);
7032 // Process values for 'auto'
7033 if ($width === 'auto')
7035 if ($mime === 'video')
7037 if ($height === 'auto')
7041 elseif ($widescreen)
7043 $width = round((intval($height)/9)*16);
7047 $width = round((intval($height)/3)*4);
7056 if ($height === 'auto')
7058 if ($mime === 'audio')
7062 elseif ($mime === 'video')
7064 if ($width === 'auto')
7075 elseif ($widescreen)
7077 $height = round((intval($width)/16)*9);
7081 $height = round((intval($width)/4)*3);
7089 elseif ($mime === 'audio')
7094 // Set proper placeholder value
7095 if ($mime === 'audio')
7097 $placeholder = $audio;
7099 elseif ($mime === 'video')
7101 $placeholder = $video;
7106 // Make sure the JS library is included
7109 static $javascript_outputted = null;
7110 if (!$javascript_outputted && $this->javascript)
7112 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7113 $javascript_outputted = true;
7118 if ($handler === 'odeo')
7122 $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>';
7126 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7131 elseif ($handler === 'flash')
7135 $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>";
7139 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7143 // Flash Media Player file types.
7144 // Preferred handler for MP3 file types.
7145 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
7150 $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>";
7154 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7158 // QuickTime 7 file types. Need to test with QuickTime 6.
7159 // Only handle MP3's if the Flash Media Player is not present.
7160 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
7165 if ($placeholder !== '')
7167 $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>";
7171 $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>";
7176 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7181 elseif ($handler === 'wmedia')
7186 $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>";
7190 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7195 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7200 function get_real_type($find_handler = false)
7202 // If it's Odeo, let's get it out of the way.
7203 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
7208 // Mime-types by handler.
7209 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7210 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7211 $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
7212 $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
7213 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7215 if ($this->get_type() !== null)
7217 $type = strtolower($this->type);
7224 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7225 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7227 switch (strtolower($this->get_extension()))
7232 $type = 'audio/acc';
7239 $type = 'audio/aiff';
7243 $type = 'audio/wav';
7250 $type = 'audio/midi';
7254 $type = 'audio/x-m4a';
7259 $type = 'audio/mp3';
7263 $type = 'audio/wav';
7267 $type = 'audio/x-ms-wax';
7271 $type = 'audio/x-ms-wma';
7277 $type = 'video/3gpp';
7282 $type = 'video/3gpp2';
7286 $type = 'video/x-ms-asf';
7290 $type = 'video/x-flv';
7304 $type = 'video/mpeg';
7308 $type = 'video/x-m4v';
7313 $type = 'video/quicktime';
7318 $type = 'video/mp4';
7322 $type = 'video/sd-video';
7326 $type = 'video/x-ms-wm';
7330 $type = 'video/x-ms-wmv';
7334 $type = 'video/x-ms-wvx';
7339 $type = 'application/futuresplash';
7343 $type = 'application/x-shockwave-flash';
7350 if (in_array($type, $types_flash))
7354 elseif (in_array($type, $types_fmedia))
7358 elseif (in_array($type, $types_quicktime))
7362 elseif (in_array($type, $types_wmedia))
7366 elseif (in_array($type, $types_mp3))
7382 class SimplePie_Caption
7390 // Constructor, used to input the data
7391 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7393 $this->type = $type;
7394 $this->lang = $lang;
7395 $this->startTime = $startTime;
7396 $this->endTime = $endTime;
7397 $this->text = $text;
7400 function __toString()
7402 // There is no $this->data here
7403 return md5(serialize($this));
7406 function get_endtime()
7408 if ($this->endTime !== null)
7410 return $this->endTime;
7418 function get_language()
7420 if ($this->lang !== null)
7430 function get_starttime()
7432 if ($this->startTime !== null)
7434 return $this->startTime;
7444 if ($this->text !== null)
7456 if ($this->type !== null)
7467 class SimplePie_Credit
7473 // Constructor, used to input the data
7474 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7476 $this->role = $role;
7477 $this->scheme = $scheme;
7478 $this->name = $name;
7481 function __toString()
7483 // There is no $this->data here
7484 return md5(serialize($this));
7489 if ($this->role !== null)
7499 function get_scheme()
7501 if ($this->scheme !== null)
7503 return $this->scheme;
7513 if ($this->name !== null)
7524 class SimplePie_Copyright
7529 // Constructor, used to input the data
7530 function SimplePie_Copyright($url = null, $label = null)
7533 $this->label = $label;
7536 function __toString()
7538 // There is no $this->data here
7539 return md5(serialize($this));
7544 if ($this->url !== null)
7554 function get_attribution()
7556 if ($this->label !== null)
7558 return $this->label;
7567 class SimplePie_Rating
7572 // Constructor, used to input the data
7573 function SimplePie_Rating($scheme = null, $value = null)
7575 $this->scheme = $scheme;
7576 $this->value = $value;
7579 function __toString()
7581 // There is no $this->data here
7582 return md5(serialize($this));
7585 function get_scheme()
7587 if ($this->scheme !== null)
7589 return $this->scheme;
7597 function get_value()
7599 if ($this->value !== null)
7601 return $this->value;
7610 class SimplePie_Restriction
7616 // Constructor, used to input the data
7617 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7619 $this->relationship = $relationship;
7620 $this->type = $type;
7621 $this->value = $value;
7624 function __toString()
7626 // There is no $this->data here
7627 return md5(serialize($this));
7630 function get_relationship()
7632 if ($this->relationship !== null)
7634 return $this->relationship;
7644 if ($this->type !== null)
7654 function get_value()
7656 if ($this->value !== null)
7658 return $this->value;
7668 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7670 class SimplePie_File
7674 var $success = true;
7675 var $headers = array();
7680 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7682 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7684 if (class_exists('idna_convert'))
7686 $idn = new idna_convert;
7687 $parsed = SimplePie_Misc::parse_url($url);
7688 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7691 $this->useragent = $useragent;
7692 if (preg_match('/^http(s)?:\/\//i', $url))
7694 if ($useragent === null)
7696 $useragent = ini_get('user_agent');
7697 $this->useragent = $useragent;
7699 if (!is_array($headers))
7703 if (!$force_fsockopen && function_exists('curl_exec'))
7705 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7707 $headers2 = array();
7708 foreach ($headers as $key => $value)
7710 $headers2[] = "$key: $value";
7712 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7714 curl_setopt($fp, CURLOPT_ENCODING, '');
7716 curl_setopt($fp, CURLOPT_URL, $url);
7717 curl_setopt($fp, CURLOPT_HEADER, 1);
7718 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7719 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7720 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7721 curl_setopt($fp, CURLOPT_REFERER, $url);
7722 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7723 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7724 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7726 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7727 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7730 $this->headers = curl_exec($fp);
7731 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
7733 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7734 $this->headers = curl_exec($fp);
7736 if (curl_errno($fp))
7738 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7739 $this->success = false;
7743 $info = curl_getinfo($fp);
7745 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7746 $this->headers = array_pop($this->headers);
7747 $parser = new SimplePie_HTTP_Parser($this->headers);
7748 if ($parser->parse())
7750 $this->headers = $parser->headers;
7751 $this->body = $parser->body;
7752 $this->status_code = $parser->status_code;
7753 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7756 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7757 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7764 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7765 $url_parts = parse_url($url);
7766 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
7768 $url_parts['host'] = "ssl://$url_parts[host]";
7769 $url_parts['port'] = 443;
7771 if (!isset($url_parts['port']))
7773 $url_parts['port'] = 80;
7775 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7778 $this->error = 'fsockopen error: ' . $errstr;
7779 $this->success = false;
7783 stream_set_timeout($fp, $timeout);
7784 if (isset($url_parts['path']))
7786 if (isset($url_parts['query']))
7788 $get = "$url_parts[path]?$url_parts[query]";
7792 $get = $url_parts['path'];
7799 $out = "GET $get HTTP/1.0\r\n";
7800 $out .= "Host: $url_parts[host]\r\n";
7801 $out .= "User-Agent: $useragent\r\n";
7802 if (extension_loaded('zlib'))
7804 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7807 if (isset($url_parts['user']) && isset($url_parts['pass']))
7809 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7811 foreach ($headers as $key => $value)
7813 $out .= "$key: $value\r\n";
7815 $out .= "Connection: Close\r\n\r\n";
7818 $info = stream_get_meta_data($fp);
7820 $this->headers = '';
7821 while (!$info['eof'] && !$info['timed_out'])
7823 $this->headers .= fread($fp, 1160);
7824 $info = stream_get_meta_data($fp);
7826 if (!$info['timed_out'])
7828 $parser = new SimplePie_HTTP_Parser($this->headers);
7829 if ($parser->parse())
7831 $this->headers = $parser->headers;
7832 $this->body = $parser->body;
7833 $this->status_code = $parser->status_code;
7834 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7837 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7838 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7840 if (isset($this->headers['content-encoding']))
7842 // Hey, we act dumb elsewhere, so let's do that here too
7843 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7847 $decoder = new SimplePie_gzdecode($this->body);
7848 if (!$decoder->parse())
7850 $this->error = 'Unable to decode HTTP "gzip" stream';
7851 $this->success = false;
7855 $this->body = $decoder->data;
7860 if (($body = gzuncompress($this->body)) === false)
7862 if (($body = gzinflate($this->body)) === false)
7864 $this->error = 'Unable to decode HTTP "deflate" stream';
7865 $this->success = false;
7868 $this->body = $body;
7872 $this->error = 'Unknown content coding';
7873 $this->success = false;
7880 $this->error = 'fsocket timed out';
7881 $this->success = false;
7889 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7890 if (!$this->body = file_get_contents($url))
7892 $this->error = 'file_get_contents could not read the file';
7893 $this->success = false;
7900 * HTTP Response Parser
7902 * @package SimplePie
7904 class SimplePie_HTTP_Parser
7912 var $http_version = 0.0;
7920 var $status_code = 0;
7931 * Key/value pairs of the headers
7936 var $headers = array();
7939 * Body of the response
7947 * Current state of the state machine
7952 var $state = 'http_version';
7963 * Input data length (to avoid calling strlen() everytime this is needed)
7968 var $data_length = 0;
7971 * Current position of the pointer
7979 * Name of the hedaer currently being parsed
7987 * Value of the hedaer currently being parsed
7995 * Create an instance of the class with the input data
7998 * @param string $data Input data
8000 function SimplePie_HTTP_Parser($data)
8002 $this->data = $data;
8003 $this->data_length = strlen($this->data);
8007 * Parse the input data
8010 * @return bool true on success, false on failure
8014 while ($this->state && $this->state !== 'emit' && $this->has_data())
8016 $state = $this->state;
8020 if ($this->state === 'emit' || $this->state === 'body')
8026 $this->http_version = '';
8027 $this->status_code = '';
8029 $this->headers = array();
8036 * Check whether there is data beyond the pointer
8039 * @return bool true if there is further data, false if not
8043 return (bool) ($this->position < $this->data_length);
8047 * See if the next character is LWS
8050 * @return bool true if the next character is LWS, false if not
8052 function is_linear_whitespace()
8054 return (bool) ($this->data[$this->position] === "\x09"
8055 || $this->data[$this->position] === "\x20"
8056 || ($this->data[$this->position] === "\x0A"
8057 && isset($this->data[$this->position + 1])
8058 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8062 * Parse the HTTP version
8066 function http_version()
8068 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8070 $len = strspn($this->data, '0123456789.', 5);
8071 $this->http_version = substr($this->data, 5, $len);
8072 $this->position += 5 + $len;
8073 if (substr_count($this->http_version, '.') <= 1)
8075 $this->http_version = (float) $this->http_version;
8076 $this->position += strspn($this->data, "\x09\x20", $this->position);
8077 $this->state = 'status';
8081 $this->state = false;
8086 $this->state = false;
8091 * Parse the status code
8097 if ($len = strspn($this->data, '0123456789', $this->position))
8099 $this->status_code = (int) substr($this->data, $this->position, $len);
8100 $this->position += $len;
8101 $this->state = 'reason';
8105 $this->state = false;
8110 * Parse the reason phrase
8116 $len = strcspn($this->data, "\x0A", $this->position);
8117 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8118 $this->position += $len + 1;
8119 $this->state = 'new_line';
8123 * Deal with a new line, shifting data around as needed
8129 $this->value = trim($this->value, "\x0D\x20");
8130 if ($this->name !== '' && $this->value !== '')
8132 $this->name = strtolower($this->name);
8133 if (isset($this->headers[$this->name]))
8135 $this->headers[$this->name] .= ', ' . $this->value;
8139 $this->headers[$this->name] = $this->value;
8144 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8146 $this->position += 2;
8147 $this->state = 'body';
8149 elseif ($this->data[$this->position] === "\x0A")
8152 $this->state = 'body';
8156 $this->state = 'name';
8161 * Parse a header name
8167 $len = strcspn($this->data, "\x0A:", $this->position);
8168 if (isset($this->data[$this->position + $len]))
8170 if ($this->data[$this->position + $len] === "\x0A")
8172 $this->position += $len;
8173 $this->state = 'new_line';
8177 $this->name = substr($this->data, $this->position, $len);
8178 $this->position += $len + 1;
8179 $this->state = 'value';
8184 $this->state = false;
8189 * Parse LWS, replacing consecutive LWS characters with a single space
8193 function linear_whitespace()
8197 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8199 $this->position += 2;
8201 elseif ($this->data[$this->position] === "\x0A")
8205 $this->position += strspn($this->data, "\x09\x20", $this->position);
8206 } while ($this->has_data() && $this->is_linear_whitespace());
8207 $this->value .= "\x20";
8211 * See what state to move to while within non-quoted header values
8217 if ($this->is_linear_whitespace())
8219 $this->linear_whitespace();
8223 switch ($this->data[$this->position])
8227 $this->state = 'quote';
8232 $this->state = 'new_line';
8236 $this->state = 'value_char';
8243 * Parse a header value while outside quotes
8247 function value_char()
8249 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8250 $this->value .= substr($this->data, $this->position, $len);
8251 $this->position += $len;
8252 $this->state = 'value';
8256 * See what state to move to while within quoted header values
8262 if ($this->is_linear_whitespace())
8264 $this->linear_whitespace();
8268 switch ($this->data[$this->position])
8272 $this->state = 'value';
8277 $this->state = 'new_line';
8282 $this->state = 'quote_escaped';
8286 $this->state = 'quote_char';
8293 * Parse a header value while within quotes
8297 function quote_char()
8299 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8300 $this->value .= substr($this->data, $this->position, $len);
8301 $this->position += $len;
8302 $this->state = 'value';
8306 * Parse an escaped character within quotes
8310 function quote_escaped()
8312 $this->value .= $this->data[$this->position];
8314 $this->state = 'quote';
8324 $this->body = substr($this->data, $this->position);
8325 $this->state = 'emit';
8332 * @package SimplePie
8334 class SimplePie_gzdecode
8340 * @see gzdecode::$data
8342 var $compressed_data;
8345 * Size of compressed data
8349 var $compressed_size;
8352 * Minimum size of a valid gzip string
8356 var $min_compressed_size = 18;
8359 * Current position of pointer
8376 * @see gzdecode::$compressed_data
8405 * @see gzdecode::$extra_field
8406 * @see gzdecode::$SI2
8414 * @see gzdecode::$extra_field
8415 * @see gzdecode::$SI1
8420 * Extra field content
8423 * @see gzdecode::$SI1
8424 * @see gzdecode::$SI2
8436 * Human readable comment
8443 * Don't allow anything to be set
8447 function __set($name, $value)
8449 trigger_error("Cannot write property $name", E_USER_ERROR);
8453 * Set the compressed string and related properties
8457 function SimplePie_gzdecode($data)
8459 $this->compressed_data = $data;
8460 $this->compressed_size = strlen($data);
8464 * Decode the GZIP stream
8470 if ($this->compressed_size >= $this->min_compressed_size)
8472 // Check ID1, ID2, and CM
8473 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8478 // Get the FLG (FLaGs)
8479 $this->flags = ord($this->compressed_data[3]);
8481 // FLG bits above (1 << 4) are reserved
8482 if ($this->flags > 0x1F)
8487 // Advance the pointer after the above
8488 $this->position += 4;
8491 $mtime = substr($this->compressed_data, $this->position, 4);
8492 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8493 if (current(unpack('S', "\x00\x01")) === 1)
8495 $mtime = strrev($mtime);
8497 $this->MTIME = current(unpack('l', $mtime));
8498 $this->position += 4;
8500 // Get the XFL (eXtra FLags)
8501 $this->XFL = ord($this->compressed_data[$this->position++]);
8503 // Get the OS (Operating System)
8504 $this->OS = ord($this->compressed_data[$this->position++]);
8507 if ($this->flags & 4)
8509 // Read subfield IDs
8510 $this->SI1 = $this->compressed_data[$this->position++];
8511 $this->SI2 = $this->compressed_data[$this->position++];
8513 // SI2 set to zero is reserved for future use
8514 if ($this->SI2 === "\x00")
8519 // Get the length of the extra field
8520 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8523 // Check the length of the string is still valid
8524 $this->min_compressed_size += $len + 4;
8525 if ($this->compressed_size >= $this->min_compressed_size)
8527 // Set the extra field to the given data
8528 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8529 $this->position += $len;
8538 if ($this->flags & 8)
8540 // Get the length of the filename
8541 $len = strcspn($this->compressed_data, "\x00", $this->position);
8543 // Check the length of the string is still valid
8544 $this->min_compressed_size += $len + 1;
8545 if ($this->compressed_size >= $this->min_compressed_size)
8547 // Set the original filename to the given string
8548 $this->filename = substr($this->compressed_data, $this->position, $len);
8549 $this->position += $len + 1;
8557 // Parse the FCOMMENT
8558 if ($this->flags & 16)
8560 // Get the length of the comment
8561 $len = strcspn($this->compressed_data, "\x00", $this->position);
8563 // Check the length of the string is still valid
8564 $this->min_compressed_size += $len + 1;
8565 if ($this->compressed_size >= $this->min_compressed_size)
8567 // Set the original comment to the given string
8568 $this->comment = substr($this->compressed_data, $this->position, $len);
8569 $this->position += $len + 1;
8578 if ($this->flags & 2)
8580 // Check the length of the string is still valid
8581 $this->min_compressed_size += $len + 2;
8582 if ($this->compressed_size >= $this->min_compressed_size)
8585 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8587 // Check the CRC matches
8588 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8590 $this->position += 2;
8603 // Decompress the actual data
8604 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8610 $this->position = $this->compressed_size - 8;
8613 // Check CRC of data
8614 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8615 $this->position += 4;
8616 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8621 // Check ISIZE of data
8622 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8623 $this->position += 4;
8624 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8629 // Wow, against all odds, we've actually got a valid gzip string
8639 class SimplePie_Cache
8642 * Don't call the constructor. Please.
8646 function SimplePie_Cache()
8648 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8652 * Create a new SimplePie_Cache object
8657 function create($location, $filename, $extension)
8659 $location_iri = new SimplePie_IRI($location);
8660 switch ($location_iri->get_scheme())
8663 if (extension_loaded('mysql'))
8665 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
8670 return new SimplePie_Cache_File($location, $filename, $extension);
8675 class SimplePie_Cache_File
8682 function SimplePie_Cache_File($location, $filename, $extension)
8684 $this->location = $location;
8685 $this->filename = $filename;
8686 $this->extension = $extension;
8687 $this->name = "$this->location/$this->filename.$this->extension";
8690 function save($data)
8692 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8694 if (is_a($data, 'SimplePie'))
8696 $data = $data->data;
8699 $data = serialize($data);
8701 if (function_exists('file_put_contents'))
8703 return (bool) file_put_contents($this->name, $data);
8707 $fp = fopen($this->name, 'wb');
8721 if (file_exists($this->name) && is_readable($this->name))
8723 return unserialize(file_get_contents($this->name));
8730 if (file_exists($this->name))
8732 return filemtime($this->name);
8739 if (file_exists($this->name))
8741 return touch($this->name);
8748 if (file_exists($this->name))
8750 return unlink($this->name);
8756 class SimplePie_Cache_DB
8758 function prepare_simplepie_object_for_cache($data)
8760 $items = $data->get_items();
8761 $items_by_id = array();
8765 foreach ($items as $item)
8767 $items_by_id[$item->get_id()] = $item;
8770 if (count($items_by_id) !== count($items))
8772 $items_by_id = array();
8773 foreach ($items as $item)
8775 $items_by_id[$item->get_id(true)] = $item;
8779 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8781 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8783 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8785 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8787 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
8789 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
8791 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
8793 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
8800 if ($channel !== null)
8802 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
8804 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
8806 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
8808 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
8810 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
8812 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
8814 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
8816 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
8818 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
8820 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
8823 if (isset($data->data['items']))
8825 unset($data->data['items']);
8827 if (isset($data->data['ordered_items']))
8829 unset($data->data['ordered_items']);
8832 return array(serialize($data->data), $items_by_id);
8836 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
8842 function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
8844 $host = $mysql_location->get_host();
8845 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
8847 $server = ':' . substr($host, 5, -1);
8852 if ($mysql_location->get_port() !== null)
8854 $server .= ':' . $mysql_location->get_port();
8858 if (strpos($mysql_location->get_userinfo(), ':') !== false)
8860 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
8864 $username = $mysql_location->get_userinfo();
8868 if ($this->mysql = mysql_connect($server, $username, $password))
8870 $this->id = $name . $extension;
8871 $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
8872 if (!isset($this->options['prefix'][0]))
8874 $this->options['prefix'][0] = '';
8877 if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
8878 && mysql_query('SET NAMES utf8')
8879 && ($query = mysql_unbuffered_query('SHOW TABLES')))
8882 while ($row = mysql_fetch_row($query))
8887 if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
8889 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
8891 $this->mysql = null;
8895 if (!in_array($this->options['prefix'][0] . 'items', $db))
8897 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
8899 $this->mysql = null;
8905 $this->mysql = null;
8910 function save($data)
8914 $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
8916 if (is_a($data, 'SimplePie'))
8920 // This keyword needs to defy coding standards for PHP4 compatibility
8921 $data = clone($data);
8924 $prepared = $this->prepare_simplepie_object_for_cache($data);
8926 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8928 if (mysql_num_rows($query))
8930 $items = count($prepared[1]);
8933 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8937 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8940 if (!mysql_query($sql, $this->mysql))
8945 elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
8950 $ids = array_keys($prepared[1]);
8953 foreach ($ids as $id)
8955 $database_ids[] = mysql_real_escape_string($id);
8958 if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
8960 $existing_ids = array();
8961 while ($row = mysql_fetch_row($query))
8963 $existing_ids[] = $row[0];
8966 $new_ids = array_diff($ids, $existing_ids);
8968 foreach ($new_ids as $new_id)
8970 if (!($date = $prepared[1][$new_id]->get_date('U')))
8975 if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
8989 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8991 if (mysql_num_rows($query))
8993 if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
8998 elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
9009 if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
9011 $data = unserialize($row[1]);
9013 if (isset($this->options['items'][0]))
9015 $items = (int) $this->options['items'][0];
9019 $items = (int) $row[0];
9024 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
9026 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
9028 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
9030 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
9032 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
9034 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
9036 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
9038 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
9047 $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
9050 $sql .= ' LIMIT ' . $items;
9053 if ($query = mysql_unbuffered_query($sql, $this->mysql))
9055 while ($row = mysql_fetch_row($query))
9057 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
9073 if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
9085 if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
9097 if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
9108 class SimplePie_Misc
9110 function time_hms($seconds)
9114 $hours = floor($seconds / 3600);
9115 $remainder = $seconds % 3600;
9118 $time .= $hours.':';
9121 $minutes = floor($remainder / 60);
9122 $seconds = $remainder % 60;
9123 if ($minutes < 10 && $hours > 0)
9125 $minutes = '0' . $minutes;
9129 $seconds = '0' . $seconds;
9132 $time .= $minutes.':';
9138 function absolutize_url($relative, $base)
9140 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
9141 return $iri->get_iri();
9144 function remove_dot_segments($input)
9147 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
9149 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
9150 if (strpos($input, '../') === 0)
9152 $input = substr($input, 3);
9154 elseif (strpos($input, './') === 0)
9156 $input = substr($input, 2);
9158 // 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,
9159 elseif (strpos($input, '/./') === 0)
9161 $input = substr_replace($input, '/', 0, 3);
9163 elseif ($input === '/.')
9167 // 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,
9168 elseif (strpos($input, '/../') === 0)
9170 $input = substr_replace($input, '/', 0, 4);
9171 $output = substr_replace($output, '', strrpos($output, '/'));
9173 elseif ($input === '/..')
9176 $output = substr_replace($output, '', strrpos($output, '/'));
9178 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
9179 elseif ($input === '.' || $input === '..')
9183 // 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
9184 elseif (($pos = strpos($input, '/', 1)) !== false)
9186 $output .= substr($input, 0, $pos);
9187 $input = substr_replace($input, '', 0, $pos);
9195 return $output . $input;
9198 function get_element($realname, $string)
9201 $name = preg_quote($realname, '/');
9202 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
9204 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
9206 $return[$i]['tag'] = $realname;
9207 $return[$i]['full'] = $matches[$i][0][0];
9208 $return[$i]['offset'] = $matches[$i][0][1];
9209 if (strlen($matches[$i][3][0]) <= 2)
9211 $return[$i]['self_closing'] = true;
9215 $return[$i]['self_closing'] = false;
9216 $return[$i]['content'] = $matches[$i][4][0];
9218 $return[$i]['attribs'] = array();
9219 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))
9221 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
9223 if (count($attribs[$j]) === 2)
9225 $attribs[$j][2] = $attribs[$j][1];
9227 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
9235 function element_implode($element)
9237 $full = "<$element[tag]";
9238 foreach ($element['attribs'] as $key => $value)
9240 $key = strtolower($key);
9241 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
9243 if ($element['self_closing'])
9249 $full .= ">$element[content]</$element[tag]>";
9254 function error($message, $level, $file, $line)
9256 if ((ini_get('error_reporting') & $level) > 0)
9261 $note = 'PHP Error';
9263 case E_USER_WARNING:
9264 $note = 'PHP Warning';
9267 $note = 'PHP Notice';
9270 $note = 'Unknown Error';
9275 if (!function_exists('error_log'))
9280 $log_file = @ini_get('error_log');
9281 if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file))
9288 @error_log("$note: $message in $file on line $line", 0);
9296 * If a file has been cached, retrieve and display it.
9298 * This is most useful for caching images (get_favicon(), etc.),
9299 * however it works for all cached files. This WILL NOT display ANY
9300 * file/image/page/whatever, but rather only display what has already
9301 * been cached by SimplePie.
9304 * @see SimplePie::get_favicon()
9305 * @param str $identifier_url URL that is used to identify the content.
9306 * This may or may not be the actual URL of the live content.
9307 * @param str $cache_location Location of SimplePie's cache. Defaults
9309 * @param str $cache_extension The file extension that the file was
9310 * cached with. Defaults to 'spc'.
9311 * @param str $cache_class Name of the cache-handling class being used
9312 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
9313 * as-is unless you've overloaded the class.
9314 * @param str $cache_name_function Obsolete. Exists for backwards
9315 * compatibility reasons only.
9317 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
9319 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
9321 if ($file = $cache->load())
9323 if (isset($file['headers']['content-type']))
9325 header('Content-type:' . $file['headers']['content-type']);
9329 header('Content-type: application/octet-stream');
9331 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
9336 die('Cached file for ' . $identifier_url . ' cannot be found.');
9339 function fix_protocol($url, $http = 1)
9341 $url = SimplePie_Misc::normalize_url($url);
9342 $parsed = SimplePie_Misc::parse_url($url);
9343 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
9345 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
9348 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
9350 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9353 if ($http === 2 && $parsed['scheme'] !== '')
9357 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
9359 return substr_replace($url, 'podcast', 0, 4);
9361 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
9363 return substr_replace($url, 'itpc', 0, 4);
9371 function parse_url($url)
9373 $iri = new SimplePie_IRI($url);
9375 'scheme' => (string) $iri->get_scheme(),
9376 'authority' => (string) $iri->get_authority(),
9377 'path' => (string) $iri->get_path(),
9378 'query' => (string) $iri->get_query(),
9379 'fragment' => (string) $iri->get_fragment()
9383 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9385 $iri = new SimplePie_IRI('');
9386 $iri->set_scheme($scheme);
9387 $iri->set_authority($authority);
9388 $iri->set_path($path);
9389 $iri->set_query($query);
9390 $iri->set_fragment($fragment);
9391 return $iri->get_iri();
9394 function normalize_url($url)
9396 $iri = new SimplePie_IRI($url);
9397 return $iri->get_iri();
9400 function percent_encoding_normalization($match)
9402 $integer = hexdec($match[1]);
9403 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
9405 return chr($integer);
9409 return strtoupper($match[0]);
9414 * Remove bad UTF-8 bytes
9416 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9417 * FAQ: Multilingual Forms (modified to include full ASCII range)
9419 * @author Geoffrey Sneddon
9420 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9421 * @param string $str String to remove bad UTF-8 bytes from
9422 * @return string UTF-8 string
9424 function utf8_bad_replace($str)
9426 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9430 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9434 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))
9436 return implode("\xEF\xBF\xBD", $matches[0]);
9438 elseif ($str !== '')
9440 return "\xEF\xBF\xBD";
9449 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9453 * @param string $string Windows-1252 encoded string
9454 * @return string UTF-8 encoded string
9456 function windows_1252_to_utf8($string)
9458 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");
9460 return strtr($string, $convert_table);
9463 function change_encoding($data, $input, $output)
9465 $input = SimplePie_Misc::encoding($input);
9466 $output = SimplePie_Misc::encoding($output);
9468 // We fail to fail on non US-ASCII bytes
9469 if ($input === 'US-ASCII')
9471 static $non_ascii_octects = '';
9472 if (!$non_ascii_octects)
9474 for ($i = 0x80; $i <= 0xFF; $i++)
9476 $non_ascii_octects .= chr($i);
9479 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9482 // This is first, as behaviour of this is completely predictable
9483 if ($input === 'Windows-1252' && $output === 'UTF-8')
9485 return SimplePie_Misc::windows_1252_to_utf8($data);
9487 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9488 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
9492 // This is last, as behaviour of this varies with OS userland and PHP version
9493 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9497 // If we can't do anything, just fail
9504 function encoding($charset)
9506 // Normalization from UTS #22
9507 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9509 case 'adobestandardencoding':
9510 case 'csadobestandardencoding':
9511 return 'Adobe-Standard-Encoding';
9513 case 'adobesymbolencoding':
9515 return 'Adobe-Symbol-Encoding';
9519 return 'Amiga-1251';
9521 case 'ansix31101983':
9523 case 'csiso99naplps':
9526 return 'ANSI_X3.110-1983';
9530 case 'csiso89asmo449':
9541 return 'Big5-HKSCS';
9552 case 'csiso4unitedkingdom':
9560 case 'csiso47bsviewdata':
9562 return 'BS_viewdata';
9570 case 'csaz243419851':
9571 case 'csiso121canadian1':
9574 return 'CSA_Z243.4-1985-1';
9577 case 'csaz243419852':
9578 case 'csiso122canadian2':
9581 return 'CSA_Z243.4-1985-2';
9583 case 'csaz24341985gr':
9584 case 'csiso123csaz24341985gr':
9586 return 'CSA_Z243.4-1985-gr';
9588 case 'csiso139csn369103':
9591 return 'CSN_369103';
9598 case 'csiso21german':
9609 case 'csiso646danish':
9615 case 'csibmebcdicatde':
9617 return 'EBCDIC-AT-DE';
9619 case 'csebcdicatdea':
9621 return 'EBCDIC-AT-DE-A';
9623 case 'csebcdiccafr':
9625 return 'EBCDIC-CA-FR';
9627 case 'csebcdicdkno':
9629 return 'EBCDIC-DK-NO';
9631 case 'csebcdicdknoa':
9633 return 'EBCDIC-DK-NO-A';
9641 return 'EBCDIC-ES-A';
9645 return 'EBCDIC-ES-S';
9647 case 'csebcdicfise':
9649 return 'EBCDIC-FI-SE';
9651 case 'csebcdicfisea':
9653 return 'EBCDIC-FI-SE-A';
9675 case 'csiso111ecmacyrillic':
9676 case 'ecmacyrillic':
9679 return 'ECMA-cyrillic';
9681 case 'csiso17spanish':
9687 case 'csiso85spanish2':
9693 case 'cseucfixwidjapanese':
9694 case 'extendedunixcodefixedwidthforjapanese':
9695 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9697 case 'cseucpkdfmtjapanese':
9699 case 'extendedunixcodepackedformatforjapanese':
9700 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9708 case 'csiso58gb231280':
9718 case 'csiso57gb1988':
9722 return 'GB_1988-80';
9724 case 'csiso153gost1976874':
9728 return 'GOST_19768-74';
9731 case 'csiso150greekccitt':
9734 return 'greek-ccitt';
9736 case 'csiso88greek7':
9741 case 'csiso18greek7old':
9744 return 'greek7-old';
9748 return 'HP-DeskTop';
9760 return 'HP-Pi-font';
9769 return 'HZ-GB-2312';
9771 case 'csibmsymbols':
9773 return 'IBM-Symbols';
9782 case 'pcmultilingual850euro':
9787 case 'ebcdiclatin9euro':
9793 case 'ebcdicus37euro':
9799 case 'ebcdicde273euro':
9805 case 'ebcdicdk277euro':
9806 case 'ebcdicno277euro':
9812 case 'ebcdicfi278euro':
9813 case 'ebcdicse278euro':
9819 case 'ebcdicit280euro':
9825 case 'ebcdices284euro':
9831 case 'ebcdicgb285euro':
9837 case 'ebcdicfr297euro':
9843 case 'ebcdicinternational500euro':
9849 case 'ebcdicis871euro':
9924 case 'ebcdicjpkana':
9954 case 'cspc8codepage437':
9966 case 'cspc775baltic':
9972 case 'cspc850multilingual':
10015 case 'cspc862latinhebrew':
10057 case 'ebcdiccproece':
10070 case 'ebcdiccyrillic':
10098 case 'ebcdiccpar2':
10110 case 'csiso143iecp271':
10113 return 'IEC_P27-1';
10115 case 'csiso49inis':
10120 case 'csiso50inis8':
10125 case 'csiso51iniscyrillic':
10126 case 'iniscyrillic':
10128 return 'INIS-cyrillic';
10130 case 'csinvariant':
10132 return 'INVARIANT';
10135 return 'ISO-2022-CN';
10137 case 'iso2022cnext':
10138 return 'ISO-2022-CN-EXT';
10140 case 'csiso2022jp':
10142 return 'ISO-2022-JP';
10144 case 'csiso2022jp2':
10146 return 'ISO-2022-JP-2';
10148 case 'csiso2022kr':
10150 return 'ISO-2022-KR';
10152 case 'cswindows30latin1':
10153 case 'iso88591windows30latin1':
10154 return 'ISO-8859-1-Windows-3.0-Latin-1';
10156 case 'cswindows31latin1':
10157 case 'iso88591windows31latin1':
10158 return 'ISO-8859-1-Windows-3.1-Latin-1';
10160 case 'csisolatin2':
10162 case 'iso885921987':
10166 return 'ISO-8859-2';
10168 case 'cswindows31latin2':
10169 case 'iso88592windowslatin2':
10170 return 'ISO-8859-2-Windows-Latin-2';
10172 case 'csisolatin3':
10174 case 'iso885931988':
10178 return 'ISO-8859-3';
10180 case 'csisolatin4':
10182 case 'iso885941988':
10186 return 'ISO-8859-4';
10188 case 'csisolatincyrillic':
10191 case 'iso885951988':
10193 return 'ISO-8859-5';
10197 case 'csisolatinarabic':
10200 case 'iso885961987':
10202 return 'ISO-8859-6';
10204 case 'csiso88596e':
10206 return 'ISO-8859-6-E';
10208 case 'csiso88596i':
10210 return 'ISO-8859-6-I';
10212 case 'csisolatingreek':
10218 case 'iso885971987':
10220 return 'ISO-8859-7';
10222 case 'csisolatinhebrew':
10225 case 'iso885981988':
10227 return 'ISO-8859-8';
10229 case 'csiso88598e':
10231 return 'ISO-8859-8-E';
10233 case 'csiso88598i':
10235 return 'ISO-8859-8-I';
10237 case 'cswindows31latin5':
10238 case 'iso88599windowslatin5':
10239 return 'ISO-8859-9-Windows-Latin-5';
10241 case 'csisolatin6':
10243 case 'iso8859101992':
10247 return 'ISO-8859-10';
10250 return 'ISO-8859-13';
10253 case 'iso8859141998':
10258 return 'ISO-8859-14';
10262 return 'ISO-8859-15';
10265 case 'iso8859162001':
10269 return 'ISO-8859-16';
10272 return 'ISO-10646-J-1';
10275 case 'iso10646ucs2':
10276 return 'ISO-10646-UCS-2';
10279 case 'iso10646ucs4':
10280 return 'ISO-10646-UCS-4';
10282 case 'csunicodeascii':
10283 case 'iso10646ucsbasic':
10284 return 'ISO-10646-UCS-Basic';
10286 case 'csunicodelatin1':
10288 case 'iso10646unicodelatin1':
10289 return 'ISO-10646-Unicode-Latin1';
10291 case 'csiso10646utf1':
10292 case 'iso10646utf1':
10293 return 'ISO-10646-UTF-1';
10295 case 'csiso115481':
10297 case 'isotr115481':
10298 return 'ISO-11548-1';
10302 return 'iso-ir-90';
10304 case 'csunicodeibm1261':
10305 case 'isounicodeibm1261':
10306 return 'ISO-Unicode-IBM-1261';
10308 case 'csunicodeibm1264':
10309 case 'isounicodeibm1264':
10310 return 'ISO-Unicode-IBM-1264';
10312 case 'csunicodeibm1265':
10313 case 'isounicodeibm1265':
10314 return 'ISO-Unicode-IBM-1265';
10316 case 'csunicodeibm1268':
10317 case 'isounicodeibm1268':
10318 return 'ISO-Unicode-IBM-1268';
10320 case 'csunicodeibm1276':
10321 case 'isounicodeibm1276':
10322 return 'ISO-Unicode-IBM-1276';
10324 case 'csiso646basic1983':
10325 case 'iso646basic1983':
10327 return 'ISO_646.basic:1983';
10329 case 'csiso2intlrefversion':
10331 case 'iso646irv1983':
10333 return 'ISO_646.irv:1983';
10337 case 'iso20331983':
10339 return 'ISO_2033-1983';
10341 case 'csiso5427cyrillic':
10346 case 'iso5427cyrillic1981':
10347 case 'iso54271981':
10349 return 'ISO_5427:1981';
10351 case 'csiso5428greek':
10352 case 'iso54281980':
10354 return 'ISO_5428:1980';
10356 case 'csiso6937add':
10359 return 'ISO_6937-2-25';
10361 case 'csisotextcomm':
10362 case 'iso69372add':
10364 return 'ISO_6937-2-add';
10366 case 'csiso8859supp':
10367 case 'iso8859supp':
10370 return 'ISO_8859-supp';
10372 case 'csiso10367box':
10373 case 'iso10367box':
10375 return 'ISO_10367-box';
10377 case 'csiso15italian':
10383 case 'csiso13jisc6220jp':
10385 case 'jisc62201969':
10386 case 'jisc62201969jp':
10389 return 'JIS_C6220-1969-jp';
10391 case 'csiso14jisc6220ro':
10394 case 'jisc62201969ro':
10396 return 'JIS_C6220-1969-ro';
10398 case 'csiso42jisc62261978':
10400 case 'jisc62261978':
10401 return 'JIS_C6226-1978';
10403 case 'csiso87jisx208':
10405 case 'jisc62261983':
10406 case 'jisx2081983':
10408 return 'JIS_C6226-1983';
10410 case 'csiso91jisc62291984a':
10412 case 'jisc62291984a':
10414 return 'JIS_C6229-1984-a';
10416 case 'csiso92jisc62991984b':
10417 case 'iso646jpocrb':
10419 case 'jisc62291984b':
10421 return 'JIS_C6229-1984-b';
10423 case 'csiso93jis62291984badd':
10425 case 'jisc62291984badd':
10427 return 'JIS_C6229-1984-b-add';
10429 case 'csiso94jis62291984hand':
10431 case 'jisc62291984hand':
10433 return 'JIS_C6229-1984-hand';
10435 case 'csiso95jis62291984handadd':
10437 case 'jisc62291984handadd':
10438 case 'jpocrhandadd':
10439 return 'JIS_C6229-1984-hand-add';
10441 case 'csiso96jisc62291984kana':
10443 case 'jisc62291984kana':
10444 return 'JIS_C6229-1984-kana';
10446 case 'csjisencoding':
10447 case 'jisencoding':
10448 return 'JIS_Encoding';
10450 case 'cshalfwidthkatakana':
10453 return 'JIS_X0201';
10455 case 'csiso159jisx2121990':
10457 case 'jisx2121990':
10459 return 'JIS_X0212-1990';
10461 case 'csiso141jusib1002':
10467 return 'JUS_I.B1.002';
10469 case 'csiso147macedonian':
10471 case 'jusib1003mac':
10473 return 'JUS_I.B1.003-mac';
10475 case 'csiso146serbian':
10477 case 'jusib1003serb':
10479 return 'JUS_I.B1.003-serb';
10481 case 'koi7switched':
10482 return 'KOI7-switched';
10499 case 'strk10482002':
10502 case 'csiso19latingreek':
10505 return 'latin-greek';
10507 case 'csiso27latingreek1':
10509 case 'latingreek1':
10510 return 'Latin-greek-1';
10512 case 'csiso158lap':
10516 return 'latin-lap';
10518 case 'csmacintosh':
10521 return 'macintosh';
10523 case 'csmicrosoftpublishing':
10524 case 'microsoftpublishing':
10525 return 'Microsoft-Publishing';
10535 case 'csiso86hungarian':
10540 return 'MSZ_7795.3';
10545 return 'NATS-DANO';
10547 case 'csnatsdanoadd':
10549 case 'natsdanoadd':
10550 return 'NATS-DANO-ADD';
10555 return 'NATS-SEFI';
10557 case 'csnatssefiadd':
10559 case 'natssefiadd':
10560 return 'NATS-SEFI-ADD';
10562 case 'csiso151cuba':
10567 return 'NC_NC00-10:81';
10569 case 'csiso69french':
10574 return 'NF_Z_62-010';
10576 case 'csiso25french':
10579 case 'nfz620101973':
10580 return 'NF_Z_62-010_(1973)';
10582 case 'csiso60danishnorwegian':
10583 case 'csiso60norwegian1':
10588 return 'NS_4551-1';
10590 case 'csiso61norwegian2':
10595 return 'NS_4551-2';
10597 case 'osdebcdicdf3irv':
10598 return 'OSD_EBCDIC_DF03_IRV';
10600 case 'osdebcdicdf41':
10601 return 'OSD_EBCDIC_DF04_1';
10603 case 'osdebcdicdf415':
10604 return 'OSD_EBCDIC_DF04_15';
10606 case 'cspc8danishnorwegian':
10607 case 'pc8danishnorwegian':
10608 return 'PC8-Danish-Norwegian';
10610 case 'cspc8turkish':
10612 return 'PC8-Turkish';
10614 case 'csiso16portuguese':
10620 case 'csiso84portuguese2':
10628 case 'cyrillicasian':
10636 case 'csiso10swedish':
10643 return 'SEN_850200_B';
10645 case 'csiso11swedishfornames':
10650 return 'SEN_850200_C';
10655 return 'Shift_JIS';
10657 case 'csiso102t617bit':
10660 return 'T.61-7bit';
10662 case 'csiso103t618bit':
10666 return 'T.61-8bit';
10668 case 'csiso128t101g2':
10677 case 'csunicode11':
10679 return 'UNICODE-1-1';
10681 case 'csunicode11utf7':
10682 case 'unicode11utf7':
10683 return 'UNICODE-1-1-UTF-7';
10685 case 'csunknown8bit':
10686 case 'unknown8bit':
10687 return 'UNKNOWN-8BIT';
10689 case 'ansix341968':
10690 case 'ansix341986':
10695 case 'iso646irv1991':
10730 case 'csventurainternational':
10731 case 'venturainternational':
10732 return 'Ventura-International';
10734 case 'csventuramath':
10735 case 'venturamath':
10736 return 'Ventura-Math';
10738 case 'csventuraus':
10740 return 'Ventura-US';
10742 case 'csiso70videotexsupp1':
10744 case 'videotexsuppl':
10745 return 'videotex-suppl';
10755 case 'cswindows31j':
10757 return 'Windows-31J';
10761 return 'windows-874';
10764 case 'csksc56011987':
10769 case 'ksc56011987':
10770 case 'ksc56011989':
10772 return 'windows-949';
10774 case 'windows1250':
10775 return 'windows-1250';
10777 case 'windows1251':
10778 return 'windows-1251';
10781 case 'csisolatin1':
10784 case 'iso885911987':
10788 case 'windows1252':
10789 return 'windows-1252';
10791 case 'windows1253':
10792 return 'windows-1253';
10794 case 'csisolatin5':
10796 case 'iso885991989':
10800 case 'windows1254':
10801 return 'windows-1254';
10803 case 'windows1255':
10804 return 'windows-1255';
10806 case 'windows1256':
10807 return 'windows-1256';
10809 case 'windows1257':
10810 return 'windows-1257';
10812 case 'windows1258':
10813 return 'windows-1258';
10820 function get_curl_version()
10822 if (is_array($curl = curl_version()))
10824 $curl = $curl['version'];
10826 elseif (substr($curl, 0, 5) === 'curl/')
10828 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10830 elseif (substr($curl, 0, 8) === 'libcurl/')
10832 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10841 function is_subclass_of($class1, $class2)
10843 if (func_num_args() !== 2)
10845 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10847 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10849 return is_subclass_of($class1, $class2);
10851 elseif (is_string($class1) && is_string($class2))
10853 if (class_exists($class1))
10855 if (class_exists($class2))
10857 $class2 = strtolower($class2);
10858 while ($class1 = strtolower(get_parent_class($class1)))
10860 if ($class1 === $class2)
10869 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10876 * Strip HTML comments
10879 * @param string $data Data to strip comments from
10880 * @return string Comment stripped string
10882 function strip_comments($data)
10885 while (($start = strpos($data, '<!--')) !== false)
10887 $output .= substr($data, 0, $start);
10888 if (($end = strpos($data, '-->', $start)) !== false)
10890 $data = substr_replace($data, '', 0, $end + 3);
10897 return $output . $data;
10900 function parse_date($dt)
10902 $parser = SimplePie_Parse_Date::get();
10903 return $parser->parse($dt);
10907 * Decode HTML entities
10911 * @param string $data Input data
10912 * @return string Output data
10914 function entities_decode($data)
10916 $decoder = new SimplePie_Decode_HTML_Entities($data);
10917 return $decoder->parse();
10921 * Remove RFC822 comments
10924 * @param string $data Data to strip comments from
10925 * @return string Comment stripped string
10927 function uncomment_rfc822($string)
10929 $string = (string) $string;
10931 $length = strlen($string);
10936 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10938 $output .= substr($string, $position, $pos - $position);
10939 $position = $pos + 1;
10940 if ($string[$pos - 1] !== '\\')
10943 while ($depth && $position < $length)
10945 $position += strcspn($string, '()', $position);
10946 if ($string[$position - 1] === '\\')
10951 elseif (isset($string[$position]))
10953 switch ($string[$position])
10976 $output .= substr($string, $position);
10981 function parse_mime($mime)
10983 if (($pos = strpos($mime, ';')) === false)
10985 return trim($mime);
10989 return trim(substr($mime, 0, $pos));
10993 function htmlspecialchars_decode($string, $quote_style)
10995 if (function_exists('htmlspecialchars_decode'))
10997 return htmlspecialchars_decode($string, $quote_style);
11001 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
11005 function atom_03_construct_type($attribs)
11007 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
11009 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
11013 $mode = SIMPLEPIE_CONSTRUCT_NONE;
11015 if (isset($attribs['']['type']))
11017 switch (strtolower(trim($attribs['']['type'])))
11021 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11025 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
11028 case 'application/xhtml+xml':
11029 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
11032 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
11037 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11041 function atom_10_construct_type($attribs)
11043 if (isset($attribs['']['type']))
11045 switch (strtolower(trim($attribs['']['type'])))
11048 return SIMPLEPIE_CONSTRUCT_TEXT;
11051 return SIMPLEPIE_CONSTRUCT_HTML;
11054 return SIMPLEPIE_CONSTRUCT_XHTML;
11057 return SIMPLEPIE_CONSTRUCT_NONE;
11060 return SIMPLEPIE_CONSTRUCT_TEXT;
11063 function atom_10_content_construct_type($attribs)
11065 if (isset($attribs['']['type']))
11067 $type = strtolower(trim($attribs['']['type']));
11071 return SIMPLEPIE_CONSTRUCT_TEXT;
11074 return SIMPLEPIE_CONSTRUCT_HTML;
11077 return SIMPLEPIE_CONSTRUCT_XHTML;
11079 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
11081 return SIMPLEPIE_CONSTRUCT_NONE;
11085 return SIMPLEPIE_CONSTRUCT_BASE64;
11090 return SIMPLEPIE_CONSTRUCT_TEXT;
11094 function is_isegment_nz_nc($string)
11096 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);
11099 function space_seperated_tokens($string)
11101 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
11102 $string_length = strlen($string);
11104 $position = strspn($string, $space_characters);
11107 while ($position < $string_length)
11109 $len = strcspn($string, $space_characters, $position);
11110 $tokens[] = substr($string, $position, $len);
11112 $position += strspn($string, $space_characters, $position);
11118 function array_unique($array)
11120 if (version_compare(PHP_VERSION, '5.2', '>='))
11122 return array_unique($array);
11126 $array = (array) $array;
11127 $new_array = array();
11128 $new_array_strings = array();
11129 foreach ($array as $key => $value)
11131 if (is_object($value))
11133 if (method_exists($value, '__toString'))
11135 $cmp = $value->__toString();
11139 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
11142 elseif (is_array($value))
11144 $cmp = (string) reset($value);
11148 $cmp = (string) $value;
11150 if (!in_array($cmp, $new_array_strings))
11152 $new_array[$key] = $value;
11153 $new_array_strings[] = $cmp;
11161 * Converts a unicode codepoint to a UTF-8 character
11165 * @param int $codepoint Unicode codepoint
11166 * @return string UTF-8 character
11168 function codepoint_to_utf8($codepoint)
11170 $codepoint = (int) $codepoint;
11171 if ($codepoint < 0)
11175 else if ($codepoint <= 0x7f)
11177 return chr($codepoint);
11179 else if ($codepoint <= 0x7ff)
11181 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
11183 else if ($codepoint <= 0xffff)
11185 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11187 else if ($codepoint <= 0x10ffff)
11189 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11193 // U+FFFD REPLACEMENT CHARACTER
11194 return "\xEF\xBF\xBD";
11199 * Re-implementation of PHP 5's stripos()
11201 * Returns the numeric position of the first occurrence of needle in the
11206 * @param object $haystack
11207 * @param string $needle Note that the needle may be a string of one or more
11208 * characters. If needle is not a string, it is converted to an integer
11209 * and applied as the ordinal value of a character.
11210 * @param int $offset The optional offset parameter allows you to specify which
11211 * character in haystack to start searching. The position returned is still
11212 * relative to the beginning of haystack.
11213 * @return bool If needle is not found, stripos() will return boolean false.
11215 function stripos($haystack, $needle, $offset = 0)
11217 if (function_exists('stripos'))
11219 return stripos($haystack, $needle, $offset);
11223 if (is_string($needle))
11225 $needle = strtolower($needle);
11227 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
11229 $needle = strtolower(chr($needle));
11233 trigger_error('needle is not a string or an integer', E_USER_WARNING);
11237 return strpos(strtolower($haystack), $needle, $offset);
11242 * Similar to parse_str()
11244 * Returns an associative array of name/value pairs, where the value is an
11245 * array of values that have used the same name
11249 * @param string $str The input string.
11252 function parse_str($str)
11255 $str = explode('&', $str);
11257 foreach ($str as $section)
11259 if (strpos($section, '=') !== false)
11261 list($name, $value) = explode('=', $section, 2);
11262 $return[urldecode($name)][] = urldecode($value);
11266 $return[urldecode($section)][] = null;
11274 * Detect XML encoding, as per XML 1.0 Appendix F.1
11276 * @todo Add support for EBCDIC
11277 * @param string $data XML data
11278 * @return array Possible encodings
11280 function xml_encoding($data)
11282 // UTF-32 Big Endian BOM
11283 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
11285 $encoding[] = 'UTF-32BE';
11287 // UTF-32 Little Endian BOM
11288 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
11290 $encoding[] = 'UTF-32LE';
11292 // UTF-16 Big Endian BOM
11293 elseif (substr($data, 0, 2) === "\xFE\xFF")
11295 $encoding[] = 'UTF-16BE';
11297 // UTF-16 Little Endian BOM
11298 elseif (substr($data, 0, 2) === "\xFF\xFE")
11300 $encoding[] = 'UTF-16LE';
11303 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11305 $encoding[] = 'UTF-8';
11307 // UTF-32 Big Endian Without BOM
11308 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")
11310 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11312 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11313 if ($parser->parse())
11315 $encoding[] = $parser->encoding;
11318 $encoding[] = 'UTF-32BE';
11320 // UTF-32 Little Endian Without BOM
11321 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")
11323 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11325 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11326 if ($parser->parse())
11328 $encoding[] = $parser->encoding;
11331 $encoding[] = 'UTF-32LE';
11333 // UTF-16 Big Endian Without BOM
11334 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11336 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11338 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11339 if ($parser->parse())
11341 $encoding[] = $parser->encoding;
11344 $encoding[] = 'UTF-16BE';
11346 // UTF-16 Little Endian Without BOM
11347 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11349 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11351 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11352 if ($parser->parse())
11354 $encoding[] = $parser->encoding;
11357 $encoding[] = 'UTF-16LE';
11359 // US-ASCII (or superset)
11360 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11362 if ($pos = strpos($data, "\x3F\x3E"))
11364 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11365 if ($parser->parse())
11367 $encoding[] = $parser->encoding;
11370 $encoding[] = 'UTF-8';
11372 // Fallback to UTF-8
11375 $encoding[] = 'UTF-8';
11380 function output_javascript()
11382 if (function_exists('ob_gzhandler'))
11384 ob_start('ob_gzhandler');
11386 header('Content-type: text/javascript; charset: UTF-8');
11387 header('Cache-Control: must-revalidate');
11388 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
11390 function embed_odeo(link) {
11391 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>');
11394 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
11395 if (placeholder != '') {
11396 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>');
11399 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>');
11403 function embed_flash(bgcolor, width, height, link, loop, type) {
11404 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>');
11407 function embed_flv(width, height, link, placeholder, loop, player) {
11408 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>');
11411 function embed_wmedia(width, height, link) {
11412 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
11419 * Decode HTML Entities
11421 * This implements HTML5 as of revision 967 (2007-06-28)
11423 * @package SimplePie
11425 class SimplePie_Decode_HTML_Entities
11428 * Data to be parsed
11436 * Currently consumed bytes
11441 var $consumed = '';
11444 * Position of the current byte being parsed
11452 * Create an instance of the class with the input data
11455 * @param string $data Input data
11457 function SimplePie_Decode_HTML_Entities($data)
11459 $this->data = $data;
11463 * Parse the input data
11466 * @return string Output data
11470 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11474 $this->consumed = '';
11476 return $this->data;
11480 * Consume the next byte
11483 * @return mixed The next byte, or false, if there is no more data
11487 if (isset($this->data[$this->position]))
11489 $this->consumed .= $this->data[$this->position];
11490 return $this->data[$this->position++];
11499 * Consume a range of characters
11502 * @param string $chars Characters to consume
11503 * @return mixed A series of characters that match the range, or false
11505 function consume_range($chars)
11507 if ($len = strspn($this->data, $chars, $this->position))
11509 $data = substr($this->data, $this->position, $len);
11510 $this->consumed .= $data;
11511 $this->position += $len;
11521 * Unconsume one byte
11525 function unconsume()
11527 $this->consumed = substr($this->consumed, 0, -1);
11538 switch ($this->consume())
11552 switch ($this->consume())
11556 $range = '0123456789ABCDEFabcdef';
11561 $range = '0123456789';
11563 $this->unconsume();
11567 if ($codepoint = $this->consume_range($range))
11569 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");
11573 $codepoint = hexdec($codepoint);
11577 $codepoint = intval($codepoint);
11580 if (isset($windows_1252_specials[$codepoint]))
11582 $replacement = $windows_1252_specials[$codepoint];
11586 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11589 if (!in_array($this->consume(), array(';', false), true))
11591 $this->unconsume();
11594 $consumed_length = strlen($this->consumed);
11595 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11596 $this->position += strlen($replacement) - $consumed_length;
11601 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");
11603 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11605 $consumed = substr($this->consumed, 1);
11606 if (isset($entities[$consumed]))
11608 $match = $consumed;
11612 if ($match !== null)
11614 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11615 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11623 * IRI parser/serialiser
11625 * @package SimplePie
11627 class SimplePie_IRI
11686 * Whether the object represents a valid IRI
11691 var $valid = array();
11694 * Return the entire IRI when you try and read the object as a string
11699 function __toString()
11701 return $this->get_iri();
11705 * Create a new IRI object, from a specified string
11708 * @param string $iri
11709 * @return SimplePie_IRI
11711 function SimplePie_IRI($iri)
11713 $iri = (string) $iri;
11716 $parsed = $this->parse_iri($iri);
11717 $this->set_scheme($parsed['scheme']);
11718 $this->set_authority($parsed['authority']);
11719 $this->set_path($parsed['path']);
11720 $this->set_query($parsed['query']);
11721 $this->set_fragment($parsed['fragment']);
11726 * Create a new IRI object by resolving a relative IRI
11730 * @param SimplePie_IRI $base Base IRI
11731 * @param string $relative Relative IRI
11732 * @return SimplePie_IRI
11734 function absolutize($base, $relative)
11736 $relative = (string) $relative;
11737 if ($relative !== '')
11739 $relative = new SimplePie_IRI($relative);
11740 if ($relative->get_scheme() !== null)
11742 $target = $relative;
11744 elseif ($base->get_iri() !== null)
11746 if ($relative->get_authority() !== null)
11748 $target = $relative;
11749 $target->set_scheme($base->get_scheme());
11753 $target = new SimplePie_IRI('');
11754 $target->set_scheme($base->get_scheme());
11755 $target->set_userinfo($base->get_userinfo());
11756 $target->set_host($base->get_host());
11757 $target->set_port($base->get_port());
11758 if ($relative->get_path() !== null)
11760 if (strpos($relative->get_path(), '/') === 0)
11762 $target->set_path($relative->get_path());
11764 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
11766 $target->set_path('/' . $relative->get_path());
11768 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11770 $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
11774 $target->set_path($relative->get_path());
11776 $target->set_query($relative->get_query());
11780 $target->set_path($base->get_path());
11781 if ($relative->get_query() !== null)
11783 $target->set_query($relative->get_query());
11785 elseif ($base->get_query() !== null)
11787 $target->set_query($base->get_query());
11791 $target->set_fragment($relative->get_fragment());
11795 // No base URL, just return the relative URL
11796 $target = $relative;
11807 * Parse an IRI into scheme/authority/path/query/fragment segments
11810 * @param string $iri
11813 function parse_iri($iri)
11815 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11816 for ($i = count($match); $i <= 9; $i++)
11820 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11824 * Remove dot segments from a path
11827 * @param string $input
11830 function remove_dot_segments($input)
11833 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
11835 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11836 if (strpos($input, '../') === 0)
11838 $input = substr($input, 3);
11840 elseif (strpos($input, './') === 0)
11842 $input = substr($input, 2);
11844 // 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,
11845 elseif (strpos($input, '/./') === 0)
11847 $input = substr_replace($input, '/', 0, 3);
11849 elseif ($input === '/.')
11853 // 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,
11854 elseif (strpos($input, '/../') === 0)
11856 $input = substr_replace($input, '/', 0, 4);
11857 $output = substr_replace($output, '', strrpos($output, '/'));
11859 elseif ($input === '/..')
11862 $output = substr_replace($output, '', strrpos($output, '/'));
11864 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11865 elseif ($input === '.' || $input === '..')
11869 // 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
11870 elseif (($pos = strpos($input, '/', 1)) !== false)
11872 $output .= substr($input, 0, $pos);
11873 $input = substr_replace($input, '', 0, $pos);
11881 return $output . $input;
11885 * Replace invalid character with percent encoding
11888 * @param string $string Input string
11889 * @param string $valid_chars Valid characters
11890 * @param int $case Normalise case
11893 function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
11896 if ($case & SIMPLEPIE_LOWERCASE)
11898 $string = strtolower($string);
11900 elseif ($case & SIMPLEPIE_UPPERCASE)
11902 $string = strtoupper($string);
11905 // Store position and string length (to avoid constantly recalculating this)
11907 $strlen = strlen($string);
11909 // Loop as long as we have invalid characters, advancing the position to the next invalid character
11910 while (($position += strspn($string, $valid_chars, $position)) < $strlen)
11912 // If we have a % character
11913 if ($string[$position] === '%')
11915 // If we have a pct-encoded section
11916 if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
11918 // Get the the represented character
11919 $chr = chr(hexdec(substr($string, $position + 1, 2)));
11921 // If the character is valid, replace the pct-encoded with the actual character while normalising case
11922 if (strpos($valid_chars, $chr) !== false)
11924 if ($case & SIMPLEPIE_LOWERCASE)
11926 $chr = strtolower($chr);
11928 elseif ($case & SIMPLEPIE_UPPERCASE)
11930 $chr = strtoupper($chr);
11932 $string = substr_replace($string, $chr, $position, 3);
11937 // Otherwise just normalise the pct-encoded to uppercase
11940 $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
11944 // If we don't have a pct-encoded section, just replace the % with its own esccaped form
11947 $string = substr_replace($string, '%25', $position, 1);
11952 // If we have an invalid character, change into its pct-encoded form
11955 $replacement = sprintf("%%%02X", ord($string[$position]));
11956 $string = str_replace($string[$position], $replacement, $string);
11957 $strlen = strlen($string);
11964 * Check if the object represents a valid IRI
11969 function is_valid()
11971 return array_sum($this->valid) === count($this->valid);
11975 * Set the scheme. Returns true on success, false on failure (if there are
11976 * any invalid characters).
11979 * @param string $scheme
11982 function set_scheme($scheme)
11984 if ($scheme === null || $scheme === '')
11986 $this->scheme = null;
11990 $len = strlen($scheme);
11994 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
11996 $this->scheme = null;
11997 $this->valid[__FUNCTION__] = false;
12002 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
12004 $this->scheme = null;
12005 $this->valid[__FUNCTION__] = false;
12009 $this->scheme = strtolower($scheme);
12011 $this->valid[__FUNCTION__] = true;
12016 * Set the authority. Returns true on success, false on failure (if there are
12017 * any invalid characters).
12020 * @param string $authority
12023 function set_authority($authority)
12025 if (($userinfo_end = strrpos($authority, '@')) !== false)
12027 $userinfo = substr($authority, 0, $userinfo_end);
12028 $authority = substr($authority, $userinfo_end + 1);
12035 if (($port_start = strpos($authority, ':')) !== false)
12037 $port = substr($authority, $port_start + 1);
12038 $authority = substr($authority, 0, $port_start);
12045 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
12049 * Set the userinfo.
12052 * @param string $userinfo
12055 function set_userinfo($userinfo)
12057 if ($userinfo === null || $userinfo === '')
12059 $this->userinfo = null;
12063 $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
12065 $this->valid[__FUNCTION__] = true;
12070 * Set the host. Returns true on success, false on failure (if there are
12071 * any invalid characters).
12074 * @param string $host
12077 function set_host($host)
12079 if ($host === null || $host === '')
12081 $this->host = null;
12082 $this->valid[__FUNCTION__] = true;
12085 elseif ($host[0] === '[' && substr($host, -1) === ']')
12087 if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
12089 $this->host = $host;
12090 $this->valid[__FUNCTION__] = true;
12095 $this->host = null;
12096 $this->valid[__FUNCTION__] = false;
12102 $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
12103 $this->valid[__FUNCTION__] = true;
12109 * Set the port. Returns true on success, false on failure (if there are
12110 * any invalid characters).
12113 * @param string $port
12116 function set_port($port)
12118 if ($port === null || $port === '')
12120 $this->port = null;
12121 $this->valid[__FUNCTION__] = true;
12124 elseif (strspn($port, '0123456789') === strlen($port))
12126 $this->port = (int) $port;
12127 $this->valid[__FUNCTION__] = true;
12132 $this->port = null;
12133 $this->valid[__FUNCTION__] = false;
12142 * @param string $path
12145 function set_path($path)
12147 if ($path === null || $path === '')
12149 $this->path = null;
12150 $this->valid[__FUNCTION__] = true;
12153 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
12155 $this->path = null;
12156 $this->valid[__FUNCTION__] = false;
12161 $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
12162 if ($this->scheme !== null)
12164 $this->path = $this->remove_dot_segments($this->path);
12166 $this->valid[__FUNCTION__] = true;
12175 * @param string $query
12178 function set_query($query)
12180 if ($query === null || $query === '')
12182 $this->query = null;
12186 $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?');
12188 $this->valid[__FUNCTION__] = true;
12193 * Set the fragment.
12196 * @param string $fragment
12199 function set_fragment($fragment)
12201 if ($fragment === null || $fragment === '')
12203 $this->fragment = null;
12207 $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12209 $this->valid[__FUNCTION__] = true;
12214 * Get the complete IRI
12222 if ($this->scheme !== null)
12224 $iri .= $this->scheme . ':';
12226 if (($authority = $this->get_authority()) !== null)
12228 $iri .= '//' . $authority;
12230 if ($this->path !== null)
12232 $iri .= $this->path;
12234 if ($this->query !== null)
12236 $iri .= '?' . $this->query;
12238 if ($this->fragment !== null)
12240 $iri .= '#' . $this->fragment;
12259 function get_scheme()
12261 return $this->scheme;
12265 * Get the complete authority
12270 function get_authority()
12273 if ($this->userinfo !== null)
12275 $authority .= $this->userinfo . '@';
12277 if ($this->host !== null)
12279 $authority .= $this->host;
12281 if ($this->port !== null)
12283 $authority .= ':' . $this->port;
12286 if ($authority !== '')
12297 * Get the user information
12302 function get_userinfo()
12304 return $this->userinfo;
12313 function get_host()
12315 return $this->host;
12324 function get_port()
12326 return $this->port;
12335 function get_path()
12337 return $this->path;
12346 function get_query()
12348 return $this->query;
12357 function get_fragment()
12359 return $this->fragment;
12364 * Class to validate and to work with IPv6 addresses.
12366 * @package SimplePie
12367 * @copyright 2003-2005 The PHP Group
12368 * @license http://www.opensource.org/licenses/bsd-license.php
12369 * @link http://pear.php.net/package/Net_IPv6
12370 * @author Alexander Merz <alexander.merz@web.de>
12371 * @author elfrink at introweb dot nl
12372 * @author Josh Peck <jmp at joshpeck dot org>
12373 * @author Geoffrey Sneddon <geoffers@gmail.com>
12375 class SimplePie_Net_IPv6
12378 * Removes a possible existing netmask specification of an IP address.
12380 * @param string $ip the (compressed) IP as Hex representation
12381 * @return string the IP the without netmask
12386 function removeNetmaskSpec($ip)
12388 if (strpos($ip, '/') !== false)
12390 list($addr, $nm) = explode('/', $ip);
12400 * Uncompresses an IPv6 address
12402 * RFC 2373 allows you to compress zeros in an address to '::'. This
12403 * function expects an valid IPv6 address and expands the '::' to
12404 * the required zeros.
12406 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
12407 * ::1 -> 0:0:0:0:0:0:0:1
12411 * @param string $ip a valid IPv6-address (hex format)
12412 * @return string the uncompressed IPv6-address (hex format)
12414 function Uncompress($ip)
12416 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
12419 if (strpos($ip, '::') !== false)
12421 list($ip1, $ip2) = explode('::', $ip);
12429 if (($pos = substr_count($ip1, ':')) > 0)
12445 if (($pos = substr_count($ip2, ':')) > 0)
12454 if (strstr($ip2, '.'))
12459 if ($c1 === -1 && $c2 === -1)
12461 $uip = '0:0:0:0:0:0:0:0';
12464 else if ($c1 === -1)
12466 $fill = str_repeat('0:', 7 - $c2);
12467 $uip = str_replace('::', $fill, $uip);
12470 else if ($c2 === -1)
12472 $fill = str_repeat(':0', 7 - $c1);
12473 $uip = str_replace('::', $fill, $uip);
12478 $fill = str_repeat(':0:', 6 - $c2 - $c1);
12479 $uip = str_replace('::', $fill, $uip);
12480 $uip = str_replace('::', ':', $uip);
12487 * Splits an IPv6 address into the IPv6 and a possible IPv4 part
12489 * RFC 2373 allows you to note the last two parts of an IPv6 address as
12490 * an IPv4 compatible address
12492 * Example: 0:0:0:0:0:0:13.1.68.3
12493 * 0:0:0:0:0:FFFF:129.144.52.38
12497 * @param string $ip a valid IPv6-address (hex format)
12498 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
12500 function SplitV64($ip)
12502 $ip = SimplePie_Net_IPv6::Uncompress($ip);
12503 if (strstr($ip, '.'))
12505 $pos = strrpos($ip, ':');
12507 $ipPart = explode('_', $ip);
12512 return array($ip, '');
12517 * Checks an IPv6 address
12519 * Checks if the given IP is IPv6-compatible
12523 * @param string $ip a valid IPv6-address
12524 * @return bool true if $ip is an IPv6 address
12526 function checkIPv6($ip)
12528 $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
12530 if (!empty($ipPart[0]))
12532 $ipv6 = explode(':', $ipPart[0]);
12533 for ($i = 0; $i < count($ipv6); $i++)
12535 $dec = hexdec($ipv6[$i]);
12536 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12537 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12546 elseif ($count === 6 && !empty($ipPart[1]))
12548 $ipv4 = explode('.', $ipPart[1]);
12550 foreach ($ipv4 as $ipv4_part)
12552 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12578 * @package SimplePie
12580 class SimplePie_Parse_Date
12585 * @access protected
12591 * List of days, calendar day name => ordinal day number in the week
12593 * @access protected
12656 'keskiviikko' => 3,
12680 * List of months, calendar month name => calendar month number
12682 * @access protected
12685 var $month = array(
12696 // No long form of May
12825 * List of timezones, abbreviation => offset from UTC
12827 * @access protected
12830 var $timezone = array(
13033 * Cached PCRE for SimplePie_Parse_Date::$day
13035 * @access protected
13041 * Cached PCRE for SimplePie_Parse_Date::$month
13043 * @access protected
13049 * Array of user-added callback methods
13054 var $built_in = array();
13057 * Array of user-added callback methods
13062 var $user = array();
13065 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
13066 * self::month_pcre, and self::built_in
13070 function SimplePie_Parse_Date()
13072 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
13073 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
13076 if (!isset($cache[get_class($this)]))
13078 $all_methods = get_class_methods($this);
13080 foreach ($all_methods as $method)
13082 if (strtolower(substr($method, 0, 5)) === 'date_')
13084 $cache[get_class($this)][] = $method;
13089 foreach ($cache[get_class($this)] as $method)
13091 $this->built_in[] = $method;
13105 $object = new SimplePie_Parse_Date;
13115 * @param string $date Date to parse
13116 * @return int Timestamp corresponding to date string, or false on failure
13118 function parse($date)
13120 foreach ($this->user as $method)
13122 if (($returned = call_user_func($method, $date)) !== false)
13128 foreach ($this->built_in as $method)
13130 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
13140 * Add a callback method to parse a date
13144 * @param callback $callback
13146 function add_callback($callback)
13148 if (is_callable($callback))
13150 $this->user[] = $callback;
13154 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
13159 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
13160 * well as allowing any of upper or lower case "T", horizontal tabs, or
13161 * spaces to be used as the time seperator (including more than one))
13163 * @access protected
13164 * @return int Timestamp
13166 function date_w3cdtf($date)
13171 $year = '([0-9]{4})';
13172 $month = $day = $hour = $minute = $second = '([0-9]{2})';
13173 $decimal = '([0-9]*)';
13174 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
13175 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
13177 if (preg_match($pcre, $date, $match))
13180 Capturing subpatterns:
13187 7: Decimal fraction of a second
13191 11: Timezone minutes
13194 // Fill in empty matches
13195 for ($i = count($match); $i <= 3; $i++)
13200 for ($i = count($match); $i <= 7; $i++)
13205 // Numeric timezone
13206 if (isset($match[9]) && $match[9] !== '')
13208 $timezone = $match[10] * 3600;
13209 $timezone += $match[11] * 60;
13210 if ($match[9] === '-')
13212 $timezone = 0 - $timezone;
13220 // Convert the number of seconds to an integer, taking decimals into account
13221 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
13223 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
13232 * Remove RFC822 comments
13234 * @access protected
13235 * @param string $data Data to strip comments from
13236 * @return string Comment stripped string
13238 function remove_rfc2822_comments($string)
13240 $string = (string) $string;
13242 $length = strlen($string);
13247 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
13249 $output .= substr($string, $position, $pos - $position);
13250 $position = $pos + 1;
13251 if ($string[$pos - 1] !== '\\')
13254 while ($depth && $position < $length)
13256 $position += strcspn($string, '()', $position);
13257 if ($string[$position - 1] === '\\')
13262 elseif (isset($string[$position]))
13264 switch ($string[$position])
13287 $output .= substr($string, $position);
13293 * Parse RFC2822's date format
13295 * @access protected
13296 * @return int Timestamp
13298 function date_rfc2822($date)
13303 $wsp = '[\x09\x20]';
13304 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
13305 $optional_fws = $fws . '?';
13306 $day_name = $this->day_pcre;
13307 $month = $this->month_pcre;
13308 $day = '([0-9]{1,2})';
13309 $hour = $minute = $second = '([0-9]{2})';
13310 $year = '([0-9]{2,4})';
13311 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
13312 $character_zone = '([A-Z]{1,5})';
13313 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
13314 $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';
13316 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
13319 Capturing subpatterns:
13329 10: Timezone minutes
13330 11: Alphabetic timezone
13333 // Find the month number
13334 $month = $this->month[strtolower($match[3])];
13336 // Numeric timezone
13337 if ($match[8] !== '')
13339 $timezone = $match[9] * 3600;
13340 $timezone += $match[10] * 60;
13341 if ($match[8] === '-')
13343 $timezone = 0 - $timezone;
13346 // Character timezone
13347 elseif (isset($this->timezone[strtoupper($match[11])]))
13349 $timezone = $this->timezone[strtoupper($match[11])];
13351 // Assume everything else to be -0000
13357 // Deal with 2/3 digit years
13358 if ($match[4] < 50)
13362 elseif ($match[4] < 1000)
13367 // Second is optional, if it is empty set it to zero
13368 if ($match[7] !== '')
13370 $second = $match[7];
13377 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
13386 * Parse RFC850's date format
13388 * @access protected
13389 * @return int Timestamp
13391 function date_rfc850($date)
13396 $space = '[\x09\x20]+';
13397 $day_name = $this->day_pcre;
13398 $month = $this->month_pcre;
13399 $day = '([0-9]{1,2})';
13400 $year = $hour = $minute = $second = '([0-9]{2})';
13401 $zone = '([A-Z]{1,5})';
13402 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
13404 if (preg_match($pcre, $date, $match))
13407 Capturing subpatterns:
13419 $month = $this->month[strtolower($match[3])];
13421 // Character timezone
13422 if (isset($this->timezone[strtoupper($match[8])]))
13424 $timezone = $this->timezone[strtoupper($match[8])];
13426 // Assume everything else to be -0000
13432 // Deal with 2 digit year
13433 if ($match[4] < 50)
13442 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
13451 * Parse C99's asctime()'s date format
13453 * @access protected
13454 * @return int Timestamp
13456 function date_asctime($date)
13461 $space = '[\x09\x20]+';
13462 $wday_name = $this->day_pcre;
13463 $mon_name = $this->month_pcre;
13464 $day = '([0-9]{1,2})';
13465 $hour = $sec = $min = '([0-9]{2})';
13466 $year = '([0-9]{4})';
13467 $terminator = '\x0A?\x00?';
13468 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
13470 if (preg_match($pcre, $date, $match))
13473 Capturing subpatterns:
13483 $month = $this->month[strtolower($match[2])];
13484 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
13493 * Parse dates using strtotime()
13495 * @access protected
13496 * @return int Timestamp
13498 function date_strtotime($date)
13500 $strtotime = strtotime($date);
13501 if ($strtotime === -1 || $strtotime === false)
13513 * Content-type sniffing
13515 * @package SimplePie
13517 class SimplePie_Content_Type_Sniffer
13522 * @var SimplePie_File
13528 * Create an instance of the class with the input file
13531 * @param SimplePie_Content_Type_Sniffer $file Input file
13533 function SimplePie_Content_Type_Sniffer($file)
13535 $this->file = $file;
13539 * Get the Content-Type of the specified file
13542 * @return string Actual Content-Type
13544 function get_type()
13546 if (isset($this->file->headers['content-type']))
13548 if (!isset($this->file->headers['content-encoding'])
13549 && ($this->file->headers['content-type'] === 'text/plain'
13550 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
13551 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
13553 return $this->text_or_binary();
13556 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
13558 $official = substr($this->file->headers['content-type'], 0, $pos);
13562 $official = $this->file->headers['content-type'];
13564 $official = strtolower($official);
13566 if ($official === 'unknown/unknown'
13567 || $official === 'application/unknown')
13569 return $this->unknown();
13571 elseif (substr($official, -4) === '+xml'
13572 || $official === 'text/xml'
13573 || $official === 'application/xml')
13577 elseif (substr($official, 0, 6) === 'image/')
13579 if ($return = $this->image())
13588 elseif ($official === 'text/html')
13590 return $this->feed_or_html();
13599 return $this->unknown();
13604 * Sniff text or binary
13607 * @return string Actual Content-Type
13609 function text_or_binary()
13611 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
13612 || substr($this->file->body, 0, 2) === "\xFF\xFE"
13613 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
13614 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
13616 return 'text/plain';
13618 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
13620 return 'application/octect-stream';
13624 return 'text/plain';
13632 * @return string Actual Content-Type
13636 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
13637 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
13638 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
13639 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
13641 return 'text/html';
13643 elseif (substr($this->file->body, 0, 5) === '%PDF-')
13645 return 'application/pdf';
13647 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
13649 return 'application/postscript';
13651 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
13652 || substr($this->file->body, 0, 6) === 'GIF89a')
13654 return 'image/gif';
13656 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13658 return 'image/png';
13660 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13662 return 'image/jpeg';
13664 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13666 return 'image/bmp';
13670 return $this->text_or_binary();
13678 * @return string Actual Content-Type
13682 if (substr($this->file->body, 0, 6) === 'GIF87a'
13683 || substr($this->file->body, 0, 6) === 'GIF89a')
13685 return 'image/gif';
13687 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13689 return 'image/png';
13691 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13693 return 'image/jpeg';
13695 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13697 return 'image/bmp';
13709 * @return string Actual Content-Type
13711 function feed_or_html()
13713 $len = strlen($this->file->body);
13714 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
13716 while ($pos < $len)
13718 switch ($this->file->body[$pos])
13724 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
13732 return 'text/html';
13735 if (substr($this->file->body, $pos, 3) === '!--')
13738 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
13744 return 'text/html';
13747 elseif (substr($this->file->body, $pos, 1) === '!')
13749 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
13755 return 'text/html';
13758 elseif (substr($this->file->body, $pos, 1) === '?')
13760 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
13766 return 'text/html';
13769 elseif (substr($this->file->body, $pos, 3) === 'rss'
13770 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
13772 return 'application/rss+xml';
13774 elseif (substr($this->file->body, $pos, 4) === 'feed')
13776 return 'application/atom+xml';
13780 return 'text/html';
13784 return 'text/html';
13789 * Parses the XML Declaration
13791 * @package SimplePie
13793 class SimplePie_XML_Declaration_Parser
13801 var $version = '1.0';
13809 var $encoding = 'UTF-8';
13817 var $standalone = false;
13820 * Current state of the state machine
13825 var $state = 'before_version_name';
13836 * Input data length (to avoid calling strlen() everytime this is needed)
13841 var $data_length = 0;
13844 * Current position of the pointer
13852 * Create an instance of the class with the input data
13855 * @param string $data Input data
13857 function SimplePie_XML_Declaration_Parser($data)
13859 $this->data = $data;
13860 $this->data_length = strlen($this->data);
13864 * Parse the input data
13867 * @return bool true on success, false on failure
13871 while ($this->state && $this->state !== 'emit' && $this->has_data())
13873 $state = $this->state;
13877 if ($this->state === 'emit')
13883 $this->version = '';
13884 $this->encoding = '';
13885 $this->standalone = '';
13891 * Check whether there is data beyond the pointer
13894 * @return bool true if there is further data, false if not
13896 function has_data()
13898 return (bool) ($this->position < $this->data_length);
13902 * Advance past any whitespace
13904 * @return int Number of whitespace characters passed
13906 function skip_whitespace()
13908 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
13909 $this->position += $whitespace;
13910 return $whitespace;
13916 function get_value()
13918 $quote = substr($this->data, $this->position, 1);
13919 if ($quote === '"' || $quote === "'")
13922 $len = strcspn($this->data, $quote, $this->position);
13923 if ($this->has_data())
13925 $value = substr($this->data, $this->position, $len);
13926 $this->position += $len + 1;
13933 function before_version_name()
13935 if ($this->skip_whitespace())
13937 $this->state = 'version_name';
13941 $this->state = false;
13945 function version_name()
13947 if (substr($this->data, $this->position, 7) === 'version')
13949 $this->position += 7;
13950 $this->skip_whitespace();
13951 $this->state = 'version_equals';
13955 $this->state = false;
13959 function version_equals()
13961 if (substr($this->data, $this->position, 1) === '=')
13964 $this->skip_whitespace();
13965 $this->state = 'version_value';
13969 $this->state = false;
13973 function version_value()
13975 if ($this->version = $this->get_value())
13977 $this->skip_whitespace();
13978 if ($this->has_data())
13980 $this->state = 'encoding_name';
13984 $this->state = 'emit';
13989 $this->state = false;
13993 function encoding_name()
13995 if (substr($this->data, $this->position, 8) === 'encoding')
13997 $this->position += 8;
13998 $this->skip_whitespace();
13999 $this->state = 'encoding_equals';
14003 $this->state = 'standalone_name';
14007 function encoding_equals()
14009 if (substr($this->data, $this->position, 1) === '=')
14012 $this->skip_whitespace();
14013 $this->state = 'encoding_value';
14017 $this->state = false;
14021 function encoding_value()
14023 if ($this->encoding = $this->get_value())
14025 $this->skip_whitespace();
14026 if ($this->has_data())
14028 $this->state = 'standalone_name';
14032 $this->state = 'emit';
14037 $this->state = false;
14041 function standalone_name()
14043 if (substr($this->data, $this->position, 10) === 'standalone')
14045 $this->position += 10;
14046 $this->skip_whitespace();
14047 $this->state = 'standalone_equals';
14051 $this->state = false;
14055 function standalone_equals()
14057 if (substr($this->data, $this->position, 1) === '=')
14060 $this->skip_whitespace();
14061 $this->state = 'standalone_value';
14065 $this->state = false;
14069 function standalone_value()
14071 if ($standalone = $this->get_value())
14073 switch ($standalone)
14076 $this->standalone = true;
14080 $this->standalone = false;
14084 $this->state = false;
14088 $this->skip_whitespace();
14089 if ($this->has_data())
14091 $this->state = false;
14095 $this->state = 'emit';
14100 $this->state = false;
14105 class SimplePie_Locator
14110 var $local = array();
14111 var $elsewhere = array();
14112 var $file_class = 'SimplePie_File';
14113 var $cached_entities = array();
14116 var $base_location = 0;
14117 var $checked_feeds = 0;
14118 var $max_checked_feeds = 10;
14119 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
14121 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
14123 $this->file =& $file;
14124 $this->file_class = $file_class;
14125 $this->useragent = $useragent;
14126 $this->timeout = $timeout;
14127 $this->max_checked_feeds = $max_checked_feeds;
14128 $this->content_type_sniffer_class = $content_type_sniffer_class;
14131 function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
14133 if ($this->is_feed($this->file))
14135 return $this->file;
14138 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14140 $sniffer = new $this->content_type_sniffer_class($this->file);
14141 if ($sniffer->get_type() !== 'text/html')
14147 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
14152 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
14154 return $working[0];
14157 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
14159 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
14164 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
14169 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
14174 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
14182 function is_feed(&$file)
14184 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14186 $sniffer = new $this->content_type_sniffer_class($file);
14187 $sniffed = $sniffer->get_type();
14188 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
14197 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
14207 function get_base()
14209 $this->http_base = $this->file->url;
14210 $this->base = $this->http_base;
14211 $elements = SimplePie_Misc::get_element('base', $this->file->body);
14212 foreach ($elements as $element)
14214 if ($element['attribs']['href']['data'] !== '')
14216 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
14217 $this->base_location = $element['offset'];
14223 function autodiscovery()
14225 $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));
14228 foreach ($links as $link)
14230 if ($this->checked_feeds === $this->max_checked_feeds)
14234 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
14236 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
14238 if ($this->base_location < $link['offset'])
14240 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14244 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14247 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'))) && !isset($feeds[$href]))
14249 $this->checked_feeds++;
14250 $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
14251 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14253 $feeds[$href] = $feed;
14260 if (!empty($feeds))
14262 return array_values($feeds);
14269 function get_links()
14271 $links = SimplePie_Misc::get_element('a', $this->file->body);
14272 foreach ($links as $link)
14274 if (isset($link['attribs']['href']['data']))
14276 $href = trim($link['attribs']['href']['data']);
14277 $parsed = SimplePie_Misc::parse_url($href);
14278 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
14280 if ($this->base_location < $link['offset'])
14282 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14286 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14289 $current = SimplePie_Misc::parse_url($this->file->url);
14291 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
14293 $this->local[] = $href;
14297 $this->elsewhere[] = $href;
14302 $this->local = array_unique($this->local);
14303 $this->elsewhere = array_unique($this->elsewhere);
14304 if (!empty($this->local) || !empty($this->elsewhere))
14311 function extension(&$array)
14313 foreach ($array as $key => $value)
14315 if ($this->checked_feeds === $this->max_checked_feeds)
14319 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
14321 $this->checked_feeds++;
14322 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14323 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14329 unset($array[$key]);
14336 function body(&$array)
14338 foreach ($array as $key => $value)
14340 if ($this->checked_feeds === $this->max_checked_feeds)
14344 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
14346 $this->checked_feeds++;
14347 $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14348 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14354 unset($array[$key]);
14362 class SimplePie_Parser
14367 var $current_column;
14369 var $separator = ' ';
14370 var $namespace = array('');
14371 var $element = array('');
14372 var $xml_base = array('');
14373 var $xml_base_explicit = array(false);
14374 var $xml_lang = array('');
14375 var $data = array();
14376 var $datas = array(array());
14377 var $current_xhtml_construct = -1;
14380 function parse(&$data, $encoding)
14382 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
14383 if (strtoupper($encoding) === 'US-ASCII')
14385 $this->encoding = 'UTF-8';
14389 $this->encoding = $encoding;
14393 // UTF-32 Big Endian BOM
14394 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
14396 $data = substr($data, 4);
14398 // UTF-32 Little Endian BOM
14399 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
14401 $data = substr($data, 4);
14403 // UTF-16 Big Endian BOM
14404 elseif (substr($data, 0, 2) === "\xFE\xFF")
14406 $data = substr($data, 2);
14408 // UTF-16 Little Endian BOM
14409 elseif (substr($data, 0, 2) === "\xFF\xFE")
14411 $data = substr($data, 2);
14414 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
14416 $data = substr($data, 3);
14419 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
14421 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
14422 if ($declaration->parse())
14424 $data = substr($data, $pos + 2);
14425 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
14429 $this->error_string = 'SimplePie bug! Please report this!';
14436 static $xml_is_sane = null;
14437 if ($xml_is_sane === null)
14439 $parser_check = xml_parser_create();
14440 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
14441 xml_parser_free($parser_check);
14442 $xml_is_sane = isset($values[0]['value']);
14445 // Create the parser
14448 $xml = xml_parser_create_ns($this->encoding, $this->separator);
14449 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
14450 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
14451 xml_set_object($xml, $this);
14452 xml_set_character_data_handler($xml, 'cdata');
14453 xml_set_element_handler($xml, 'tag_open', 'tag_close');
14456 if (!xml_parse($xml, $data, true))
14458 $this->error_code = xml_get_error_code($xml);
14459 $this->error_string = xml_error_string($this->error_code);
14462 $this->current_line = xml_get_current_line_number($xml);
14463 $this->current_column = xml_get_current_column_number($xml);
14464 $this->current_byte = xml_get_current_byte_index($xml);
14465 xml_parser_free($xml);
14470 libxml_clear_errors();
14471 $xml = new XMLReader();
14473 while (@$xml->read())
14475 switch ($xml->nodeType)
14478 case constant('XMLReader::END_ELEMENT'):
14479 if ($xml->namespaceURI !== '')
14481 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14485 $tagName = $xml->localName;
14487 $this->tag_close(null, $tagName);
14489 case constant('XMLReader::ELEMENT'):
14490 $empty = $xml->isEmptyElement;
14491 if ($xml->namespaceURI !== '')
14493 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14497 $tagName = $xml->localName;
14499 $attributes = array();
14500 while ($xml->moveToNextAttribute())
14502 if ($xml->namespaceURI !== '')
14504 $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14508 $attrName = $xml->localName;
14510 $attributes[$attrName] = $xml->value;
14512 $this->tag_open(null, $tagName, $attributes);
14515 $this->tag_close(null, $tagName);
14518 case constant('XMLReader::TEXT'):
14520 case constant('XMLReader::CDATA'):
14521 $this->cdata(null, $xml->value);
14525 if ($error = libxml_get_last_error())
14527 $this->error_code = $error->code;
14528 $this->error_string = $error->message;
14529 $this->current_line = $error->line;
14530 $this->current_column = $error->column;
14540 function get_error_code()
14542 return $this->error_code;
14545 function get_error_string()
14547 return $this->error_string;
14550 function get_current_line()
14552 return $this->current_line;
14555 function get_current_column()
14557 return $this->current_column;
14560 function get_current_byte()
14562 return $this->current_byte;
14565 function get_data()
14567 return $this->data;
14570 function tag_open($parser, $tag, $attributes)
14572 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
14574 $attribs = array();
14575 foreach ($attributes as $name => $value)
14577 list($attrib_namespace, $attribute) = $this->split_ns($name);
14578 $attribs[$attrib_namespace][$attribute] = $value;
14581 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
14583 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
14584 $this->xml_base_explicit[] = true;
14588 $this->xml_base[] = end($this->xml_base);
14589 $this->xml_base_explicit[] = end($this->xml_base_explicit);
14592 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
14594 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
14598 $this->xml_lang[] = end($this->xml_lang);
14601 if ($this->current_xhtml_construct >= 0)
14603 $this->current_xhtml_construct++;
14604 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
14606 $this->data['data'] .= '<' . end($this->element);
14607 if (isset($attribs['']))
14609 foreach ($attribs[''] as $name => $value)
14611 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
14614 $this->data['data'] .= '>';
14619 $this->datas[] =& $this->data;
14620 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
14621 $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));
14622 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')
14623 || (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'))
14625 $this->current_xhtml_construct = 0;
14630 function cdata($parser, $cdata)
14632 if ($this->current_xhtml_construct >= 0)
14634 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
14638 $this->data['data'] .= $cdata;
14642 function tag_close($parser, $tag)
14644 if ($this->current_xhtml_construct >= 0)
14646 $this->current_xhtml_construct--;
14647 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')))
14649 $this->data['data'] .= '</' . end($this->element) . '>';
14652 if ($this->current_xhtml_construct === -1)
14654 $this->data =& $this->datas[count($this->datas) - 1];
14655 array_pop($this->datas);
14658 array_pop($this->element);
14659 array_pop($this->namespace);
14660 array_pop($this->xml_base);
14661 array_pop($this->xml_base_explicit);
14662 array_pop($this->xml_lang);
14665 function split_ns($string)
14667 static $cache = array();
14668 if (!isset($cache[$string]))
14670 if ($pos = strpos($string, $this->separator))
14672 static $separator_length;
14673 if (!$separator_length)
14675 $separator_length = strlen($this->separator);
14677 $namespace = substr($string, 0, $pos);
14678 $local_name = substr($string, $pos + $separator_length);
14679 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
14681 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
14684 // Normalize the Media RSS namespaces
14685 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
14687 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
14689 $cache[$string] = array($namespace, $local_name);
14693 $cache[$string] = array('', $string);
14696 return $cache[$string];
14701 * @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
14703 class SimplePie_Sanitize
14709 var $remove_div = true;
14710 var $image_handler = '';
14711 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14712 var $encode_instead_of_strip = false;
14713 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14714 var $strip_comments = false;
14715 var $output_encoding = 'UTF-8';
14716 var $enable_cache = true;
14717 var $cache_location = './cache';
14718 var $cache_name_function = 'md5';
14719 var $cache_class = 'SimplePie_Cache';
14720 var $file_class = 'SimplePie_File';
14722 var $useragent = '';
14723 var $force_fsockopen = false;
14725 var $replace_url_attributes = array(
14728 'blockquote' => 'cite',
14730 'form' => 'action',
14731 'img' => array('longdesc', 'src'),
14737 function remove_div($enable = true)
14739 $this->remove_div = (bool) $enable;
14742 function set_image_handler($page = false)
14746 $this->image_handler = (string) $page;
14750 $this->image_handler = false;
14754 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
14756 if (isset($enable_cache))
14758 $this->enable_cache = (bool) $enable_cache;
14761 if ($cache_location)
14763 $this->cache_location = (string) $cache_location;
14766 if ($cache_name_function)
14768 $this->cache_name_function = (string) $cache_name_function;
14773 $this->cache_class = (string) $cache_class;
14777 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
14781 $this->file_class = (string) $file_class;
14786 $this->timeout = (string) $timeout;
14791 $this->useragent = (string) $useragent;
14794 if ($force_fsockopen)
14796 $this->force_fsockopen = (string) $force_fsockopen;
14800 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
14804 if (is_array($tags))
14806 $this->strip_htmltags = $tags;
14810 $this->strip_htmltags = explode(',', $tags);
14815 $this->strip_htmltags = false;
14819 function encode_instead_of_strip($encode = false)
14821 $this->encode_instead_of_strip = (bool) $encode;
14824 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
14828 if (is_array($attribs))
14830 $this->strip_attributes = $attribs;
14834 $this->strip_attributes = explode(',', $attribs);
14839 $this->strip_attributes = false;
14843 function strip_comments($strip = false)
14845 $this->strip_comments = (bool) $strip;
14848 function set_output_encoding($encoding = 'UTF-8')
14850 $this->output_encoding = (string) $encoding;
14854 * Set element/attribute key/value pairs of HTML attributes
14855 * containing URLs that need to be resolved relative to the feed
14859 * @param array $element_attribute Element/attribute key/value pairs
14861 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'))
14863 $this->replace_url_attributes = (array) $element_attribute;
14866 function sanitize($data, $type, $base = '')
14868 $data = trim($data);
14869 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
14871 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
14873 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))
14875 $type |= SIMPLEPIE_CONSTRUCT_HTML;
14879 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
14883 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
14885 $data = base64_decode($data);
14888 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
14890 if ($this->remove_div)
14892 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
14893 $data = preg_replace('/<\/div>$/', '', $data);
14897 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
14901 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
14904 if ($this->strip_comments)
14906 $data = SimplePie_Misc::strip_comments($data);
14909 // Strip out HTML tags and attributes that might cause various security problems.
14910 // Based on recommendations by Mark Pilgrim at:
14911 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
14912 if ($this->strip_htmltags)
14914 foreach ($this->strip_htmltags as $tag)
14916 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
14917 while (preg_match($pcre, $data))
14919 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
14924 if ($this->strip_attributes)
14926 foreach ($this->strip_attributes as $attrib)
14928 $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);
14932 // Replace relative URLs
14933 $this->base = $base;
14934 foreach ($this->replace_url_attributes as $element => $attributes)
14936 $data = $this->replace_urls($data, $element, $attributes);
14939 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
14940 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
14942 $images = SimplePie_Misc::get_element('img', $data);
14943 foreach ($images as $img)
14945 if (isset($img['attribs']['src']['data']))
14947 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
14948 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
14950 if ($cache->load())
14952 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14953 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14957 $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
14958 $headers = $file->headers;
14960 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
14962 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
14964 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14965 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14969 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
14977 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
14978 $data = trim($data);
14981 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
14983 $data = SimplePie_Misc::absolutize_url($data, $base);
14986 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
14988 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
14991 if ($this->output_encoding !== 'UTF-8')
14993 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
14999 function replace_urls($data, $tag, $attributes)
15001 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
15003 $elements = SimplePie_Misc::get_element($tag, $data);
15004 foreach ($elements as $element)
15006 if (is_array($attributes))
15008 foreach ($attributes as $attribute)
15010 if (isset($element['attribs'][$attribute]['data']))
15012 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
15013 $new_element = SimplePie_Misc::element_implode($element);
15014 $data = str_replace($element['full'], $new_element, $data);
15015 $element['full'] = $new_element;
15019 elseif (isset($element['attribs'][$attributes]['data']))
15021 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
15022 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
15029 function do_strip_htmltags($match)
15031 if ($this->encode_instead_of_strip)
15033 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
15035 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
15036 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
15037 return "<$match[1]$match[2]>$match[3]</$match[1]>";
15041 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
15044 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))