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');
59 define('SIMPLEPIE_BUILD', '20090627192103');
62 * SimplePie Website URL
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
68 * @see SimplePie::set_useragent()
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
79 * @see SimplePie::set_autodiscovery_level()
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
122 define('SIMPLEPIE_TYPE_NONE', 0);
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
130 * RSS 0.91 (Netscape)
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
135 * RSS 0.91 (Userland)
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
140 * RSS 0.91 (both Netscape and Userland)
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
175 * Non-RDF-based RSS (truly intended as syndication format)
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
202 define('SIMPLEPIE_TYPE_ALL', 1023);
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
225 * base64-encoded construct
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
235 * A construct that might be HTML
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
247 define('SIMPLEPIE_SAME_CASE', 1);
250 * Change to lowercase
252 define('SIMPLEPIE_LOWERCASE', 2);
255 * Change to uppercase
257 define('SIMPLEPIE_UPPERCASE', 4);
260 * PCRE for HTML attributes
262 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]*');
265 * PCRE for XML attributes
267 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
272 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
277 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
282 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
287 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
292 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
297 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
300 * RSS 1.0 Content Module Namespace
302 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
306 * (Stupid, I know, but I'm certain it will confuse people less with support.)
308 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
313 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
318 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
321 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
323 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
328 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
331 * Media RSS Namespace
333 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
336 * Wrong Media RSS Namespace
338 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
341 * iTunes RSS Namespace
343 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
348 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
351 * IANA Link Relations Registry
353 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
356 * Whether we're running on PHP5
358 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
363 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
368 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
373 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
376 * fsockopen() file source
378 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
383 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
386 * file_get_contents() file source
388 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
398 * @var array Raw data
404 * @var mixed Error string
410 * @var object Instance of SimplePie_Sanitize (or other class)
411 * @see SimplePie::set_sanitize_class()
417 * @var string SimplePie Useragent
418 * @see SimplePie::set_useragent()
421 var $useragent = SIMPLEPIE_USERAGENT;
424 * @var string Feed URL
425 * @see SimplePie::set_feed_url()
431 * @var object Instance of SimplePie_File to use as a feed
432 * @see SimplePie::set_file()
438 * @var string Raw feed data
439 * @see SimplePie::set_raw_data()
445 * @var int Timeout for fetching remote files
446 * @see SimplePie::set_timeout()
452 * @var bool Forces fsockopen() to be used for remote files instead
453 * of cURL, even if a new enough version is installed
454 * @see SimplePie::force_fsockopen()
457 var $force_fsockopen = false;
460 * @var bool Force the given data/URL to be treated as a feed no matter what
462 * @see SimplePie::force_feed()
465 var $force_feed = false;
468 * @var bool Enable/Disable XML dump
469 * @see SimplePie::enable_xml_dump()
472 var $xml_dump = false;
475 * @var bool Enable/Disable Caching
476 * @see SimplePie::enable_cache()
482 * @var int Cache duration (in seconds)
483 * @see SimplePie::set_cache_duration()
486 var $cache_duration = 3600;
489 * @var int Auto-discovery cache duration (in seconds)
490 * @see SimplePie::set_autodiscovery_cache_duration()
493 var $autodiscovery_cache_duration = 604800; // 7 Days.
496 * @var string Cache location (relative to executing script)
497 * @see SimplePie::set_cache_location()
500 var $cache_location = './cache';
503 * @var string Function that creates the cache filename
504 * @see SimplePie::set_cache_name_function()
507 var $cache_name_function = 'md5';
510 * @var bool Reorder feed by date descending
511 * @see SimplePie::enable_order_by_date()
514 var $order_by_date = true;
517 * @var mixed Force input encoding to be set to the follow value
518 * (false, or anything type-cast to false, disables this feature)
519 * @see SimplePie::set_input_encoding()
522 var $input_encoding = false;
525 * @var int Feed Autodiscovery Level
526 * @see SimplePie::set_autodiscovery_level()
529 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
532 * @var string Class used for caching feeds
533 * @see SimplePie::set_cache_class()
536 var $cache_class = 'SimplePie_Cache';
539 * @var string Class used for locating feeds
540 * @see SimplePie::set_locator_class()
543 var $locator_class = 'SimplePie_Locator';
546 * @var string Class used for parsing feeds
547 * @see SimplePie::set_parser_class()
550 var $parser_class = 'SimplePie_Parser';
553 * @var string Class used for fetching feeds
554 * @see SimplePie::set_file_class()
557 var $file_class = 'SimplePie_File';
560 * @var string Class used for items
561 * @see SimplePie::set_item_class()
564 var $item_class = 'SimplePie_Item';
567 * @var string Class used for authors
568 * @see SimplePie::set_author_class()
571 var $author_class = 'SimplePie_Author';
574 * @var string Class used for categories
575 * @see SimplePie::set_category_class()
578 var $category_class = 'SimplePie_Category';
581 * @var string Class used for enclosures
582 * @see SimplePie::set_enclosures_class()
585 var $enclosure_class = 'SimplePie_Enclosure';
588 * @var string Class used for Media RSS <media:text> captions
589 * @see SimplePie::set_caption_class()
592 var $caption_class = 'SimplePie_Caption';
595 * @var string Class used for Media RSS <media:copyright>
596 * @see SimplePie::set_copyright_class()
599 var $copyright_class = 'SimplePie_Copyright';
602 * @var string Class used for Media RSS <media:credit>
603 * @see SimplePie::set_credit_class()
606 var $credit_class = 'SimplePie_Credit';
609 * @var string Class used for Media RSS <media:rating>
610 * @see SimplePie::set_rating_class()
613 var $rating_class = 'SimplePie_Rating';
616 * @var string Class used for Media RSS <media:restriction>
617 * @see SimplePie::set_restriction_class()
620 var $restriction_class = 'SimplePie_Restriction';
623 * @var string Class used for content-type sniffing
624 * @see SimplePie::set_content_type_sniffer_class()
627 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
630 * @var string Class used for item sources.
631 * @see SimplePie::set_source_class()
634 var $source_class = 'SimplePie_Source';
637 * @var mixed Set javascript query string parameter (false, or
638 * anything type-cast to false, disables this feature)
639 * @see SimplePie::set_javascript()
642 var $javascript = 'js';
645 * @var int Maximum number of feeds to check with autodiscovery
646 * @see SimplePie::set_max_checked_feeds()
649 var $max_checked_feeds = 10;
652 * @var array All the feeds found during the autodiscovery process
653 * @see SimplePie::get_all_discovered_feeds()
656 var $all_discovered_feeds = array();
659 * @var string Web-accessible path to the handler_favicon.php file.
660 * @see SimplePie::set_favicon_handler()
663 var $favicon_handler = '';
666 * @var string Web-accessible path to the handler_image.php file.
667 * @see SimplePie::set_image_handler()
670 var $image_handler = '';
673 * @var array Stores the URLs when multiple feeds are being initialized.
674 * @see SimplePie::set_feed_url()
677 var $multifeed_url = array();
680 * @var array Stores SimplePie objects when multiple feeds initialized.
683 var $multifeed_objects = array();
686 * @var array Stores the get_object_vars() array for use with multifeeds.
687 * @see SimplePie::set_feed_url()
690 var $config_settings = null;
693 * @var integer Stores the number of items to return per-feed with multifeeds.
694 * @see SimplePie::set_item_limit()
700 * @var array Stores the default attributes to be stripped by strip_attributes().
701 * @see SimplePie::strip_attributes()
704 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
707 * @var array Stores the default tags to be stripped by strip_htmltags().
708 * @see SimplePie::strip_htmltags()
711 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
714 * The SimplePie class contains feed level data and options
716 * There are two ways that you can create a new SimplePie object. The first
717 * is by passing a feed URL as a parameter to the SimplePie constructor
718 * (as well as optionally setting the cache location and cache expiry). This
719 * will initialise the whole feed with all of the default settings, and you
720 * can begin accessing methods and properties immediately.
722 * The second way is to create the SimplePie object with no parameters
723 * at all. This will enable you to set configuration options. After setting
724 * them, you must initialise the feed using $feed->init(). At that point the
725 * object's methods and properties will be available to you. This format is
726 * what is used throughout this documentation.
729 * @since 1.0 Preview Release
730 * @param string $feed_url This is the URL you want to parse.
731 * @param string $cache_location This is where you want the cache to be stored.
732 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
734 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
736 // Other objects, instances created here so we can set options on them
737 $this->sanitize =& new SimplePie_Sanitize;
739 // Set options if they're passed to the constructor
740 if ($cache_location !== null)
742 $this->set_cache_location($cache_location);
745 if ($cache_duration !== null)
747 $this->set_cache_duration($cache_duration);
750 // Only init the script if we're passed a feed URL
751 if ($feed_url !== null)
753 $this->set_feed_url($feed_url);
759 * Used for converting object to a string
761 function __toString()
763 return md5(serialize($this->data));
767 * Remove items that link back to this before destroying this object
769 function __destruct()
771 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
773 if (!empty($this->data['items']))
775 foreach ($this->data['items'] as $item)
779 unset($item, $this->data['items']);
781 if (!empty($this->data['ordered_items']))
783 foreach ($this->data['ordered_items'] as $item)
787 unset($item, $this->data['ordered_items']);
793 * Force the given data/URL to be treated as a feed no matter what it
798 * @param bool $enable Force the given data/URL to be treated as a feed
800 function force_feed($enable = false)
802 $this->force_feed = (bool) $enable;
806 * This is the URL of the feed you want to parse.
808 * This allows you to enter the URL of the feed you want to parse, or the
809 * website you want to try to use auto-discovery on. This takes priority
810 * over any set raw data.
812 * You can set multiple feeds to mash together by passing an array instead
813 * of a string for the $url. Remember that with each additional feed comes
814 * additional processing and resources.
817 * @since 1.0 Preview Release
818 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
819 * @see SimplePie::set_raw_data()
821 function set_feed_url($url)
825 $this->multifeed_url = array();
826 foreach ($url as $value)
828 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
833 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
838 * Provides an instance of SimplePie_File to use as a feed
841 * @param object &$file Instance of SimplePie_File (or subclass)
842 * @return bool True on success, false on failure
844 function set_file(&$file)
846 if (is_a($file, 'SimplePie_File'))
848 $this->feed_url = $file->url;
849 $this->file =& $file;
856 * Allows you to use a string of RSS/Atom data instead of a remote feed.
858 * If you have a feed available as a string in PHP, you can tell SimplePie
859 * to parse that data string instead of a remote feed. Any set feed URL
864 * @param string $data RSS or Atom data as a string.
865 * @see SimplePie::set_feed_url()
867 function set_raw_data($data)
869 $this->raw_data = $data;
873 * Allows you to override the default timeout for fetching remote feeds.
875 * This allows you to change the maximum time the feed's server to respond
876 * and send the feed back.
880 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
882 function set_timeout($timeout = 10)
884 $this->timeout = (int) $timeout;
888 * Forces SimplePie to use fsockopen() instead of the preferred cURL
893 * @param bool $enable Force fsockopen() to be used
895 function force_fsockopen($enable = false)
897 $this->force_fsockopen = (bool) $enable;
901 * Outputs the raw XML content of the feed, after it has gone through
902 * SimplePie's filters.
904 * Used only for debugging, this function will output the XML content as
905 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
906 * before trying to parse it. Many parts of the feed are re-written in
907 * memory, and in the end, you have a parsable feed. XML dump shows you the
908 * actual XML that SimplePie tries to parse, which may or may not be very
909 * different from the original feed.
912 * @since 1.0 Preview Release
913 * @param bool $enable Enable XML dump
915 function enable_xml_dump($enable = false)
917 $this->xml_dump = (bool) $enable;
921 * Enables/disables caching in SimplePie.
923 * This option allows you to disable caching all-together in SimplePie.
924 * However, disabling the cache can lead to longer load times.
927 * @since 1.0 Preview Release
928 * @param bool $enable Enable caching
930 function enable_cache($enable = true)
932 $this->cache = (bool) $enable;
936 * Set the length of time (in seconds) that the contents of a feed
940 * @param int $seconds The feed content cache duration.
942 function set_cache_duration($seconds = 3600)
944 $this->cache_duration = (int) $seconds;
948 * Set the length of time (in seconds) that the autodiscovered feed
949 * URL will be cached.
952 * @param int $seconds The autodiscovered feed URL cache duration.
954 function set_autodiscovery_cache_duration($seconds = 604800)
956 $this->autodiscovery_cache_duration = (int) $seconds;
960 * Set the file system location where the cached files should be stored.
963 * @param string $location The file system location.
965 function set_cache_location($location = './cache')
967 $this->cache_location = (string) $location;
971 * Determines whether feed items should be sorted into reverse chronological order.
974 * @param bool $enable Sort as reverse chronological order.
976 function enable_order_by_date($enable = true)
978 $this->order_by_date = (bool) $enable;
982 * Allows you to override the character encoding reported by the feed.
985 * @param string $encoding Character encoding.
987 function set_input_encoding($encoding = false)
991 $this->input_encoding = (string) $encoding;
995 $this->input_encoding = false;
1000 * Set how much feed autodiscovery to do
1003 * @see SIMPLEPIE_LOCATOR_NONE
1004 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1005 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1006 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1007 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1008 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1009 * @see SIMPLEPIE_LOCATOR_ALL
1010 * @param int $level Feed Autodiscovery Level (level can be a
1011 * combination of the above constants, see bitwise OR operator)
1013 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1015 $this->autodiscovery = (int) $level;
1019 * Allows you to change which class SimplePie uses for caching.
1020 * Useful when you are overloading or extending SimplePie's default classes.
1023 * @param string $class Name of custom class.
1024 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1025 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1027 function set_cache_class($class = 'SimplePie_Cache')
1029 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1031 $this->cache_class = $class;
1038 * Allows you to change which class SimplePie uses for auto-discovery.
1039 * Useful when you are overloading or extending SimplePie's default classes.
1042 * @param string $class Name of custom class.
1043 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1044 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1046 function set_locator_class($class = 'SimplePie_Locator')
1048 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1050 $this->locator_class = $class;
1057 * Allows you to change which class SimplePie uses for XML parsing.
1058 * Useful when you are overloading or extending SimplePie's default classes.
1061 * @param string $class Name of custom class.
1062 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1063 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1065 function set_parser_class($class = 'SimplePie_Parser')
1067 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1069 $this->parser_class = $class;
1076 * Allows you to change which class SimplePie uses for remote file fetching.
1077 * Useful when you are overloading or extending SimplePie's default classes.
1080 * @param string $class Name of custom class.
1081 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1082 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1084 function set_file_class($class = 'SimplePie_File')
1086 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1088 $this->file_class = $class;
1095 * Allows you to change which class SimplePie uses for data sanitization.
1096 * Useful when you are overloading or extending SimplePie's default classes.
1099 * @param string $class Name of custom class.
1100 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1101 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1103 function set_sanitize_class($class = 'SimplePie_Sanitize')
1105 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1107 $this->sanitize =& new $class;
1114 * Allows you to change which class SimplePie uses for handling feed items.
1115 * Useful when you are overloading or extending SimplePie's default classes.
1118 * @param string $class Name of custom class.
1119 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1120 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1122 function set_item_class($class = 'SimplePie_Item')
1124 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1126 $this->item_class = $class;
1133 * Allows you to change which class SimplePie uses for handling author data.
1134 * Useful when you are overloading or extending SimplePie's default classes.
1137 * @param string $class Name of custom class.
1138 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1139 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1141 function set_author_class($class = 'SimplePie_Author')
1143 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1145 $this->author_class = $class;
1152 * Allows you to change which class SimplePie uses for handling category data.
1153 * Useful when you are overloading or extending SimplePie's default classes.
1156 * @param string $class Name of custom class.
1157 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1158 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1160 function set_category_class($class = 'SimplePie_Category')
1162 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1164 $this->category_class = $class;
1171 * Allows you to change which class SimplePie uses for feed enclosures.
1172 * Useful when you are overloading or extending SimplePie's default classes.
1175 * @param string $class Name of custom class.
1176 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1177 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1179 function set_enclosure_class($class = 'SimplePie_Enclosure')
1181 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1183 $this->enclosure_class = $class;
1190 * Allows you to change which class SimplePie uses for <media:text> captions
1191 * Useful when you are overloading or extending SimplePie's default classes.
1194 * @param string $class Name of custom class.
1195 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1196 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1198 function set_caption_class($class = 'SimplePie_Caption')
1200 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1202 $this->caption_class = $class;
1209 * Allows you to change which class SimplePie uses for <media:copyright>
1210 * Useful when you are overloading or extending SimplePie's default classes.
1213 * @param string $class Name of custom class.
1214 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1215 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1217 function set_copyright_class($class = 'SimplePie_Copyright')
1219 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1221 $this->copyright_class = $class;
1228 * Allows you to change which class SimplePie uses for <media:credit>
1229 * Useful when you are overloading or extending SimplePie's default classes.
1232 * @param string $class Name of custom class.
1233 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1234 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1236 function set_credit_class($class = 'SimplePie_Credit')
1238 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1240 $this->credit_class = $class;
1247 * Allows you to change which class SimplePie uses for <media:rating>
1248 * Useful when you are overloading or extending SimplePie's default classes.
1251 * @param string $class Name of custom class.
1252 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1253 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1255 function set_rating_class($class = 'SimplePie_Rating')
1257 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1259 $this->rating_class = $class;
1266 * Allows you to change which class SimplePie uses for <media:restriction>
1267 * Useful when you are overloading or extending SimplePie's default classes.
1270 * @param string $class Name of custom class.
1271 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1272 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1274 function set_restriction_class($class = 'SimplePie_Restriction')
1276 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1278 $this->restriction_class = $class;
1285 * Allows you to change which class SimplePie uses for content-type sniffing.
1286 * Useful when you are overloading or extending SimplePie's default classes.
1289 * @param string $class Name of custom class.
1290 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1291 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1293 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1295 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1297 $this->content_type_sniffer_class = $class;
1304 * Allows you to change which class SimplePie uses item sources.
1305 * Useful when you are overloading or extending SimplePie's default classes.
1308 * @param string $class Name of custom class.
1309 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1310 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1312 function set_source_class($class = 'SimplePie_Source')
1314 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1316 $this->source_class = $class;
1323 * Allows you to override the default user agent string.
1326 * @param string $ua New user agent string.
1328 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1330 $this->useragent = (string) $ua;
1334 * Set callback function to create cache filename with
1337 * @param mixed $function Callback function
1339 function set_cache_name_function($function = 'md5')
1341 if (is_callable($function))
1343 $this->cache_name_function = $function;
1348 * Set javascript query string parameter
1351 * @param mixed $get Javascript query string parameter
1353 function set_javascript($get = 'js')
1357 $this->javascript = (string) $get;
1361 $this->javascript = false;
1366 * Set options to make SP as fast as possible. Forgoes a
1367 * substantial amount of data sanitization in favor of speed.
1370 * @param bool $set Whether to set them or not
1372 function set_stupidly_fast($set = false)
1376 $this->enable_order_by_date(false);
1377 $this->remove_div(false);
1378 $this->strip_comments(false);
1379 $this->strip_htmltags(false);
1380 $this->strip_attributes(false);
1381 $this->set_image_handler(false);
1386 * Set maximum number of feeds to check with autodiscovery
1389 * @param int $max Maximum number of feeds to check
1391 function set_max_checked_feeds($max = 10)
1393 $this->max_checked_feeds = (int) $max;
1396 function remove_div($enable = true)
1398 $this->sanitize->remove_div($enable);
1401 function strip_htmltags($tags = '', $encode = null)
1405 $tags = $this->strip_htmltags;
1407 $this->sanitize->strip_htmltags($tags);
1408 if ($encode !== null)
1410 $this->sanitize->encode_instead_of_strip($tags);
1414 function encode_instead_of_strip($enable = true)
1416 $this->sanitize->encode_instead_of_strip($enable);
1419 function strip_attributes($attribs = '')
1421 if ($attribs === '')
1423 $attribs = $this->strip_attributes;
1425 $this->sanitize->strip_attributes($attribs);
1428 function set_output_encoding($encoding = 'UTF-8')
1430 $this->sanitize->set_output_encoding($encoding);
1433 function strip_comments($strip = false)
1435 $this->sanitize->strip_comments($strip);
1439 * Set element/attribute key/value pairs of HTML attributes
1440 * containing URLs that need to be resolved relative to the feed
1444 * @param array $element_attribute Element/attribute key/value pairs
1446 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'))
1448 $this->sanitize->set_url_replacements($element_attribute);
1452 * Set the handler to enable the display of cached favicons.
1455 * @param str $page Web-accessible path to the handler_favicon.php file.
1456 * @param str $qs The query string that the value should be passed to.
1458 function set_favicon_handler($page = false, $qs = 'i')
1460 if ($page !== false)
1462 $this->favicon_handler = $page . '?' . $qs . '=';
1466 $this->favicon_handler = '';
1471 * Set the handler to enable the display of cached images.
1474 * @param str $page Web-accessible path to the handler_image.php file.
1475 * @param str $qs The query string that the value should be passed to.
1477 function set_image_handler($page = false, $qs = 'i')
1479 if ($page !== false)
1481 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1485 $this->image_handler = '';
1490 * Set the limit for items returned per-feed with multifeeds.
1493 * @param integer $limit The maximum number of items to return.
1495 function set_item_limit($limit = 0)
1497 $this->item_limit = (int) $limit;
1502 // Check absolute bare minimum requirements.
1503 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1507 // 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.
1508 elseif (!extension_loaded('xmlreader'))
1510 static $xml_is_sane = null;
1511 if ($xml_is_sane === null)
1513 $parser_check = xml_parser_create();
1514 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1515 xml_parser_free($parser_check);
1516 $xml_is_sane = isset($values[0]['value']);
1524 if (isset($_GET[$this->javascript]))
1526 SimplePie_Misc::output_javascript();
1530 // Pass whatever was set with config options over to the sanitizer.
1531 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1532 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1534 if ($this->feed_url !== null || $this->raw_data !== null)
1536 $this->data = array();
1537 $this->multifeed_objects = array();
1540 if ($this->feed_url !== null)
1542 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1543 // Decide whether to enable caching
1544 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1546 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1548 // If it's enabled and we don't want an XML dump, use the cache
1549 if ($cache && !$this->xml_dump)
1552 $this->data = $cache->load();
1553 if (!empty($this->data))
1555 // If the cache is for an outdated build of SimplePie
1556 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1559 $this->data = array();
1561 // If we've hit a collision just rerun it with caching disabled
1562 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1565 $this->data = array();
1567 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1568 elseif (isset($this->data['feed_url']))
1570 // If the autodiscovery cache is still valid use it.
1571 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1573 // Do not need to do feed autodiscovery yet.
1574 if ($this->data['feed_url'] === $this->data['url'])
1577 $this->data = array();
1581 $this->set_feed_url($this->data['feed_url']);
1582 return $this->init();
1586 // Check if the cache has been updated
1587 elseif ($cache->mtime() + $this->cache_duration < time())
1589 // If we have last-modified and/or etag set
1590 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1593 if (isset($this->data['headers']['last-modified']))
1595 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1597 if (isset($this->data['headers']['etag']))
1599 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1601 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1604 if ($file->status_code === 304)
1611 $headers = $file->headers;
1620 // If the cache is still valid, just return true
1626 // If the cache is empty, delete it
1630 $this->data = array();
1633 // 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.
1636 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1638 $file =& $this->file;
1642 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1645 // If the file connection has an error, set SimplePie::error to that and quit
1646 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1648 $this->error = $file->error;
1649 if (!empty($this->data))
1659 if (!$this->force_feed)
1661 // Check if the supplied URL is a feed, if it isn't, look for it.
1662 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1663 if (!$locate->is_feed($file))
1665 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1667 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1671 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1672 if (!$cache->save($this))
1674 trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
1676 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1678 $this->feed_url = $file->url;
1682 $this->error = "A feed could not be found at $this->feed_url";
1683 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1690 $headers = $file->headers;
1691 $data = $file->body;
1692 $sniffer =& new $this->content_type_sniffer_class($file);
1693 $sniffed = $sniffer->get_type();
1697 $data = $this->raw_data;
1700 // Set up array of possible encodings
1701 $encodings = array();
1703 // First check to see if input has been overridden.
1704 if ($this->input_encoding !== false)
1706 $encodings[] = $this->input_encoding;
1709 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1710 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1712 // RFC 3023 (only applies to sniffed content)
1713 if (isset($sniffed))
1715 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1717 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1719 $encodings[] = strtoupper($charset[1]);
1721 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1722 $encodings[] = 'UTF-8';
1724 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1726 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1728 $encodings[] = $charset[1];
1730 $encodings[] = 'US-ASCII';
1732 // Text MIME-type default
1733 elseif (substr($sniffed, 0, 5) === 'text/')
1735 $encodings[] = 'US-ASCII';
1739 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1740 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1741 $encodings[] = 'UTF-8';
1742 $encodings[] = 'ISO-8859-1';
1744 // There's no point in trying an encoding twice
1745 $encodings = array_unique($encodings);
1747 // If we want the XML, just output that with the most likely encoding and quit
1748 if ($this->xml_dump)
1750 header('Content-type: text/xml; charset=' . $encodings[0]);
1755 // Loop through each possible encoding, till we return something, or run out of possibilities
1756 foreach ($encodings as $encoding)
1758 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1759 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1761 // Create new parser
1762 $parser =& new $this->parser_class();
1764 // If it's parsed fine
1765 if ($parser->parse($utf8_data, 'UTF-8'))
1767 $this->data = $parser->get_data();
1768 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1770 if (isset($headers))
1772 $this->data['headers'] = $headers;
1774 $this->data['build'] = SIMPLEPIE_BUILD;
1776 // Cache the file if caching is enabled
1777 if ($cache && !$cache->save($this))
1779 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1785 $this->error = "A feed could not be found at $this->feed_url";
1786 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1794 // We have an error, just set SimplePie_Misc::error to it and quit
1795 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1799 $this->error = 'The data could not be converted to UTF-8';
1801 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1804 elseif (!empty($this->multifeed_url))
1808 $this->multifeed_objects = array();
1809 foreach ($this->multifeed_url as $url)
1813 // This keyword needs to defy coding standards for PHP4 compatibility
1814 $this->multifeed_objects[$i] = clone($this);
1818 $this->multifeed_objects[$i] = $this;
1820 $this->multifeed_objects[$i]->set_feed_url($url);
1821 $success |= $this->multifeed_objects[$i]->init();
1824 return (bool) $success;
1833 * Return the error message for the occured error
1836 * @return string Error message
1840 return $this->error;
1843 function get_encoding()
1845 return $this->sanitize->output_encoding;
1848 function handle_content_type($mime = 'text/html')
1850 if (!headers_sent())
1852 $header = "Content-type: $mime;";
1853 if ($this->get_encoding())
1855 $header .= ' charset=' . $this->get_encoding();
1859 $header .= ' charset=UTF-8';
1867 if (!isset($this->data['type']))
1869 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1870 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1872 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1874 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1876 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1878 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1880 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1881 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1882 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1885 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1887 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1888 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1889 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1892 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1895 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1897 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1898 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1900 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1904 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1906 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1909 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1913 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1920 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1924 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1928 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1932 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1939 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1942 return $this->data['type'];
1946 * Returns the URL for the favicon of the feed's website.
1948 * @todo Cache atom:icon
1952 function get_favicon()
1954 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1956 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1958 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1960 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1962 if ($this->cache && $this->favicon_handler)
1964 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1965 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1969 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1973 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1975 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)
1977 $sniffer =& new $this->content_type_sniffer_class($file);
1978 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1980 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1982 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1986 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1987 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2000 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2007 * @todo If we have a perm redirect we should return the new URL
2008 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2009 * @todo Also, |atom:link|@rel=self
2011 function subscribe_url()
2013 if ($this->feed_url !== null)
2015 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2023 function subscribe_feed()
2025 if ($this->feed_url !== null)
2027 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2035 function subscribe_outlook()
2037 if ($this->feed_url !== null)
2039 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2047 function subscribe_podcast()
2049 if ($this->feed_url !== null)
2051 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2059 function subscribe_itunes()
2061 if ($this->feed_url !== null)
2063 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2072 * Creates the subscribe_* methods' return data
2075 * @param string $feed_url String to prefix to the feed URL
2076 * @param string $site_url String to prefix to the site URL (and
2077 * suffix to the feed URL)
2078 * @return mixed URL if feed exists, false otherwise
2080 function subscribe_service($feed_url, $site_url = null)
2082 if ($this->subscribe_url())
2084 $return = $feed_url . rawurlencode($this->feed_url);
2085 if ($site_url !== null && $this->get_link() !== null)
2087 $return .= $site_url . rawurlencode($this->get_link());
2089 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2097 function subscribe_aol()
2099 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2102 function subscribe_bloglines()
2104 return $this->subscribe_service('http://www.bloglines.com/sub/');
2107 function subscribe_eskobo()
2109 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2112 function subscribe_feedfeeds()
2114 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2117 function subscribe_feedster()
2119 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2122 function subscribe_google()
2124 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2127 function subscribe_gritwire()
2129 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2132 function subscribe_msn()
2134 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2137 function subscribe_netvibes()
2139 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2142 function subscribe_newsburst()
2144 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2147 function subscribe_newsgator()
2149 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2152 function subscribe_odeo()
2154 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2157 function subscribe_podnova()
2159 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2162 function subscribe_rojo()
2164 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2167 function subscribe_yahoo()
2169 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2172 function get_feed_tags($namespace, $tag)
2174 $type = $this->get_type();
2175 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2177 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2179 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2182 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2184 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2186 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2189 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2191 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2193 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2196 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2198 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2200 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2206 function get_channel_tags($namespace, $tag)
2208 $type = $this->get_type();
2209 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2211 if ($return = $this->get_feed_tags($namespace, $tag))
2216 if ($type & SIMPLEPIE_TYPE_RSS_10)
2218 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2220 if (isset($channel[0]['child'][$namespace][$tag]))
2222 return $channel[0]['child'][$namespace][$tag];
2226 if ($type & SIMPLEPIE_TYPE_RSS_090)
2228 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2230 if (isset($channel[0]['child'][$namespace][$tag]))
2232 return $channel[0]['child'][$namespace][$tag];
2236 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2238 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2240 if (isset($channel[0]['child'][$namespace][$tag]))
2242 return $channel[0]['child'][$namespace][$tag];
2249 function get_image_tags($namespace, $tag)
2251 $type = $this->get_type();
2252 if ($type & SIMPLEPIE_TYPE_RSS_10)
2254 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2256 if (isset($image[0]['child'][$namespace][$tag]))
2258 return $image[0]['child'][$namespace][$tag];
2262 if ($type & SIMPLEPIE_TYPE_RSS_090)
2264 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2266 if (isset($image[0]['child'][$namespace][$tag]))
2268 return $image[0]['child'][$namespace][$tag];
2272 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2274 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2276 if (isset($image[0]['child'][$namespace][$tag]))
2278 return $image[0]['child'][$namespace][$tag];
2285 function get_base($element = array())
2287 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2289 return $element['xml_base'];
2291 elseif ($this->get_link() !== null)
2293 return $this->get_link();
2297 return $this->subscribe_url();
2301 function sanitize($data, $type, $base = '')
2303 return $this->sanitize->sanitize($data, $type, $base);
2306 function get_title()
2308 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2310 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2312 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2314 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2316 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2318 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2320 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2322 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2324 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2326 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2328 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2330 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2332 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2334 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2342 function get_category($key = 0)
2344 $categories = $this->get_categories();
2345 if (isset($categories[$key]))
2347 return $categories[$key];
2355 function get_categories()
2357 $categories = array();
2359 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2364 if (isset($category['attribs']['']['term']))
2366 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2368 if (isset($category['attribs']['']['scheme']))
2370 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2372 if (isset($category['attribs']['']['label']))
2374 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2376 $categories[] =& new $this->category_class($term, $scheme, $label);
2378 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2380 // This is really the label, but keep this as the term also for BC.
2381 // Label will also work on retrieving because that falls back to term.
2382 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2383 if (isset($category['attribs']['']['domain']))
2385 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2391 $categories[] =& new $this->category_class($term, $scheme, null);
2393 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2395 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2397 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2399 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2402 if (!empty($categories))
2404 return SimplePie_Misc::array_unique($categories);
2412 function get_author($key = 0)
2414 $authors = $this->get_authors();
2415 if (isset($authors[$key]))
2417 return $authors[$key];
2425 function get_authors()
2428 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2433 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2435 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2437 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2439 $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]));
2441 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2443 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2445 if ($name !== null || $email !== null || $uri !== null)
2447 $authors[] =& new $this->author_class($name, $uri, $email);
2450 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2455 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2457 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2459 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2461 $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]));
2463 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2465 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2467 if ($name !== null || $email !== null || $url !== null)
2469 $authors[] =& new $this->author_class($name, $url, $email);
2472 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2474 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2476 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2478 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2480 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2482 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2485 if (!empty($authors))
2487 return SimplePie_Misc::array_unique($authors);
2495 function get_contributor($key = 0)
2497 $contributors = $this->get_contributors();
2498 if (isset($contributors[$key]))
2500 return $contributors[$key];
2508 function get_contributors()
2510 $contributors = array();
2511 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2516 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2518 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2520 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2522 $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]));
2524 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2526 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2528 if ($name !== null || $email !== null || $uri !== null)
2530 $contributors[] =& new $this->author_class($name, $uri, $email);
2533 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2538 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2540 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2542 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2544 $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]));
2546 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2548 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2550 if ($name !== null || $email !== null || $url !== null)
2552 $contributors[] =& new $this->author_class($name, $url, $email);
2556 if (!empty($contributors))
2558 return SimplePie_Misc::array_unique($contributors);
2566 function get_link($key = 0, $rel = 'alternate')
2568 $links = $this->get_links($rel);
2569 if (isset($links[$key]))
2571 return $links[$key];
2580 * Added for parity between the parent-level and the item/entry-level.
2582 function get_permalink()
2584 return $this->get_link(0);
2587 function get_links($rel = 'alternate')
2589 if (!isset($this->data['links']))
2591 $this->data['links'] = array();
2592 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2594 foreach ($links as $link)
2596 if (isset($link['attribs']['']['href']))
2598 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2599 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2603 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2605 foreach ($links as $link)
2607 if (isset($link['attribs']['']['href']))
2609 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2610 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2615 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2617 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2619 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2621 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2623 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2625 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2628 $keys = array_keys($this->data['links']);
2629 foreach ($keys as $key)
2631 if (SimplePie_Misc::is_isegment_nz_nc($key))
2633 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2635 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2636 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2640 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2643 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2645 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2647 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2651 if (isset($this->data['links'][$rel]))
2653 return $this->data['links'][$rel];
2661 function get_all_discovered_feeds()
2663 return $this->all_discovered_feeds;
2666 function get_description()
2668 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2670 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2672 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2674 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2676 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2678 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2680 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2682 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2684 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2688 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2692 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2696 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2700 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2710 function get_copyright()
2712 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2714 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2716 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2718 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2720 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2722 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2724 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2726 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2728 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2730 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2738 function get_language()
2740 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2742 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2744 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2746 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2748 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2750 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2754 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2756 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2758 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2760 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2762 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2764 elseif (isset($this->data['headers']['content-language']))
2766 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2774 function get_latitude()
2776 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2778 return (float) $return[0]['data'];
2780 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2782 return (float) $match[1];
2790 function get_longitude()
2792 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2794 return (float) $return[0]['data'];
2796 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2798 return (float) $return[0]['data'];
2800 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2802 return (float) $match[2];
2810 function get_image_title()
2812 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2814 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2816 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2818 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2820 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2822 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2824 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2826 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2828 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2830 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2838 function get_image_url()
2840 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2842 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2844 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2846 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2848 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2850 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2852 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2854 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2856 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2858 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2860 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2862 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2870 function get_image_link()
2872 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2874 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2876 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2878 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2880 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2882 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2890 function get_image_width()
2892 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2894 return round($return[0]['data']);
2896 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2906 function get_image_height()
2908 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2910 return round($return[0]['data']);
2912 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2922 function get_item_quantity($max = 0)
2925 $qty = count($this->get_items());
2932 return ($qty > $max) ? $max : $qty;
2936 function get_item($key = 0)
2938 $items = $this->get_items();
2939 if (isset($items[$key]))
2941 return $items[$key];
2949 function get_items($start = 0, $end = 0)
2951 if (!isset($this->data['items']))
2953 if (!empty($this->multifeed_objects))
2955 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2959 $this->data['items'] = array();
2960 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2962 $keys = array_keys($items);
2963 foreach ($keys as $key)
2965 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2968 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2970 $keys = array_keys($items);
2971 foreach ($keys as $key)
2973 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2976 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2978 $keys = array_keys($items);
2979 foreach ($keys as $key)
2981 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2984 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2986 $keys = array_keys($items);
2987 foreach ($keys as $key)
2989 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2992 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2994 $keys = array_keys($items);
2995 foreach ($keys as $key)
2997 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
3003 if (!empty($this->data['items']))
3005 // If we want to order it by date, check if all items have a date, and then sort it
3006 if ($this->order_by_date && empty($this->multifeed_objects))
3008 if (!isset($this->data['ordered_items']))
3011 foreach ($this->data['items'] as $item)
3013 if (!$item->get_date('U'))
3020 $this->data['ordered_items'] = $this->data['items'];
3023 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3026 $items = $this->data['ordered_items'];
3030 $items = $this->data['items'];
3033 // Slice the data as desired
3036 return array_slice($items, $start);
3040 return array_slice($items, $start, $end);
3052 function sort_items($a, $b)
3054 return $a->get_date('U') <= $b->get_date('U');
3060 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3062 if (is_array($urls) && sizeof($urls) > 0)
3065 foreach ($urls as $arg)
3067 if (is_a($arg, 'SimplePie'))
3069 $items = array_merge($items, $arg->get_items(0, $limit));
3073 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3078 foreach ($items as $item)
3080 if (!$item->get_date('U'))
3089 usort($items, array('SimplePie', 'sort_items'));
3094 return array_slice($items, $start);
3098 return array_slice($items, $start, $end);
3103 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3109 class SimplePie_Item
3112 var $data = array();
3114 function SimplePie_Item($feed, $data)
3116 $this->feed = $feed;
3117 $this->data = $data;
3120 function __toString()
3122 return md5(serialize($this->data));
3126 * Remove items that link back to this before destroying this object
3128 function __destruct()
3130 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3136 function get_item_tags($namespace, $tag)
3138 if (isset($this->data['child'][$namespace][$tag]))
3140 return $this->data['child'][$namespace][$tag];
3148 function get_base($element = array())
3150 return $this->feed->get_base($element);
3153 function sanitize($data, $type, $base = '')
3155 return $this->feed->sanitize($data, $type, $base);
3163 function get_id($hash = false)
3167 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3169 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3171 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3173 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3175 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3177 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3179 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3181 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3183 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3185 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3187 elseif (($return = $this->get_permalink()) !== null)
3191 elseif (($return = $this->get_title()) !== null)
3196 if ($this->get_permalink() !== null || $this->get_title() !== null)
3198 return md5($this->get_permalink() . $this->get_title());
3202 return md5(serialize($this->data));
3206 function get_title()
3208 if (!isset($this->data['title']))
3210 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3212 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3214 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3216 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3218 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3220 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3222 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3224 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3226 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3228 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3232 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3236 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3240 $this->data['title'] = null;
3243 return $this->data['title'];
3246 function get_description($description_only = false)
3248 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3250 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3252 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3254 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3256 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3258 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3260 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
3262 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3264 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3266 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3268 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3270 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3272 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3274 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3276 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3278 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3280 elseif (!$description_only)
3282 return $this->get_content(true);
3290 function get_content($content_only = false)
3292 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3294 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3296 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3298 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3300 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3302 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3304 elseif (!$content_only)
3306 return $this->get_description(true);
3314 function get_category($key = 0)
3316 $categories = $this->get_categories();
3317 if (isset($categories[$key]))
3319 return $categories[$key];
3327 function get_categories()
3329 $categories = array();
3331 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3336 if (isset($category['attribs']['']['term']))
3338 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3340 if (isset($category['attribs']['']['scheme']))
3342 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3344 if (isset($category['attribs']['']['label']))
3346 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3348 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3350 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
3352 // This is really the label, but keep this as the term also for BC.
3353 // Label will also work on retrieving because that falls back to term.
3354 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3355 if (isset($category['attribs']['']['domain']))
3357 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
3363 $categories[] =& new $this->feed->category_class($term, $scheme, null);
3365 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3367 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3369 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3371 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3374 if (!empty($categories))
3376 return SimplePie_Misc::array_unique($categories);
3384 function get_author($key = 0)
3386 $authors = $this->get_authors();
3387 if (isset($authors[$key]))
3389 return $authors[$key];
3397 function get_contributor($key = 0)
3399 $contributors = $this->get_contributors();
3400 if (isset($contributors[$key]))
3402 return $contributors[$key];
3410 function get_contributors()
3412 $contributors = array();
3413 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3418 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3420 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3422 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3424 $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]));
3426 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3428 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3430 if ($name !== null || $email !== null || $uri !== null)
3432 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3435 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3440 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3442 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3444 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3446 $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]));
3448 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3450 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3452 if ($name !== null || $email !== null || $url !== null)
3454 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3458 if (!empty($contributors))
3460 return SimplePie_Misc::array_unique($contributors);
3468 function get_authors()
3471 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3476 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3478 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3480 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3482 $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]));
3484 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3486 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3488 if ($name !== null || $email !== null || $uri !== null)
3490 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3493 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3498 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3500 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3502 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3504 $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]));
3506 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3508 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3510 if ($name !== null || $email !== null || $url !== null)
3512 $authors[] =& new $this->feed->author_class($name, $url, $email);
3515 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
3517 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3519 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3521 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3523 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3525 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3527 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3529 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3532 if (!empty($authors))
3534 return SimplePie_Misc::array_unique($authors);
3536 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3540 elseif ($authors = $this->feed->get_authors())
3550 function get_copyright()
3552 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3554 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3556 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3558 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3560 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3562 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3570 function get_date($date_format = 'j F Y, g:i a')
3572 if (!isset($this->data['date']))
3574 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3576 $this->data['date']['raw'] = $return[0]['data'];
3578 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3580 $this->data['date']['raw'] = $return[0]['data'];
3582 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3584 $this->data['date']['raw'] = $return[0]['data'];
3586 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3588 $this->data['date']['raw'] = $return[0]['data'];
3590 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3592 $this->data['date']['raw'] = $return[0]['data'];
3594 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
3596 $this->data['date']['raw'] = $return[0]['data'];
3598 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3600 $this->data['date']['raw'] = $return[0]['data'];
3602 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3604 $this->data['date']['raw'] = $return[0]['data'];
3607 if (!empty($this->data['date']['raw']))
3609 $parser = SimplePie_Parse_Date::get();
3610 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3614 $this->data['date'] = null;
3617 if ($this->data['date'])
3619 $date_format = (string) $date_format;
3620 switch ($date_format)
3623 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3626 return $this->data['date']['parsed'];
3629 return date($date_format, $this->data['date']['parsed']);
3638 function get_local_date($date_format = '%c')
3642 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3644 elseif (($date = $this->get_date('U')) !== null)
3646 return strftime($date_format, $date);
3654 function get_permalink()
3656 $link = $this->get_link();
3657 $enclosure = $this->get_enclosure(0);
3662 elseif ($enclosure !== null)
3664 return $enclosure->get_link();
3672 function get_link($key = 0, $rel = 'alternate')
3674 $links = $this->get_links($rel);
3675 if ($links[$key] !== null)
3677 return $links[$key];
3685 function get_links($rel = 'alternate')
3687 if (!isset($this->data['links']))
3689 $this->data['links'] = array();
3690 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3692 if (isset($link['attribs']['']['href']))
3694 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3695 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3699 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3701 if (isset($link['attribs']['']['href']))
3703 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3704 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3707 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3709 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3711 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3713 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3715 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
3717 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3719 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3721 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
3723 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3727 $keys = array_keys($this->data['links']);
3728 foreach ($keys as $key)
3730 if (SimplePie_Misc::is_isegment_nz_nc($key))
3732 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3734 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3735 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3739 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3742 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3744 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3746 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3749 if (isset($this->data['links'][$rel]))
3751 return $this->data['links'][$rel];
3760 * @todo Add ability to prefer one type of content over another (in a media group).
3762 function get_enclosure($key = 0, $prefer = null)
3764 $enclosures = $this->get_enclosures();
3765 if (isset($enclosures[$key]))
3767 return $enclosures[$key];
3776 * Grabs all available enclosures (podcasts, etc.)
3778 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3780 * 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.
3782 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3783 * @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).
3785 function get_enclosures()
3787 if (!isset($this->data['enclosures']))
3789 $this->data['enclosures'] = array();
3792 $captions_parent = null;
3793 $categories_parent = null;
3794 $copyrights_parent = null;
3795 $credits_parent = null;
3796 $description_parent = null;
3797 $duration_parent = null;
3798 $hashes_parent = null;
3799 $keywords_parent = null;
3800 $player_parent = null;
3801 $ratings_parent = null;
3802 $restrictions_parent = null;
3803 $thumbnails_parent = null;
3804 $title_parent = null;
3806 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3807 $parent = $this->get_feed();
3810 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3812 foreach ($captions as $caption)
3814 $caption_type = null;
3815 $caption_lang = null;
3816 $caption_startTime = null;
3817 $caption_endTime = null;
3818 $caption_text = null;
3819 if (isset($caption['attribs']['']['type']))
3821 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3823 if (isset($caption['attribs']['']['lang']))
3825 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3827 if (isset($caption['attribs']['']['start']))
3829 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3831 if (isset($caption['attribs']['']['end']))
3833 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3835 if (isset($caption['data']))
3837 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3839 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3842 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3844 foreach ($captions as $caption)
3846 $caption_type = null;
3847 $caption_lang = null;
3848 $caption_startTime = null;
3849 $caption_endTime = null;
3850 $caption_text = null;
3851 if (isset($caption['attribs']['']['type']))
3853 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3855 if (isset($caption['attribs']['']['lang']))
3857 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3859 if (isset($caption['attribs']['']['start']))
3861 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3863 if (isset($caption['attribs']['']['end']))
3865 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3867 if (isset($caption['data']))
3869 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3871 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3874 if (is_array($captions_parent))
3876 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3880 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3885 if (isset($category['data']))
3887 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3889 if (isset($category['attribs']['']['scheme']))
3891 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3895 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3897 if (isset($category['attribs']['']['label']))
3899 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3901 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3903 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3908 if (isset($category['data']))
3910 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3912 if (isset($category['attribs']['']['scheme']))
3914 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3918 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3920 if (isset($category['attribs']['']['label']))
3922 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3924 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3926 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3929 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3931 if (isset($category['attribs']['']['text']))
3933 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3935 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3937 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3939 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3941 if (isset($subcategory['attribs']['']['text']))
3943 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3945 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3949 if (is_array($categories_parent))
3951 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3955 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3957 $copyright_url = null;
3958 $copyright_label = null;
3959 if (isset($copyright[0]['attribs']['']['url']))
3961 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3963 if (isset($copyright[0]['data']))
3965 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3967 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3969 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3971 $copyright_url = null;
3972 $copyright_label = null;
3973 if (isset($copyright[0]['attribs']['']['url']))
3975 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3977 if (isset($copyright[0]['data']))
3979 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3981 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3985 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3987 foreach ($credits as $credit)
3989 $credit_role = null;
3990 $credit_scheme = null;
3991 $credit_name = null;
3992 if (isset($credit['attribs']['']['role']))
3994 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3996 if (isset($credit['attribs']['']['scheme']))
3998 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4002 $credit_scheme = 'urn:ebu';
4004 if (isset($credit['data']))
4006 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4008 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4011 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4013 foreach ($credits as $credit)
4015 $credit_role = null;
4016 $credit_scheme = null;
4017 $credit_name = null;
4018 if (isset($credit['attribs']['']['role']))
4020 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4022 if (isset($credit['attribs']['']['scheme']))
4024 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4028 $credit_scheme = 'urn:ebu';
4030 if (isset($credit['data']))
4032 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4034 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4037 if (is_array($credits_parent))
4039 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4043 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4045 if (isset($description_parent[0]['data']))
4047 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4050 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4052 if (isset($description_parent[0]['data']))
4054 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4059 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4064 if (isset($duration_parent[0]['data']))
4066 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4067 if (sizeof($temp) > 0)
4069 (int) $seconds = array_pop($temp);
4071 if (sizeof($temp) > 0)
4073 (int) $minutes = array_pop($temp);
4074 $seconds += $minutes * 60;
4076 if (sizeof($temp) > 0)
4078 (int) $hours = array_pop($temp);
4079 $seconds += $hours * 3600;
4082 $duration_parent = $seconds;
4087 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4089 foreach ($hashes_iterator as $hash)
4093 if (isset($hash['data']))
4095 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4097 if (isset($hash['attribs']['']['algo']))
4099 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4105 $hashes_parent[] = $algo.':'.$value;
4108 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4110 foreach ($hashes_iterator as $hash)
4114 if (isset($hash['data']))
4116 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4118 if (isset($hash['attribs']['']['algo']))
4120 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4126 $hashes_parent[] = $algo.':'.$value;
4129 if (is_array($hashes_parent))
4131 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4135 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4137 if (isset($keywords[0]['data']))
4139 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4140 foreach ($temp as $word)
4142 $keywords_parent[] = trim($word);
4147 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4149 if (isset($keywords[0]['data']))
4151 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4152 foreach ($temp as $word)
4154 $keywords_parent[] = trim($word);
4159 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4161 if (isset($keywords[0]['data']))
4163 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4164 foreach ($temp as $word)
4166 $keywords_parent[] = trim($word);
4171 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4173 if (isset($keywords[0]['data']))
4175 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4176 foreach ($temp as $word)
4178 $keywords_parent[] = trim($word);
4183 if (is_array($keywords_parent))
4185 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4189 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4191 if (isset($player_parent[0]['attribs']['']['url']))
4193 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4196 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4198 if (isset($player_parent[0]['attribs']['']['url']))
4200 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4205 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4207 foreach ($ratings as $rating)
4209 $rating_scheme = null;
4210 $rating_value = null;
4211 if (isset($rating['attribs']['']['scheme']))
4213 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4217 $rating_scheme = 'urn:simple';
4219 if (isset($rating['data']))
4221 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4223 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4226 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4228 foreach ($ratings as $rating)
4230 $rating_scheme = 'urn:itunes';
4231 $rating_value = null;
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 = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4241 foreach ($ratings as $rating)
4243 $rating_scheme = null;
4244 $rating_value = null;
4245 if (isset($rating['attribs']['']['scheme']))
4247 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4251 $rating_scheme = 'urn:simple';
4253 if (isset($rating['data']))
4255 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4257 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4260 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4262 foreach ($ratings as $rating)
4264 $rating_scheme = 'urn:itunes';
4265 $rating_value = null;
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 if (is_array($ratings_parent))
4275 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4279 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4281 foreach ($restrictions as $restriction)
4283 $restriction_relationship = null;
4284 $restriction_type = null;
4285 $restriction_value = null;
4286 if (isset($restriction['attribs']['']['relationship']))
4288 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4290 if (isset($restriction['attribs']['']['type']))
4292 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4294 if (isset($restriction['data']))
4296 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4298 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4301 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4303 foreach ($restrictions as $restriction)
4305 $restriction_relationship = 'allow';
4306 $restriction_type = null;
4307 $restriction_value = 'itunes';
4308 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4310 $restriction_relationship = 'deny';
4312 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4315 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4317 foreach ($restrictions as $restriction)
4319 $restriction_relationship = null;
4320 $restriction_type = null;
4321 $restriction_value = null;
4322 if (isset($restriction['attribs']['']['relationship']))
4324 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4326 if (isset($restriction['attribs']['']['type']))
4328 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4330 if (isset($restriction['data']))
4332 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4334 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4337 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4339 foreach ($restrictions as $restriction)
4341 $restriction_relationship = 'allow';
4342 $restriction_type = null;
4343 $restriction_value = 'itunes';
4344 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4346 $restriction_relationship = 'deny';
4348 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4351 if (is_array($restrictions_parent))
4353 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4357 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4359 foreach ($thumbnails as $thumbnail)
4361 if (isset($thumbnail['attribs']['']['url']))
4363 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4367 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4369 foreach ($thumbnails as $thumbnail)
4371 if (isset($thumbnail['attribs']['']['url']))
4373 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4379 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4381 if (isset($title_parent[0]['data']))
4383 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4386 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4388 if (isset($title_parent[0]['data']))
4390 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4408 $samplingrate = null;
4418 $description = null;
4423 $restrictions = null;
4427 // If we have media:group tags, loop through them.
4428 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4430 // If we have media:content tags, loop through them.
4431 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4433 if (isset($content['attribs']['']['url']))
4446 $samplingrate = null;
4456 $description = null;
4461 $restrictions = null;
4465 // Start checking the attributes of media:content
4466 if (isset($content['attribs']['']['bitrate']))
4468 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4470 if (isset($content['attribs']['']['channels']))
4472 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4474 if (isset($content['attribs']['']['duration']))
4476 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4480 $duration = $duration_parent;
4482 if (isset($content['attribs']['']['expression']))
4484 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4486 if (isset($content['attribs']['']['framerate']))
4488 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4490 if (isset($content['attribs']['']['height']))
4492 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4494 if (isset($content['attribs']['']['lang']))
4496 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4498 if (isset($content['attribs']['']['fileSize']))
4500 $length = ceil($content['attribs']['']['fileSize']);
4502 if (isset($content['attribs']['']['medium']))
4504 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4506 if (isset($content['attribs']['']['samplingrate']))
4508 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4510 if (isset($content['attribs']['']['type']))
4512 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4514 if (isset($content['attribs']['']['width']))
4516 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4518 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4520 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4523 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4525 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4527 $caption_type = null;
4528 $caption_lang = null;
4529 $caption_startTime = null;
4530 $caption_endTime = null;
4531 $caption_text = null;
4532 if (isset($caption['attribs']['']['type']))
4534 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4536 if (isset($caption['attribs']['']['lang']))
4538 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4540 if (isset($caption['attribs']['']['start']))
4542 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4544 if (isset($caption['attribs']['']['end']))
4546 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4548 if (isset($caption['data']))
4550 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4552 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4554 if (is_array($captions))
4556 $captions = array_values(SimplePie_Misc::array_unique($captions));
4559 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4561 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4563 $caption_type = null;
4564 $caption_lang = null;
4565 $caption_startTime = null;
4566 $caption_endTime = null;
4567 $caption_text = null;
4568 if (isset($caption['attribs']['']['type']))
4570 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4572 if (isset($caption['attribs']['']['lang']))
4574 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4576 if (isset($caption['attribs']['']['start']))
4578 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4580 if (isset($caption['attribs']['']['end']))
4582 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4584 if (isset($caption['data']))
4586 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4588 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4590 if (is_array($captions))
4592 $captions = array_values(SimplePie_Misc::array_unique($captions));
4597 $captions = $captions_parent;
4601 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4603 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4608 if (isset($category['data']))
4610 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4612 if (isset($category['attribs']['']['scheme']))
4614 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4618 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4620 if (isset($category['attribs']['']['label']))
4622 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4624 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4627 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4629 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4634 if (isset($category['data']))
4636 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4638 if (isset($category['attribs']['']['scheme']))
4640 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4644 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4646 if (isset($category['attribs']['']['label']))
4648 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4650 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4653 if (is_array($categories) && is_array($categories_parent))
4655 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4657 elseif (is_array($categories))
4659 $categories = array_values(SimplePie_Misc::array_unique($categories));
4661 elseif (is_array($categories_parent))
4663 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4667 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4669 $copyright_url = null;
4670 $copyright_label = null;
4671 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4673 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4675 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4677 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4679 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4681 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4683 $copyright_url = null;
4684 $copyright_label = null;
4685 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4687 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4689 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4691 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4693 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4697 $copyrights = $copyrights_parent;
4701 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4703 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4705 $credit_role = null;
4706 $credit_scheme = null;
4707 $credit_name = null;
4708 if (isset($credit['attribs']['']['role']))
4710 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4712 if (isset($credit['attribs']['']['scheme']))
4714 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4718 $credit_scheme = 'urn:ebu';
4720 if (isset($credit['data']))
4722 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4724 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4726 if (is_array($credits))
4728 $credits = array_values(SimplePie_Misc::array_unique($credits));
4731 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4733 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4735 $credit_role = null;
4736 $credit_scheme = null;
4737 $credit_name = null;
4738 if (isset($credit['attribs']['']['role']))
4740 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4742 if (isset($credit['attribs']['']['scheme']))
4744 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4748 $credit_scheme = 'urn:ebu';
4750 if (isset($credit['data']))
4752 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4754 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4756 if (is_array($credits))
4758 $credits = array_values(SimplePie_Misc::array_unique($credits));
4763 $credits = $credits_parent;
4767 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4769 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4771 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4773 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4777 $description = $description_parent;
4781 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4783 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4787 if (isset($hash['data']))
4789 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4791 if (isset($hash['attribs']['']['algo']))
4793 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4799 $hashes[] = $algo.':'.$value;
4801 if (is_array($hashes))
4803 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4806 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4808 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4812 if (isset($hash['data']))
4814 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4816 if (isset($hash['attribs']['']['algo']))
4818 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4824 $hashes[] = $algo.':'.$value;
4826 if (is_array($hashes))
4828 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4833 $hashes = $hashes_parent;
4837 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4839 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4841 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4842 foreach ($temp as $word)
4844 $keywords[] = trim($word);
4848 if (is_array($keywords))
4850 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4853 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4855 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4857 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4858 foreach ($temp as $word)
4860 $keywords[] = trim($word);
4864 if (is_array($keywords))
4866 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4871 $keywords = $keywords_parent;
4875 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4877 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4879 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4881 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4885 $player = $player_parent;
4889 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4891 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4893 $rating_scheme = null;
4894 $rating_value = null;
4895 if (isset($rating['attribs']['']['scheme']))
4897 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4901 $rating_scheme = 'urn:simple';
4903 if (isset($rating['data']))
4905 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4907 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4909 if (is_array($ratings))
4911 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4914 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4916 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4918 $rating_scheme = null;
4919 $rating_value = null;
4920 if (isset($rating['attribs']['']['scheme']))
4922 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4926 $rating_scheme = 'urn:simple';
4928 if (isset($rating['data']))
4930 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4932 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4934 if (is_array($ratings))
4936 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4941 $ratings = $ratings_parent;
4945 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4947 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4949 $restriction_relationship = null;
4950 $restriction_type = null;
4951 $restriction_value = null;
4952 if (isset($restriction['attribs']['']['relationship']))
4954 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4956 if (isset($restriction['attribs']['']['type']))
4958 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4960 if (isset($restriction['data']))
4962 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4964 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4966 if (is_array($restrictions))
4968 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4971 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4973 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4975 $restriction_relationship = null;
4976 $restriction_type = null;
4977 $restriction_value = null;
4978 if (isset($restriction['attribs']['']['relationship']))
4980 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4982 if (isset($restriction['attribs']['']['type']))
4984 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4986 if (isset($restriction['data']))
4988 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4990 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4992 if (is_array($restrictions))
4994 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4999 $restrictions = $restrictions_parent;
5003 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5005 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5007 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5009 if (is_array($thumbnails))
5011 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5014 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5016 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5018 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5020 if (is_array($thumbnails))
5022 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5027 $thumbnails = $thumbnails_parent;
5031 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5033 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5035 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5037 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5041 $title = $title_parent;
5044 $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);
5049 // If we have standalone media:content tags, loop through them.
5050 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5052 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5054 if (isset($content['attribs']['']['url']))
5067 $samplingrate = null;
5077 $description = null;
5082 $restrictions = null;
5086 // Start checking the attributes of media:content
5087 if (isset($content['attribs']['']['bitrate']))
5089 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5091 if (isset($content['attribs']['']['channels']))
5093 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5095 if (isset($content['attribs']['']['duration']))
5097 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5101 $duration = $duration_parent;
5103 if (isset($content['attribs']['']['expression']))
5105 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5107 if (isset($content['attribs']['']['framerate']))
5109 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5111 if (isset($content['attribs']['']['height']))
5113 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5115 if (isset($content['attribs']['']['lang']))
5117 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5119 if (isset($content['attribs']['']['fileSize']))
5121 $length = ceil($content['attribs']['']['fileSize']);
5123 if (isset($content['attribs']['']['medium']))
5125 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5127 if (isset($content['attribs']['']['samplingrate']))
5129 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5131 if (isset($content['attribs']['']['type']))
5133 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5135 if (isset($content['attribs']['']['width']))
5137 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5139 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5141 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5144 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5146 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5148 $caption_type = null;
5149 $caption_lang = null;
5150 $caption_startTime = null;
5151 $caption_endTime = null;
5152 $caption_text = null;
5153 if (isset($caption['attribs']['']['type']))
5155 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5157 if (isset($caption['attribs']['']['lang']))
5159 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5161 if (isset($caption['attribs']['']['start']))
5163 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5165 if (isset($caption['attribs']['']['end']))
5167 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5169 if (isset($caption['data']))
5171 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5173 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5175 if (is_array($captions))
5177 $captions = array_values(SimplePie_Misc::array_unique($captions));
5182 $captions = $captions_parent;
5186 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5188 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5193 if (isset($category['data']))
5195 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5197 if (isset($category['attribs']['']['scheme']))
5199 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5203 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5205 if (isset($category['attribs']['']['label']))
5207 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5209 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5212 if (is_array($categories) && is_array($categories_parent))
5214 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5216 elseif (is_array($categories))
5218 $categories = array_values(SimplePie_Misc::array_unique($categories));
5220 elseif (is_array($categories_parent))
5222 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5230 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5232 $copyright_url = null;
5233 $copyright_label = null;
5234 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5236 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5238 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5240 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5242 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5246 $copyrights = $copyrights_parent;
5250 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5252 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5254 $credit_role = null;
5255 $credit_scheme = null;
5256 $credit_name = null;
5257 if (isset($credit['attribs']['']['role']))
5259 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5261 if (isset($credit['attribs']['']['scheme']))
5263 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5267 $credit_scheme = 'urn:ebu';
5269 if (isset($credit['data']))
5271 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5273 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5275 if (is_array($credits))
5277 $credits = array_values(SimplePie_Misc::array_unique($credits));
5282 $credits = $credits_parent;
5286 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5288 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5292 $description = $description_parent;
5296 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5298 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5302 if (isset($hash['data']))
5304 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5306 if (isset($hash['attribs']['']['algo']))
5308 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5314 $hashes[] = $algo.':'.$value;
5316 if (is_array($hashes))
5318 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5323 $hashes = $hashes_parent;
5327 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5329 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5331 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5332 foreach ($temp as $word)
5334 $keywords[] = trim($word);
5338 if (is_array($keywords))
5340 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5345 $keywords = $keywords_parent;
5349 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5351 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5355 $player = $player_parent;
5359 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5361 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5363 $rating_scheme = null;
5364 $rating_value = null;
5365 if (isset($rating['attribs']['']['scheme']))
5367 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5371 $rating_scheme = 'urn:simple';
5373 if (isset($rating['data']))
5375 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5377 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5379 if (is_array($ratings))
5381 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5386 $ratings = $ratings_parent;
5390 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5392 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5394 $restriction_relationship = null;
5395 $restriction_type = null;
5396 $restriction_value = null;
5397 if (isset($restriction['attribs']['']['relationship']))
5399 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5401 if (isset($restriction['attribs']['']['type']))
5403 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5405 if (isset($restriction['data']))
5407 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5409 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5411 if (is_array($restrictions))
5413 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5418 $restrictions = $restrictions_parent;
5422 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5424 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5426 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5428 if (is_array($thumbnails))
5430 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5435 $thumbnails = $thumbnails_parent;
5439 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5441 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5445 $title = $title_parent;
5448 $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);
5453 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5455 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5468 $samplingrate = null;
5473 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5474 if (isset($link['attribs']['']['type']))
5476 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5478 if (isset($link['attribs']['']['length']))
5480 $length = ceil($link['attribs']['']['length']);
5483 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5484 $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);
5488 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5490 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5503 $samplingrate = null;
5508 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5509 if (isset($link['attribs']['']['type']))
5511 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5513 if (isset($link['attribs']['']['length']))
5515 $length = ceil($link['attribs']['']['length']);
5518 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5519 $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);
5523 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
5525 if (isset($enclosure[0]['attribs']['']['url']))
5538 $samplingrate = null;
5543 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5544 if (isset($enclosure[0]['attribs']['']['type']))
5546 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5548 if (isset($enclosure[0]['attribs']['']['length']))
5550 $length = ceil($enclosure[0]['attribs']['']['length']);
5553 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5554 $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);
5558 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))
5560 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5561 $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);
5564 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5566 if (!empty($this->data['enclosures']))
5568 return $this->data['enclosures'];
5576 function get_latitude()
5578 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5580 return (float) $return[0]['data'];
5582 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5584 return (float) $match[1];
5592 function get_longitude()
5594 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5596 return (float) $return[0]['data'];
5598 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5600 return (float) $return[0]['data'];
5602 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5604 return (float) $match[2];
5612 function get_source()
5614 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5616 return new $this->feed->source_class($this, $return[0]);
5625 * Creates the add_to_* methods' return data
5628 * @param string $item_url String to prefix to the item permalink
5629 * @param string $title_url String to prefix to the item title
5630 * (and suffix to the item permalink)
5631 * @return mixed URL if feed exists, false otherwise
5633 function add_to_service($item_url, $title_url = null, $summary_url = null)
5635 if ($this->get_permalink() !== null)
5637 $return = $item_url . rawurlencode($this->get_permalink());
5638 if ($title_url !== null && $this->get_title() !== null)
5640 $return .= $title_url . rawurlencode($this->get_title());
5642 if ($summary_url !== null && $this->get_description() !== null)
5644 $return .= $summary_url . rawurlencode($this->get_description());
5646 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
5654 function add_to_blinklist()
5656 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5659 function add_to_blogmarks()
5661 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5664 function add_to_delicious()
5666 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5669 function add_to_digg()
5671 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5674 function add_to_furl()
5676 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5679 function add_to_magnolia()
5681 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5684 function add_to_myweb20()
5686 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5689 function add_to_newsvine()
5691 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5694 function add_to_reddit()
5696 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5699 function add_to_segnalo()
5701 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5704 function add_to_simpy()
5706 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5709 function add_to_spurl()
5711 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5714 function add_to_wists()
5716 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5719 function search_technorati()
5721 return $this->add_to_service('http://www.technorati.com/search/');
5725 class SimplePie_Source
5728 var $data = array();
5730 function SimplePie_Source($item, $data)
5732 $this->item = $item;
5733 $this->data = $data;
5736 function __toString()
5738 return md5(serialize($this->data));
5741 function get_source_tags($namespace, $tag)
5743 if (isset($this->data['child'][$namespace][$tag]))
5745 return $this->data['child'][$namespace][$tag];
5753 function get_base($element = array())
5755 return $this->item->get_base($element);
5758 function sanitize($data, $type, $base = '')
5760 return $this->item->sanitize($data, $type, $base);
5768 function get_title()
5770 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5772 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5774 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5776 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5778 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5780 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5782 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5786 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
5788 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5790 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5792 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5794 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5796 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5804 function get_category($key = 0)
5806 $categories = $this->get_categories();
5807 if (isset($categories[$key]))
5809 return $categories[$key];
5817 function get_categories()
5819 $categories = array();
5821 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5826 if (isset($category['attribs']['']['term']))
5828 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5830 if (isset($category['attribs']['']['scheme']))
5832 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5834 if (isset($category['attribs']['']['label']))
5836 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5838 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5840 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
5842 // This is really the label, but keep this as the term also for BC.
5843 // Label will also work on retrieving because that falls back to term.
5844 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5845 if (isset($category['attribs']['']['domain']))
5847 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
5853 $categories[] =& new $this->item->feed->category_class($term, $scheme, null);
5855 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5857 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5859 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5861 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5864 if (!empty($categories))
5866 return SimplePie_Misc::array_unique($categories);
5874 function get_author($key = 0)
5876 $authors = $this->get_authors();
5877 if (isset($authors[$key]))
5879 return $authors[$key];
5887 function get_authors()
5890 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5895 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5897 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5899 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5901 $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]));
5903 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5905 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5907 if ($name !== null || $email !== null || $uri !== null)
5909 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5912 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5917 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5919 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5921 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5923 $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]));
5925 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5927 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5929 if ($name !== null || $email !== null || $url !== null)
5931 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5934 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5936 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5938 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5940 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5942 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5944 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5947 if (!empty($authors))
5949 return SimplePie_Misc::array_unique($authors);
5957 function get_contributor($key = 0)
5959 $contributors = $this->get_contributors();
5960 if (isset($contributors[$key]))
5962 return $contributors[$key];
5970 function get_contributors()
5972 $contributors = array();
5973 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5978 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5980 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5982 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5984 $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]));
5986 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5988 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5990 if ($name !== null || $email !== null || $uri !== null)
5992 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5995 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
6000 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
6002 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6004 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
6006 $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]));
6008 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
6010 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6012 if ($name !== null || $email !== null || $url !== null)
6014 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
6018 if (!empty($contributors))
6020 return SimplePie_Misc::array_unique($contributors);
6028 function get_link($key = 0, $rel = 'alternate')
6030 $links = $this->get_links($rel);
6031 if (isset($links[$key]))
6033 return $links[$key];
6042 * Added for parity between the parent-level and the item/entry-level.
6044 function get_permalink()
6046 return $this->get_link(0);
6049 function get_links($rel = 'alternate')
6051 if (!isset($this->data['links']))
6053 $this->data['links'] = array();
6054 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6056 foreach ($links as $link)
6058 if (isset($link['attribs']['']['href']))
6060 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6061 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6065 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6067 foreach ($links as $link)
6069 if (isset($link['attribs']['']['href']))
6071 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6072 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6077 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6079 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6081 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6083 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6085 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
6087 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6090 $keys = array_keys($this->data['links']);
6091 foreach ($keys as $key)
6093 if (SimplePie_Misc::is_isegment_nz_nc($key))
6095 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6097 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6098 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6102 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6105 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6107 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6109 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6113 if (isset($this->data['links'][$rel]))
6115 return $this->data['links'][$rel];
6123 function get_description()
6125 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6127 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6129 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6131 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6133 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6135 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6137 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6139 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6141 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
6143 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6145 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6147 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6149 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6151 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6153 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6155 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6157 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6159 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6167 function get_copyright()
6169 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6171 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6173 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6175 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6177 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
6179 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6181 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6183 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6185 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6187 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6195 function get_language()
6197 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
6199 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6201 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6203 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6205 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6207 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6209 elseif (isset($this->data['xml_lang']))
6211 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6219 function get_latitude()
6221 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6223 return (float) $return[0]['data'];
6225 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6227 return (float) $match[1];
6235 function get_longitude()
6237 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6239 return (float) $return[0]['data'];
6241 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6243 return (float) $return[0]['data'];
6245 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6247 return (float) $match[2];
6255 function get_image_url()
6257 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6259 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6261 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6263 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6265 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6267 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6276 class SimplePie_Author
6282 // Constructor, used to input the data
6283 function SimplePie_Author($name = null, $link = null, $email = null)
6285 $this->name = $name;
6286 $this->link = $link;
6287 $this->email = $email;
6290 function __toString()
6292 // There is no $this->data here
6293 return md5(serialize($this));
6298 if ($this->name !== null)
6310 if ($this->link !== null)
6320 function get_email()
6322 if ($this->email !== null)
6324 return $this->email;
6333 class SimplePie_Category
6339 // Constructor, used to input the data
6340 function SimplePie_Category($term = null, $scheme = null, $label = null)
6342 $this->term = $term;
6343 $this->scheme = $scheme;
6344 $this->label = $label;
6347 function __toString()
6349 // There is no $this->data here
6350 return md5(serialize($this));
6355 if ($this->term !== null)
6365 function get_scheme()
6367 if ($this->scheme !== null)
6369 return $this->scheme;
6377 function get_label()
6379 if ($this->label !== null)
6381 return $this->label;
6385 return $this->get_term();
6390 class SimplePie_Enclosure
6420 // Constructor, used to input the data
6421 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)
6423 $this->bitrate = $bitrate;
6424 $this->captions = $captions;
6425 $this->categories = $categories;
6426 $this->channels = $channels;
6427 $this->copyright = $copyright;
6428 $this->credits = $credits;
6429 $this->description = $description;
6430 $this->duration = $duration;
6431 $this->expression = $expression;
6432 $this->framerate = $framerate;
6433 $this->hashes = $hashes;
6434 $this->height = $height;
6435 $this->javascript = $javascript;
6436 $this->keywords = $keywords;
6437 $this->lang = $lang;
6438 $this->length = $length;
6439 $this->link = $link;
6440 $this->medium = $medium;
6441 $this->player = $player;
6442 $this->ratings = $ratings;
6443 $this->restrictions = $restrictions;
6444 $this->samplingrate = $samplingrate;
6445 $this->thumbnails = $thumbnails;
6446 $this->title = $title;
6447 $this->type = $type;
6448 $this->width = $width;
6449 if (class_exists('idna_convert'))
6451 $idn =& new idna_convert;
6452 $parsed = SimplePie_Misc::parse_url($link);
6453 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6455 $this->handler = $this->get_handler(); // Needs to load last
6458 function __toString()
6460 // There is no $this->data here
6461 return md5(serialize($this));
6464 function get_bitrate()
6466 if ($this->bitrate !== null)
6468 return $this->bitrate;
6476 function get_caption($key = 0)
6478 $captions = $this->get_captions();
6479 if (isset($captions[$key]))
6481 return $captions[$key];
6489 function get_captions()
6491 if ($this->captions !== null)
6493 return $this->captions;
6501 function get_category($key = 0)
6503 $categories = $this->get_categories();
6504 if (isset($categories[$key]))
6506 return $categories[$key];
6514 function get_categories()
6516 if ($this->categories !== null)
6518 return $this->categories;
6526 function get_channels()
6528 if ($this->channels !== null)
6530 return $this->channels;
6538 function get_copyright()
6540 if ($this->copyright !== null)
6542 return $this->copyright;
6550 function get_credit($key = 0)
6552 $credits = $this->get_credits();
6553 if (isset($credits[$key]))
6555 return $credits[$key];
6563 function get_credits()
6565 if ($this->credits !== null)
6567 return $this->credits;
6575 function get_description()
6577 if ($this->description !== null)
6579 return $this->description;
6587 function get_duration($convert = false)
6589 if ($this->duration !== null)
6593 $time = SimplePie_Misc::time_hms($this->duration);
6598 return $this->duration;
6607 function get_expression()
6609 if ($this->expression !== null)
6611 return $this->expression;
6619 function get_extension()
6621 if ($this->link !== null)
6623 $url = SimplePie_Misc::parse_url($this->link);
6624 if ($url['path'] !== '')
6626 return pathinfo($url['path'], PATHINFO_EXTENSION);
6632 function get_framerate()
6634 if ($this->framerate !== null)
6636 return $this->framerate;
6644 function get_handler()
6646 return $this->get_real_type(true);
6649 function get_hash($key = 0)
6651 $hashes = $this->get_hashes();
6652 if (isset($hashes[$key]))
6654 return $hashes[$key];
6662 function get_hashes()
6664 if ($this->hashes !== null)
6666 return $this->hashes;
6674 function get_height()
6676 if ($this->height !== null)
6678 return $this->height;
6686 function get_language()
6688 if ($this->lang !== null)
6698 function get_keyword($key = 0)
6700 $keywords = $this->get_keywords();
6701 if (isset($keywords[$key]))
6703 return $keywords[$key];
6711 function get_keywords()
6713 if ($this->keywords !== null)
6715 return $this->keywords;
6723 function get_length()
6725 if ($this->length !== null)
6727 return $this->length;
6737 if ($this->link !== null)
6739 return urldecode($this->link);
6747 function get_medium()
6749 if ($this->medium !== null)
6751 return $this->medium;
6759 function get_player()
6761 if ($this->player !== null)
6763 return $this->player;
6771 function get_rating($key = 0)
6773 $ratings = $this->get_ratings();
6774 if (isset($ratings[$key]))
6776 return $ratings[$key];
6784 function get_ratings()
6786 if ($this->ratings !== null)
6788 return $this->ratings;
6796 function get_restriction($key = 0)
6798 $restrictions = $this->get_restrictions();
6799 if (isset($restrictions[$key]))
6801 return $restrictions[$key];
6809 function get_restrictions()
6811 if ($this->restrictions !== null)
6813 return $this->restrictions;
6821 function get_sampling_rate()
6823 if ($this->samplingrate !== null)
6825 return $this->samplingrate;
6835 $length = $this->get_length();
6836 if ($length !== null)
6838 return round($length/1048576, 2);
6846 function get_thumbnail($key = 0)
6848 $thumbnails = $this->get_thumbnails();
6849 if (isset($thumbnails[$key]))
6851 return $thumbnails[$key];
6859 function get_thumbnails()
6861 if ($this->thumbnails !== null)
6863 return $this->thumbnails;
6871 function get_title()
6873 if ($this->title !== null)
6875 return $this->title;
6885 if ($this->type !== null)
6895 function get_width()
6897 if ($this->width !== null)
6899 return $this->width;
6907 function native_embed($options='')
6909 return $this->embed($options, true);
6913 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6915 function embed($options = '', $native = false)
6925 $bgcolor = '#ffffff';
6927 $widescreen = false;
6928 $handler = $this->get_handler();
6929 $type = $this->get_real_type();
6931 // Process options and reassign values as necessary
6932 if (is_array($options))
6938 $options = explode(',', $options);
6939 foreach($options as $option)
6941 $opt = explode(':', $option, 2);
6942 if (isset($opt[0], $opt[1]))
6944 $opt[0] = trim($opt[0]);
6945 $opt[1] = trim($opt[1]);
6961 $altclass = $opt[1];
6981 $mediaplayer = $opt[1];
6985 $widescreen = $opt[1];
6992 $mime = explode('/', $type, 2);
6995 // Process values for 'auto'
6996 if ($width === 'auto')
6998 if ($mime === 'video')
7000 if ($height === 'auto')
7004 elseif ($widescreen)
7006 $width = round((intval($height)/9)*16);
7010 $width = round((intval($height)/3)*4);
7019 if ($height === 'auto')
7021 if ($mime === 'audio')
7025 elseif ($mime === 'video')
7027 if ($width === 'auto')
7038 elseif ($widescreen)
7040 $height = round((intval($width)/16)*9);
7044 $height = round((intval($width)/4)*3);
7052 elseif ($mime === 'audio')
7057 // Set proper placeholder value
7058 if ($mime === 'audio')
7060 $placeholder = $audio;
7062 elseif ($mime === 'video')
7064 $placeholder = $video;
7069 // Make sure the JS library is included
7072 static $javascript_outputted = null;
7073 if (!$javascript_outputted && $this->javascript)
7075 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7076 $javascript_outputted = true;
7081 if ($handler === 'odeo')
7085 $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>';
7089 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7094 elseif ($handler === 'flash')
7098 $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>";
7102 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7106 // Flash Media Player file types.
7107 // Preferred handler for MP3 file types.
7108 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
7113 $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>";
7117 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7121 // QuickTime 7 file types. Need to test with QuickTime 6.
7122 // Only handle MP3's if the Flash Media Player is not present.
7123 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
7128 if ($placeholder !== '')
7130 $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>";
7134 $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>";
7139 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7144 elseif ($handler === 'wmedia')
7149 $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>";
7153 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7158 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7163 function get_real_type($find_handler = false)
7165 // If it's Odeo, let's get it out of the way.
7166 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
7171 // Mime-types by handler.
7172 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7173 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7174 $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
7175 $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
7176 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7178 if ($this->get_type() !== null)
7180 $type = strtolower($this->type);
7187 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7188 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7190 switch (strtolower($this->get_extension()))
7195 $type = 'audio/acc';
7202 $type = 'audio/aiff';
7206 $type = 'audio/wav';
7213 $type = 'audio/midi';
7217 $type = 'audio/x-m4a';
7222 $type = 'audio/mp3';
7226 $type = 'audio/wav';
7230 $type = 'audio/x-ms-wax';
7234 $type = 'audio/x-ms-wma';
7240 $type = 'video/3gpp';
7245 $type = 'video/3gpp2';
7249 $type = 'video/x-ms-asf';
7253 $type = 'video/x-flv';
7267 $type = 'video/mpeg';
7271 $type = 'video/x-m4v';
7276 $type = 'video/quicktime';
7281 $type = 'video/mp4';
7285 $type = 'video/sd-video';
7289 $type = 'video/x-ms-wm';
7293 $type = 'video/x-ms-wmv';
7297 $type = 'video/x-ms-wvx';
7302 $type = 'application/futuresplash';
7306 $type = 'application/x-shockwave-flash';
7313 if (in_array($type, $types_flash))
7317 elseif (in_array($type, $types_fmedia))
7321 elseif (in_array($type, $types_quicktime))
7325 elseif (in_array($type, $types_wmedia))
7329 elseif (in_array($type, $types_mp3))
7345 class SimplePie_Caption
7353 // Constructor, used to input the data
7354 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7356 $this->type = $type;
7357 $this->lang = $lang;
7358 $this->startTime = $startTime;
7359 $this->endTime = $endTime;
7360 $this->text = $text;
7363 function __toString()
7365 // There is no $this->data here
7366 return md5(serialize($this));
7369 function get_endtime()
7371 if ($this->endTime !== null)
7373 return $this->endTime;
7381 function get_language()
7383 if ($this->lang !== null)
7393 function get_starttime()
7395 if ($this->startTime !== null)
7397 return $this->startTime;
7407 if ($this->text !== null)
7419 if ($this->type !== null)
7430 class SimplePie_Credit
7436 // Constructor, used to input the data
7437 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7439 $this->role = $role;
7440 $this->scheme = $scheme;
7441 $this->name = $name;
7444 function __toString()
7446 // There is no $this->data here
7447 return md5(serialize($this));
7452 if ($this->role !== null)
7462 function get_scheme()
7464 if ($this->scheme !== null)
7466 return $this->scheme;
7476 if ($this->name !== null)
7487 class SimplePie_Copyright
7492 // Constructor, used to input the data
7493 function SimplePie_Copyright($url = null, $label = null)
7496 $this->label = $label;
7499 function __toString()
7501 // There is no $this->data here
7502 return md5(serialize($this));
7507 if ($this->url !== null)
7517 function get_attribution()
7519 if ($this->label !== null)
7521 return $this->label;
7530 class SimplePie_Rating
7535 // Constructor, used to input the data
7536 function SimplePie_Rating($scheme = null, $value = null)
7538 $this->scheme = $scheme;
7539 $this->value = $value;
7542 function __toString()
7544 // There is no $this->data here
7545 return md5(serialize($this));
7548 function get_scheme()
7550 if ($this->scheme !== null)
7552 return $this->scheme;
7560 function get_value()
7562 if ($this->value !== null)
7564 return $this->value;
7573 class SimplePie_Restriction
7579 // Constructor, used to input the data
7580 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7582 $this->relationship = $relationship;
7583 $this->type = $type;
7584 $this->value = $value;
7587 function __toString()
7589 // There is no $this->data here
7590 return md5(serialize($this));
7593 function get_relationship()
7595 if ($this->relationship !== null)
7597 return $this->relationship;
7607 if ($this->type !== null)
7617 function get_value()
7619 if ($this->value !== null)
7621 return $this->value;
7631 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7633 class SimplePie_File
7637 var $success = true;
7638 var $headers = array();
7643 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7645 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7647 if (class_exists('idna_convert'))
7649 $idn =& new idna_convert;
7650 $parsed = SimplePie_Misc::parse_url($url);
7651 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7654 $this->useragent = $useragent;
7655 if (preg_match('/^http(s)?:\/\//i', $url))
7657 if ($useragent === null)
7659 $useragent = ini_get('user_agent');
7660 $this->useragent = $useragent;
7662 if (!is_array($headers))
7666 if (!$force_fsockopen && function_exists('curl_exec'))
7668 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7670 $headers2 = array();
7671 foreach ($headers as $key => $value)
7673 $headers2[] = "$key: $value";
7675 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7677 curl_setopt($fp, CURLOPT_ENCODING, '');
7679 curl_setopt($fp, CURLOPT_URL, $url);
7680 curl_setopt($fp, CURLOPT_HEADER, 1);
7681 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7682 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7683 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7684 curl_setopt($fp, CURLOPT_REFERER, $url);
7685 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7686 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7687 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7689 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7690 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7693 /* Enable Digest authentication and SSL -fox */
7694 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
7695 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
7697 $this->headers = curl_exec($fp);
7698 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
7700 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7701 $this->headers = curl_exec($fp);
7703 if (curl_errno($fp))
7705 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7706 $this->success = false;
7710 $info = curl_getinfo($fp);
7712 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7713 $this->headers = array_pop($this->headers);
7714 $parser =& new SimplePie_HTTP_Parser($this->headers);
7715 if ($parser->parse())
7717 $this->headers = $parser->headers;
7718 $this->body = $parser->body;
7719 $this->status_code = $parser->status_code;
7720 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)
7723 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7724 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7731 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7732 $url_parts = parse_url($url);
7733 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
7735 $url_parts['host'] = "ssl://$url_parts[host]";
7736 $url_parts['port'] = 443;
7738 if (!isset($url_parts['port']))
7740 $url_parts['port'] = 80;
7742 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7745 $this->error = 'fsockopen error: ' . $errstr;
7746 $this->success = false;
7750 stream_set_timeout($fp, $timeout);
7751 if (isset($url_parts['path']))
7753 if (isset($url_parts['query']))
7755 $get = "$url_parts[path]?$url_parts[query]";
7759 $get = $url_parts['path'];
7766 $out = "GET $get HTTP/1.0\r\n";
7767 $out .= "Host: $url_parts[host]\r\n";
7768 $out .= "User-Agent: $useragent\r\n";
7769 if (extension_loaded('zlib'))
7771 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7774 if (isset($url_parts['user']) && isset($url_parts['pass']))
7776 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7778 foreach ($headers as $key => $value)
7780 $out .= "$key: $value\r\n";
7782 $out .= "Connection: Close\r\n\r\n";
7785 $info = stream_get_meta_data($fp);
7787 $this->headers = '';
7788 while (!$info['eof'] && !$info['timed_out'])
7790 $this->headers .= fread($fp, 1160);
7791 $info = stream_get_meta_data($fp);
7793 if (!$info['timed_out'])
7795 $parser =& new SimplePie_HTTP_Parser($this->headers);
7796 if ($parser->parse())
7798 $this->headers = $parser->headers;
7799 $this->body = $parser->body;
7800 $this->status_code = $parser->status_code;
7801 if ((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)
7804 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7805 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7807 if (isset($this->headers['content-encoding']))
7809 // Hey, we act dumb elsewhere, so let's do that here too
7810 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7814 $decoder =& new SimplePie_gzdecode($this->body);
7815 if (!$decoder->parse())
7817 $this->error = 'Unable to decode HTTP "gzip" stream';
7818 $this->success = false;
7822 $this->body = $decoder->data;
7827 if (($body = gzuncompress($this->body)) === false)
7829 if (($body = gzinflate($this->body)) === false)
7831 $this->error = 'Unable to decode HTTP "deflate" stream';
7832 $this->success = false;
7835 $this->body = $body;
7839 $this->error = 'Unknown content coding';
7840 $this->success = false;
7847 $this->error = 'fsocket timed out';
7848 $this->success = false;
7856 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7857 if (!$this->body = file_get_contents($url))
7859 $this->error = 'file_get_contents could not read the file';
7860 $this->success = false;
7867 * HTTP Response Parser
7869 * @package SimplePie
7871 class SimplePie_HTTP_Parser
7879 var $http_version = 0.0;
7887 var $status_code = 0;
7898 * Key/value pairs of the headers
7903 var $headers = array();
7906 * Body of the response
7914 * Current state of the state machine
7919 var $state = 'http_version';
7930 * Input data length (to avoid calling strlen() everytime this is needed)
7935 var $data_length = 0;
7938 * Current position of the pointer
7946 * Name of the hedaer currently being parsed
7954 * Value of the hedaer currently being parsed
7962 * Create an instance of the class with the input data
7965 * @param string $data Input data
7967 function SimplePie_HTTP_Parser($data)
7969 $this->data = $data;
7970 $this->data_length = strlen($this->data);
7974 * Parse the input data
7977 * @return bool true on success, false on failure
7981 while ($this->state && $this->state !== 'emit' && $this->has_data())
7983 $state = $this->state;
7987 if ($this->state === 'emit' || $this->state === 'body')
7993 $this->http_version = '';
7994 $this->status_code = '';
7996 $this->headers = array();
8003 * Check whether there is data beyond the pointer
8006 * @return bool true if there is further data, false if not
8010 return (bool) ($this->position < $this->data_length);
8014 * See if the next character is LWS
8017 * @return bool true if the next character is LWS, false if not
8019 function is_linear_whitespace()
8021 return (bool) ($this->data[$this->position] === "\x09"
8022 || $this->data[$this->position] === "\x20"
8023 || ($this->data[$this->position] === "\x0A"
8024 && isset($this->data[$this->position + 1])
8025 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8029 * Parse the HTTP version
8033 function http_version()
8035 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8037 $len = strspn($this->data, '0123456789.', 5);
8038 $this->http_version = substr($this->data, 5, $len);
8039 $this->position += 5 + $len;
8040 if (substr_count($this->http_version, '.') <= 1)
8042 $this->http_version = (float) $this->http_version;
8043 $this->position += strspn($this->data, "\x09\x20", $this->position);
8044 $this->state = 'status';
8048 $this->state = false;
8053 $this->state = false;
8058 * Parse the status code
8064 if ($len = strspn($this->data, '0123456789', $this->position))
8066 $this->status_code = (int) substr($this->data, $this->position, $len);
8067 $this->position += $len;
8068 $this->state = 'reason';
8072 $this->state = false;
8077 * Parse the reason phrase
8083 $len = strcspn($this->data, "\x0A", $this->position);
8084 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8085 $this->position += $len + 1;
8086 $this->state = 'new_line';
8090 * Deal with a new line, shifting data around as needed
8096 $this->value = trim($this->value, "\x0D\x20");
8097 if ($this->name !== '' && $this->value !== '')
8099 $this->name = strtolower($this->name);
8100 if (isset($this->headers[$this->name]))
8102 $this->headers[$this->name] .= ', ' . $this->value;
8106 $this->headers[$this->name] = $this->value;
8111 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8113 $this->position += 2;
8114 $this->state = 'body';
8116 elseif ($this->data[$this->position] === "\x0A")
8119 $this->state = 'body';
8123 $this->state = 'name';
8128 * Parse a header name
8134 $len = strcspn($this->data, "\x0A:", $this->position);
8135 if (isset($this->data[$this->position + $len]))
8137 if ($this->data[$this->position + $len] === "\x0A")
8139 $this->position += $len;
8140 $this->state = 'new_line';
8144 $this->name = substr($this->data, $this->position, $len);
8145 $this->position += $len + 1;
8146 $this->state = 'value';
8151 $this->state = false;
8156 * Parse LWS, replacing consecutive LWS characters with a single space
8160 function linear_whitespace()
8164 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8166 $this->position += 2;
8168 elseif ($this->data[$this->position] === "\x0A")
8172 $this->position += strspn($this->data, "\x09\x20", $this->position);
8173 } while ($this->has_data() && $this->is_linear_whitespace());
8174 $this->value .= "\x20";
8178 * See what state to move to while within non-quoted header values
8184 if ($this->is_linear_whitespace())
8186 $this->linear_whitespace();
8190 switch ($this->data[$this->position])
8194 $this->state = 'quote';
8199 $this->state = 'new_line';
8203 $this->state = 'value_char';
8210 * Parse a header value while outside quotes
8214 function value_char()
8216 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8217 $this->value .= substr($this->data, $this->position, $len);
8218 $this->position += $len;
8219 $this->state = 'value';
8223 * See what state to move to while within quoted header values
8229 if ($this->is_linear_whitespace())
8231 $this->linear_whitespace();
8235 switch ($this->data[$this->position])
8239 $this->state = 'value';
8244 $this->state = 'new_line';
8249 $this->state = 'quote_escaped';
8253 $this->state = 'quote_char';
8260 * Parse a header value while within quotes
8264 function quote_char()
8266 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8267 $this->value .= substr($this->data, $this->position, $len);
8268 $this->position += $len;
8269 $this->state = 'value';
8273 * Parse an escaped character within quotes
8277 function quote_escaped()
8279 $this->value .= $this->data[$this->position];
8281 $this->state = 'quote';
8291 $this->body = substr($this->data, $this->position);
8292 $this->state = 'emit';
8299 * @package SimplePie
8301 class SimplePie_gzdecode
8307 * @see gzdecode::$data
8309 var $compressed_data;
8312 * Size of compressed data
8316 var $compressed_size;
8319 * Minimum size of a valid gzip string
8323 var $min_compressed_size = 18;
8326 * Current position of pointer
8343 * @see gzdecode::$compressed_data
8372 * @see gzdecode::$extra_field
8373 * @see gzdecode::$SI2
8381 * @see gzdecode::$extra_field
8382 * @see gzdecode::$SI1
8387 * Extra field content
8390 * @see gzdecode::$SI1
8391 * @see gzdecode::$SI2
8403 * Human readable comment
8410 * Don't allow anything to be set
8414 function __set($name, $value)
8416 trigger_error("Cannot write property $name", E_USER_ERROR);
8420 * Set the compressed string and related properties
8424 function SimplePie_gzdecode($data)
8426 $this->compressed_data = $data;
8427 $this->compressed_size = strlen($data);
8431 * Decode the GZIP stream
8437 if ($this->compressed_size >= $this->min_compressed_size)
8439 // Check ID1, ID2, and CM
8440 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8445 // Get the FLG (FLaGs)
8446 $this->flags = ord($this->compressed_data[3]);
8448 // FLG bits above (1 << 4) are reserved
8449 if ($this->flags > 0x1F)
8454 // Advance the pointer after the above
8455 $this->position += 4;
8458 $mtime = substr($this->compressed_data, $this->position, 4);
8459 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8460 if (current(unpack('S', "\x00\x01")) === 1)
8462 $mtime = strrev($mtime);
8464 $this->MTIME = current(unpack('l', $mtime));
8465 $this->position += 4;
8467 // Get the XFL (eXtra FLags)
8468 $this->XFL = ord($this->compressed_data[$this->position++]);
8470 // Get the OS (Operating System)
8471 $this->OS = ord($this->compressed_data[$this->position++]);
8474 if ($this->flags & 4)
8476 // Read subfield IDs
8477 $this->SI1 = $this->compressed_data[$this->position++];
8478 $this->SI2 = $this->compressed_data[$this->position++];
8480 // SI2 set to zero is reserved for future use
8481 if ($this->SI2 === "\x00")
8486 // Get the length of the extra field
8487 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8490 // Check the length of the string is still valid
8491 $this->min_compressed_size += $len + 4;
8492 if ($this->compressed_size >= $this->min_compressed_size)
8494 // Set the extra field to the given data
8495 $this->extra_field = substr($this->compressed_data, $this->position, $len);
8496 $this->position += $len;
8505 if ($this->flags & 8)
8507 // Get the length of the filename
8508 $len = strcspn($this->compressed_data, "\x00", $this->position);
8510 // Check the length of the string is still valid
8511 $this->min_compressed_size += $len + 1;
8512 if ($this->compressed_size >= $this->min_compressed_size)
8514 // Set the original filename to the given string
8515 $this->filename = substr($this->compressed_data, $this->position, $len);
8516 $this->position += $len + 1;
8524 // Parse the FCOMMENT
8525 if ($this->flags & 16)
8527 // Get the length of the comment
8528 $len = strcspn($this->compressed_data, "\x00", $this->position);
8530 // Check the length of the string is still valid
8531 $this->min_compressed_size += $len + 1;
8532 if ($this->compressed_size >= $this->min_compressed_size)
8534 // Set the original comment to the given string
8535 $this->comment = substr($this->compressed_data, $this->position, $len);
8536 $this->position += $len + 1;
8545 if ($this->flags & 2)
8547 // Check the length of the string is still valid
8548 $this->min_compressed_size += $len + 2;
8549 if ($this->compressed_size >= $this->min_compressed_size)
8552 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8554 // Check the CRC matches
8555 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8557 $this->position += 2;
8570 // Decompress the actual data
8571 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8577 $this->position = $this->compressed_size - 8;
8580 // Check CRC of data
8581 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8582 $this->position += 4;
8583 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8588 // Check ISIZE of data
8589 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8590 $this->position += 4;
8591 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8596 // Wow, against all odds, we've actually got a valid gzip string
8606 class SimplePie_Cache
8609 * Don't call the constructor. Please.
8613 function SimplePie_Cache()
8615 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8619 * Create a new SimplePie_Cache object
8624 function create($location, $filename, $extension)
8626 $location_iri =& new SimplePie_IRI($location);
8627 switch ($location_iri->get_scheme())
8630 if (extension_loaded('mysql'))
8632 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
8637 return new SimplePie_Cache_File($location, $filename, $extension);
8642 class SimplePie_Cache_File
8649 function SimplePie_Cache_File($location, $filename, $extension)
8651 $this->location = $location;
8652 $this->filename = $filename;
8653 $this->extension = $extension;
8654 $this->name = "$this->location/$this->filename.$this->extension";
8657 function save($data)
8659 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8661 if (is_a($data, 'SimplePie'))
8663 $data = $data->data;
8666 $data = serialize($data);
8668 if (function_exists('file_put_contents'))
8670 return (bool) file_put_contents($this->name, $data);
8674 $fp = fopen($this->name, 'wb');
8688 if (file_exists($this->name) && is_readable($this->name))
8690 return unserialize(file_get_contents($this->name));
8697 if (file_exists($this->name))
8699 return filemtime($this->name);
8706 if (file_exists($this->name))
8708 return touch($this->name);
8715 if (file_exists($this->name))
8717 return unlink($this->name);
8723 class SimplePie_Cache_DB
8725 function prepare_simplepie_object_for_cache($data)
8727 $items = $data->get_items();
8728 $items_by_id = array();
8732 foreach ($items as $item)
8734 $items_by_id[$item->get_id()] = $item;
8737 if (count($items_by_id) !== count($items))
8739 $items_by_id = array();
8740 foreach ($items as $item)
8742 $items_by_id[$item->get_id(true)] = $item;
8746 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8748 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8750 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8752 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8754 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
8756 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
8758 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
8760 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
8767 if ($channel !== null)
8769 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
8771 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
8773 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
8775 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
8777 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
8779 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
8781 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
8783 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
8785 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
8787 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
8790 if (isset($data->data['items']))
8792 unset($data->data['items']);
8794 if (isset($data->data['ordered_items']))
8796 unset($data->data['ordered_items']);
8799 return array(serialize($data->data), $items_by_id);
8803 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
8809 function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
8811 $host = $mysql_location->get_host();
8812 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
8814 $server = ':' . substr($host, 5, -1);
8819 if ($mysql_location->get_port() !== null)
8821 $server .= ':' . $mysql_location->get_port();
8825 if (strpos($mysql_location->get_userinfo(), ':') !== false)
8827 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
8831 $username = $mysql_location->get_userinfo();
8835 if ($this->mysql = mysql_connect($server, $username, $password))
8837 $this->id = $name . $extension;
8838 $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
8839 if (!isset($this->options['prefix'][0]))
8841 $this->options['prefix'][0] = '';
8844 if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
8845 && mysql_query('SET NAMES utf8')
8846 && ($query = mysql_unbuffered_query('SHOW TABLES')))
8849 while ($row = mysql_fetch_row($query))
8854 if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
8856 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)))'))
8858 $this->mysql = null;
8862 if (!in_array($this->options['prefix'][0] . 'items', $db))
8864 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)))'))
8866 $this->mysql = null;
8872 $this->mysql = null;
8877 function save($data)
8881 $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
8883 if (is_a($data, 'SimplePie'))
8887 // This keyword needs to defy coding standards for PHP4 compatibility
8888 $data = clone($data);
8891 $prepared = $this->prepare_simplepie_object_for_cache($data);
8893 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8895 if (mysql_num_rows($query))
8897 $items = count($prepared[1]);
8900 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8904 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8907 if (!mysql_query($sql, $this->mysql))
8912 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))
8917 $ids = array_keys($prepared[1]);
8920 foreach ($ids as $id)
8922 $database_ids[] = mysql_real_escape_string($id);
8925 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))
8927 $existing_ids = array();
8928 while ($row = mysql_fetch_row($query))
8930 $existing_ids[] = $row[0];
8933 $new_ids = array_diff($ids, $existing_ids);
8935 foreach ($new_ids as $new_id)
8937 if (!($date = $prepared[1][$new_id]->get_date('U')))
8942 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))
8956 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8958 if (mysql_num_rows($query))
8960 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))
8965 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))
8976 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)))
8978 $data = unserialize($row[1]);
8980 if (isset($this->options['items'][0]))
8982 $items = (int) $this->options['items'][0];
8986 $items = (int) $row[0];
8991 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8993 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8995 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8997 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8999 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
9001 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
9003 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
9005 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
9014 $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
9017 $sql .= ' LIMIT ' . $items;
9020 if ($query = mysql_unbuffered_query($sql, $this->mysql))
9022 while ($row = mysql_fetch_row($query))
9024 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
9040 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)))
9052 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))
9064 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)))
9075 class SimplePie_Misc
9077 function time_hms($seconds)
9081 $hours = floor($seconds / 3600);
9082 $remainder = $seconds % 3600;
9085 $time .= $hours.':';
9088 $minutes = floor($remainder / 60);
9089 $seconds = $remainder % 60;
9090 if ($minutes < 10 && $hours > 0)
9092 $minutes = '0' . $minutes;
9096 $seconds = '0' . $seconds;
9099 $time .= $minutes.':';
9105 function absolutize_url($relative, $base)
9107 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
9108 return $iri->get_iri();
9111 function remove_dot_segments($input)
9114 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
9116 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
9117 if (strpos($input, '../') === 0)
9119 $input = substr($input, 3);
9121 elseif (strpos($input, './') === 0)
9123 $input = substr($input, 2);
9125 // 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,
9126 elseif (strpos($input, '/./') === 0)
9128 $input = substr_replace($input, '/', 0, 3);
9130 elseif ($input === '/.')
9134 // 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,
9135 elseif (strpos($input, '/../') === 0)
9137 $input = substr_replace($input, '/', 0, 4);
9138 $output = substr_replace($output, '', strrpos($output, '/'));
9140 elseif ($input === '/..')
9143 $output = substr_replace($output, '', strrpos($output, '/'));
9145 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
9146 elseif ($input === '.' || $input === '..')
9150 // 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
9151 elseif (($pos = strpos($input, '/', 1)) !== false)
9153 $output .= substr($input, 0, $pos);
9154 $input = substr_replace($input, '', 0, $pos);
9162 return $output . $input;
9165 function get_element($realname, $string)
9168 $name = preg_quote($realname, '/');
9169 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
9171 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
9173 $return[$i]['tag'] = $realname;
9174 $return[$i]['full'] = $matches[$i][0][0];
9175 $return[$i]['offset'] = $matches[$i][0][1];
9176 if (strlen($matches[$i][3][0]) <= 2)
9178 $return[$i]['self_closing'] = true;
9182 $return[$i]['self_closing'] = false;
9183 $return[$i]['content'] = $matches[$i][4][0];
9185 $return[$i]['attribs'] = array();
9186 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))
9188 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
9190 if (count($attribs[$j]) === 2)
9192 $attribs[$j][2] = $attribs[$j][1];
9194 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
9202 function element_implode($element)
9204 $full = "<$element[tag]";
9205 foreach ($element['attribs'] as $key => $value)
9207 $key = strtolower($key);
9208 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
9210 if ($element['self_closing'])
9216 $full .= ">$element[content]</$element[tag]>";
9221 function error($message, $level, $file, $line)
9223 if ((ini_get('error_reporting') & $level) > 0)
9228 $note = 'PHP Error';
9230 case E_USER_WARNING:
9231 $note = 'PHP Warning';
9234 $note = 'PHP Notice';
9237 $note = 'Unknown Error';
9240 error_log("$note: $message in $file on line $line", 0);
9246 * If a file has been cached, retrieve and display it.
9248 * This is most useful for caching images (get_favicon(), etc.),
9249 * however it works for all cached files. This WILL NOT display ANY
9250 * file/image/page/whatever, but rather only display what has already
9251 * been cached by SimplePie.
9254 * @see SimplePie::get_favicon()
9255 * @param str $identifier_url URL that is used to identify the content.
9256 * This may or may not be the actual URL of the live content.
9257 * @param str $cache_location Location of SimplePie's cache. Defaults
9259 * @param str $cache_extension The file extension that the file was
9260 * cached with. Defaults to 'spc'.
9261 * @param str $cache_class Name of the cache-handling class being used
9262 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
9263 * as-is unless you've overloaded the class.
9264 * @param str $cache_name_function Obsolete. Exists for backwards
9265 * compatibility reasons only.
9267 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
9269 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
9271 if ($file = $cache->load())
9273 if (isset($file['headers']['content-type']))
9275 header('Content-type:' . $file['headers']['content-type']);
9279 header('Content-type: application/octet-stream');
9281 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
9286 die('Cached file for ' . $identifier_url . ' cannot be found.');
9289 function fix_protocol($url, $http = 1)
9291 $url = SimplePie_Misc::normalize_url($url);
9292 $parsed = SimplePie_Misc::parse_url($url);
9293 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
9295 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
9298 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
9300 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9303 if ($http === 2 && $parsed['scheme'] !== '')
9307 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
9309 return substr_replace($url, 'podcast', 0, 4);
9311 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
9313 return substr_replace($url, 'itpc', 0, 4);
9321 function parse_url($url)
9323 $iri =& new SimplePie_IRI($url);
9325 'scheme' => (string) $iri->get_scheme(),
9326 'authority' => (string) $iri->get_authority(),
9327 'path' => (string) $iri->get_path(),
9328 'query' => (string) $iri->get_query(),
9329 'fragment' => (string) $iri->get_fragment()
9333 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9335 $iri =& new SimplePie_IRI('');
9336 $iri->set_scheme($scheme);
9337 $iri->set_authority($authority);
9338 $iri->set_path($path);
9339 $iri->set_query($query);
9340 $iri->set_fragment($fragment);
9341 return $iri->get_iri();
9344 function normalize_url($url)
9346 $iri =& new SimplePie_IRI($url);
9347 return $iri->get_iri();
9350 function percent_encoding_normalization($match)
9352 $integer = hexdec($match[1]);
9353 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
9355 return chr($integer);
9359 return strtoupper($match[0]);
9364 * Remove bad UTF-8 bytes
9366 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9367 * FAQ: Multilingual Forms (modified to include full ASCII range)
9369 * @author Geoffrey Sneddon
9370 * @see http://www.w3.org/International/questions/qa-forms-utf-8
9371 * @param string $str String to remove bad UTF-8 bytes from
9372 * @return string UTF-8 string
9374 function utf8_bad_replace($str)
9376 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9380 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9384 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))
9386 return implode("\xEF\xBF\xBD", $matches[0]);
9388 elseif ($str !== '')
9390 return "\xEF\xBF\xBD";
9399 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9403 * @param string $string Windows-1252 encoded string
9404 * @return string UTF-8 encoded string
9406 function windows_1252_to_utf8($string)
9408 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");
9410 return strtr($string, $convert_table);
9413 function change_encoding($data, $input, $output)
9415 $input = SimplePie_Misc::encoding($input);
9416 $output = SimplePie_Misc::encoding($output);
9418 // We fail to fail on non US-ASCII bytes
9419 if ($input === 'US-ASCII')
9421 static $non_ascii_octects = '';
9422 if (!$non_ascii_octects)
9424 for ($i = 0x80; $i <= 0xFF; $i++)
9426 $non_ascii_octects .= chr($i);
9429 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9432 // This is first, as behaviour of this is completely predictable
9433 if ($input === 'Windows-1252' && $output === 'UTF-8')
9435 return SimplePie_Misc::windows_1252_to_utf8($data);
9437 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9438 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
9442 // This is last, as behaviour of this varies with OS userland and PHP version
9443 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9447 // If we can't do anything, just fail
9454 function encoding($charset)
9456 // Normalization from UTS #22
9457 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9459 case 'adobestandardencoding':
9460 case 'csadobestandardencoding':
9461 return 'Adobe-Standard-Encoding';
9463 case 'adobesymbolencoding':
9465 return 'Adobe-Symbol-Encoding';
9469 return 'Amiga-1251';
9471 case 'ansix31101983':
9473 case 'csiso99naplps':
9476 return 'ANSI_X3.110-1983';
9480 case 'csiso89asmo449':
9491 return 'Big5-HKSCS';
9502 case 'csiso4unitedkingdom':
9510 case 'csiso47bsviewdata':
9512 return 'BS_viewdata';
9520 case 'csaz243419851':
9521 case 'csiso121canadian1':
9524 return 'CSA_Z243.4-1985-1';
9527 case 'csaz243419852':
9528 case 'csiso122canadian2':
9531 return 'CSA_Z243.4-1985-2';
9533 case 'csaz24341985gr':
9534 case 'csiso123csaz24341985gr':
9536 return 'CSA_Z243.4-1985-gr';
9538 case 'csiso139csn369103':
9541 return 'CSN_369103';
9548 case 'csiso21german':
9559 case 'csiso646danish':
9565 case 'csibmebcdicatde':
9567 return 'EBCDIC-AT-DE';
9569 case 'csebcdicatdea':
9571 return 'EBCDIC-AT-DE-A';
9573 case 'csebcdiccafr':
9575 return 'EBCDIC-CA-FR';
9577 case 'csebcdicdkno':
9579 return 'EBCDIC-DK-NO';
9581 case 'csebcdicdknoa':
9583 return 'EBCDIC-DK-NO-A';
9591 return 'EBCDIC-ES-A';
9595 return 'EBCDIC-ES-S';
9597 case 'csebcdicfise':
9599 return 'EBCDIC-FI-SE';
9601 case 'csebcdicfisea':
9603 return 'EBCDIC-FI-SE-A';
9625 case 'csiso111ecmacyrillic':
9626 case 'ecmacyrillic':
9629 return 'ECMA-cyrillic';
9631 case 'csiso17spanish':
9637 case 'csiso85spanish2':
9643 case 'cseucfixwidjapanese':
9644 case 'extendedunixcodefixedwidthforjapanese':
9645 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9647 case 'cseucpkdfmtjapanese':
9649 case 'extendedunixcodepackedformatforjapanese':
9650 return 'Extended_UNIX_Code_Packed_Format_for_Japanese';
9658 case 'csiso58gb231280':
9668 case 'csiso57gb1988':
9672 return 'GB_1988-80';
9674 case 'csiso153gost1976874':
9678 return 'GOST_19768-74';
9681 case 'csiso150greekccitt':
9684 return 'greek-ccitt';
9686 case 'csiso88greek7':
9691 case 'csiso18greek7old':
9694 return 'greek7-old';
9698 return 'HP-DeskTop';
9710 return 'HP-Pi-font';
9719 return 'HZ-GB-2312';
9721 case 'csibmsymbols':
9723 return 'IBM-Symbols';
9732 case 'pcmultilingual850euro':
9737 case 'ebcdiclatin9euro':
9743 case 'ebcdicus37euro':
9749 case 'ebcdicde273euro':
9755 case 'ebcdicdk277euro':
9756 case 'ebcdicno277euro':
9762 case 'ebcdicfi278euro':
9763 case 'ebcdicse278euro':
9769 case 'ebcdicit280euro':
9775 case 'ebcdices284euro':
9781 case 'ebcdicgb285euro':
9787 case 'ebcdicfr297euro':
9793 case 'ebcdicinternational500euro':
9799 case 'ebcdicis871euro':
9874 case 'ebcdicjpkana':
9904 case 'cspc8codepage437':
9916 case 'cspc775baltic':
9922 case 'cspc850multilingual':
9965 case 'cspc862latinhebrew':
10007 case 'ebcdiccproece':
10020 case 'ebcdiccyrillic':
10048 case 'ebcdiccpar2':
10060 case 'csiso143iecp271':
10063 return 'IEC_P27-1';
10065 case 'csiso49inis':
10070 case 'csiso50inis8':
10075 case 'csiso51iniscyrillic':
10076 case 'iniscyrillic':
10078 return 'INIS-cyrillic';
10080 case 'csinvariant':
10082 return 'INVARIANT';
10085 return 'ISO-2022-CN';
10087 case 'iso2022cnext':
10088 return 'ISO-2022-CN-EXT';
10090 case 'csiso2022jp':
10092 return 'ISO-2022-JP';
10094 case 'csiso2022jp2':
10096 return 'ISO-2022-JP-2';
10098 case 'csiso2022kr':
10100 return 'ISO-2022-KR';
10102 case 'cswindows30latin1':
10103 case 'iso88591windows30latin1':
10104 return 'ISO-8859-1-Windows-3.0-Latin-1';
10106 case 'cswindows31latin1':
10107 case 'iso88591windows31latin1':
10108 return 'ISO-8859-1-Windows-3.1-Latin-1';
10110 case 'csisolatin2':
10112 case 'iso885921987':
10116 return 'ISO-8859-2';
10118 case 'cswindows31latin2':
10119 case 'iso88592windowslatin2':
10120 return 'ISO-8859-2-Windows-Latin-2';
10122 case 'csisolatin3':
10124 case 'iso885931988':
10128 return 'ISO-8859-3';
10130 case 'csisolatin4':
10132 case 'iso885941988':
10136 return 'ISO-8859-4';
10138 case 'csisolatincyrillic':
10141 case 'iso885951988':
10143 return 'ISO-8859-5';
10147 case 'csisolatinarabic':
10150 case 'iso885961987':
10152 return 'ISO-8859-6';
10154 case 'csiso88596e':
10156 return 'ISO-8859-6-E';
10158 case 'csiso88596i':
10160 return 'ISO-8859-6-I';
10162 case 'csisolatingreek':
10168 case 'iso885971987':
10170 return 'ISO-8859-7';
10172 case 'csisolatinhebrew':
10175 case 'iso885981988':
10177 return 'ISO-8859-8';
10179 case 'csiso88598e':
10181 return 'ISO-8859-8-E';
10183 case 'csiso88598i':
10185 return 'ISO-8859-8-I';
10187 case 'cswindows31latin5':
10188 case 'iso88599windowslatin5':
10189 return 'ISO-8859-9-Windows-Latin-5';
10191 case 'csisolatin6':
10193 case 'iso8859101992':
10197 return 'ISO-8859-10';
10200 return 'ISO-8859-13';
10203 case 'iso8859141998':
10208 return 'ISO-8859-14';
10212 return 'ISO-8859-15';
10215 case 'iso8859162001':
10219 return 'ISO-8859-16';
10222 return 'ISO-10646-J-1';
10225 case 'iso10646ucs2':
10226 return 'ISO-10646-UCS-2';
10229 case 'iso10646ucs4':
10230 return 'ISO-10646-UCS-4';
10232 case 'csunicodeascii':
10233 case 'iso10646ucsbasic':
10234 return 'ISO-10646-UCS-Basic';
10236 case 'csunicodelatin1':
10238 case 'iso10646unicodelatin1':
10239 return 'ISO-10646-Unicode-Latin1';
10241 case 'csiso10646utf1':
10242 case 'iso10646utf1':
10243 return 'ISO-10646-UTF-1';
10245 case 'csiso115481':
10247 case 'isotr115481':
10248 return 'ISO-11548-1';
10252 return 'iso-ir-90';
10254 case 'csunicodeibm1261':
10255 case 'isounicodeibm1261':
10256 return 'ISO-Unicode-IBM-1261';
10258 case 'csunicodeibm1264':
10259 case 'isounicodeibm1264':
10260 return 'ISO-Unicode-IBM-1264';
10262 case 'csunicodeibm1265':
10263 case 'isounicodeibm1265':
10264 return 'ISO-Unicode-IBM-1265';
10266 case 'csunicodeibm1268':
10267 case 'isounicodeibm1268':
10268 return 'ISO-Unicode-IBM-1268';
10270 case 'csunicodeibm1276':
10271 case 'isounicodeibm1276':
10272 return 'ISO-Unicode-IBM-1276';
10274 case 'csiso646basic1983':
10275 case 'iso646basic1983':
10277 return 'ISO_646.basic:1983';
10279 case 'csiso2intlrefversion':
10281 case 'iso646irv1983':
10283 return 'ISO_646.irv:1983';
10287 case 'iso20331983':
10289 return 'ISO_2033-1983';
10291 case 'csiso5427cyrillic':
10296 case 'iso5427cyrillic1981':
10297 case 'iso54271981':
10299 return 'ISO_5427:1981';
10301 case 'csiso5428greek':
10302 case 'iso54281980':
10304 return 'ISO_5428:1980';
10306 case 'csiso6937add':
10309 return 'ISO_6937-2-25';
10311 case 'csisotextcomm':
10312 case 'iso69372add':
10314 return 'ISO_6937-2-add';
10316 case 'csiso8859supp':
10317 case 'iso8859supp':
10320 return 'ISO_8859-supp';
10322 case 'csiso10367box':
10323 case 'iso10367box':
10325 return 'ISO_10367-box';
10327 case 'csiso15italian':
10333 case 'csiso13jisc6220jp':
10335 case 'jisc62201969':
10336 case 'jisc62201969jp':
10339 return 'JIS_C6220-1969-jp';
10341 case 'csiso14jisc6220ro':
10344 case 'jisc62201969ro':
10346 return 'JIS_C6220-1969-ro';
10348 case 'csiso42jisc62261978':
10350 case 'jisc62261978':
10351 return 'JIS_C6226-1978';
10353 case 'csiso87jisx208':
10355 case 'jisc62261983':
10356 case 'jisx2081983':
10358 return 'JIS_C6226-1983';
10360 case 'csiso91jisc62291984a':
10362 case 'jisc62291984a':
10364 return 'JIS_C6229-1984-a';
10366 case 'csiso92jisc62991984b':
10367 case 'iso646jpocrb':
10369 case 'jisc62291984b':
10371 return 'JIS_C6229-1984-b';
10373 case 'csiso93jis62291984badd':
10375 case 'jisc62291984badd':
10377 return 'JIS_C6229-1984-b-add';
10379 case 'csiso94jis62291984hand':
10381 case 'jisc62291984hand':
10383 return 'JIS_C6229-1984-hand';
10385 case 'csiso95jis62291984handadd':
10387 case 'jisc62291984handadd':
10388 case 'jpocrhandadd':
10389 return 'JIS_C6229-1984-hand-add';
10391 case 'csiso96jisc62291984kana':
10393 case 'jisc62291984kana':
10394 return 'JIS_C6229-1984-kana';
10396 case 'csjisencoding':
10397 case 'jisencoding':
10398 return 'JIS_Encoding';
10400 case 'cshalfwidthkatakana':
10403 return 'JIS_X0201';
10405 case 'csiso159jisx2121990':
10407 case 'jisx2121990':
10409 return 'JIS_X0212-1990';
10411 case 'csiso141jusib1002':
10417 return 'JUS_I.B1.002';
10419 case 'csiso147macedonian':
10421 case 'jusib1003mac':
10423 return 'JUS_I.B1.003-mac';
10425 case 'csiso146serbian':
10427 case 'jusib1003serb':
10429 return 'JUS_I.B1.003-serb';
10431 case 'koi7switched':
10432 return 'KOI7-switched';
10449 case 'strk10482002':
10452 case 'csiso19latingreek':
10455 return 'latin-greek';
10457 case 'csiso27latingreek1':
10459 case 'latingreek1':
10460 return 'Latin-greek-1';
10462 case 'csiso158lap':
10466 return 'latin-lap';
10468 case 'csmacintosh':
10471 return 'macintosh';
10473 case 'csmicrosoftpublishing':
10474 case 'microsoftpublishing':
10475 return 'Microsoft-Publishing';
10485 case 'csiso86hungarian':
10490 return 'MSZ_7795.3';
10495 return 'NATS-DANO';
10497 case 'csnatsdanoadd':
10499 case 'natsdanoadd':
10500 return 'NATS-DANO-ADD';
10505 return 'NATS-SEFI';
10507 case 'csnatssefiadd':
10509 case 'natssefiadd':
10510 return 'NATS-SEFI-ADD';
10512 case 'csiso151cuba':
10517 return 'NC_NC00-10:81';
10519 case 'csiso69french':
10524 return 'NF_Z_62-010';
10526 case 'csiso25french':
10529 case 'nfz620101973':
10530 return 'NF_Z_62-010_(1973)';
10532 case 'csiso60danishnorwegian':
10533 case 'csiso60norwegian1':
10538 return 'NS_4551-1';
10540 case 'csiso61norwegian2':
10545 return 'NS_4551-2';
10547 case 'osdebcdicdf3irv':
10548 return 'OSD_EBCDIC_DF03_IRV';
10550 case 'osdebcdicdf41':
10551 return 'OSD_EBCDIC_DF04_1';
10553 case 'osdebcdicdf415':
10554 return 'OSD_EBCDIC_DF04_15';
10556 case 'cspc8danishnorwegian':
10557 case 'pc8danishnorwegian':
10558 return 'PC8-Danish-Norwegian';
10560 case 'cspc8turkish':
10562 return 'PC8-Turkish';
10564 case 'csiso16portuguese':
10570 case 'csiso84portuguese2':
10578 case 'cyrillicasian':
10586 case 'csiso10swedish':
10593 return 'SEN_850200_B';
10595 case 'csiso11swedishfornames':
10600 return 'SEN_850200_C';
10605 return 'Shift_JIS';
10607 case 'csiso102t617bit':
10610 return 'T.61-7bit';
10612 case 'csiso103t618bit':
10616 return 'T.61-8bit';
10618 case 'csiso128t101g2':
10627 case 'csunicode11':
10629 return 'UNICODE-1-1';
10631 case 'csunicode11utf7':
10632 case 'unicode11utf7':
10633 return 'UNICODE-1-1-UTF-7';
10635 case 'csunknown8bit':
10636 case 'unknown8bit':
10637 return 'UNKNOWN-8BIT';
10639 case 'ansix341968':
10640 case 'ansix341986':
10645 case 'iso646irv1991':
10680 case 'csventurainternational':
10681 case 'venturainternational':
10682 return 'Ventura-International';
10684 case 'csventuramath':
10685 case 'venturamath':
10686 return 'Ventura-Math';
10688 case 'csventuraus':
10690 return 'Ventura-US';
10692 case 'csiso70videotexsupp1':
10694 case 'videotexsuppl':
10695 return 'videotex-suppl';
10705 case 'cswindows31j':
10707 return 'Windows-31J';
10711 return 'windows-874';
10714 case 'csksc56011987':
10719 case 'ksc56011987':
10720 case 'ksc56011989':
10722 return 'windows-949';
10724 case 'windows1250':
10725 return 'windows-1250';
10727 case 'windows1251':
10728 return 'windows-1251';
10731 case 'csisolatin1':
10734 case 'iso885911987':
10738 case 'windows1252':
10739 return 'windows-1252';
10741 case 'windows1253':
10742 return 'windows-1253';
10744 case 'csisolatin5':
10746 case 'iso885991989':
10750 case 'windows1254':
10751 return 'windows-1254';
10753 case 'windows1255':
10754 return 'windows-1255';
10756 case 'windows1256':
10757 return 'windows-1256';
10759 case 'windows1257':
10760 return 'windows-1257';
10762 case 'windows1258':
10763 return 'windows-1258';
10770 function get_curl_version()
10772 if (is_array($curl = curl_version()))
10774 $curl = $curl['version'];
10776 elseif (substr($curl, 0, 5) === 'curl/')
10778 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10780 elseif (substr($curl, 0, 8) === 'libcurl/')
10782 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10791 function is_subclass_of($class1, $class2)
10793 if (func_num_args() !== 2)
10795 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10797 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10799 return is_subclass_of($class1, $class2);
10801 elseif (is_string($class1) && is_string($class2))
10803 if (class_exists($class1))
10805 if (class_exists($class2))
10807 $class2 = strtolower($class2);
10808 while ($class1 = strtolower(get_parent_class($class1)))
10810 if ($class1 === $class2)
10819 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10826 * Strip HTML comments
10829 * @param string $data Data to strip comments from
10830 * @return string Comment stripped string
10832 function strip_comments($data)
10835 while (($start = strpos($data, '<!--')) !== false)
10837 $output .= substr($data, 0, $start);
10838 if (($end = strpos($data, '-->', $start)) !== false)
10840 $data = substr_replace($data, '', 0, $end + 3);
10847 return $output . $data;
10850 function parse_date($dt)
10852 $parser = SimplePie_Parse_Date::get();
10853 return $parser->parse($dt);
10857 * Decode HTML entities
10861 * @param string $data Input data
10862 * @return string Output data
10864 function entities_decode($data)
10866 $decoder =& new SimplePie_Decode_HTML_Entities($data);
10867 return $decoder->parse();
10871 * Remove RFC822 comments
10874 * @param string $data Data to strip comments from
10875 * @return string Comment stripped string
10877 function uncomment_rfc822($string)
10879 $string = (string) $string;
10881 $length = strlen($string);
10886 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10888 $output .= substr($string, $position, $pos - $position);
10889 $position = $pos + 1;
10890 if ($string[$pos - 1] !== '\\')
10893 while ($depth && $position < $length)
10895 $position += strcspn($string, '()', $position);
10896 if ($string[$position - 1] === '\\')
10901 elseif (isset($string[$position]))
10903 switch ($string[$position])
10926 $output .= substr($string, $position);
10931 function parse_mime($mime)
10933 if (($pos = strpos($mime, ';')) === false)
10935 return trim($mime);
10939 return trim(substr($mime, 0, $pos));
10943 function htmlspecialchars_decode($string, $quote_style)
10945 if (function_exists('htmlspecialchars_decode'))
10947 return htmlspecialchars_decode($string, $quote_style);
10951 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10955 function atom_03_construct_type($attribs)
10957 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
10959 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10963 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10965 if (isset($attribs['']['type']))
10967 switch (strtolower(trim($attribs['']['type'])))
10971 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10975 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10978 case 'application/xhtml+xml':
10979 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10982 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10987 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10991 function atom_10_construct_type($attribs)
10993 if (isset($attribs['']['type']))
10995 switch (strtolower(trim($attribs['']['type'])))
10998 return SIMPLEPIE_CONSTRUCT_TEXT;
11001 return SIMPLEPIE_CONSTRUCT_HTML;
11004 return SIMPLEPIE_CONSTRUCT_XHTML;
11007 return SIMPLEPIE_CONSTRUCT_NONE;
11010 return SIMPLEPIE_CONSTRUCT_TEXT;
11013 function atom_10_content_construct_type($attribs)
11015 if (isset($attribs['']['type']))
11017 $type = strtolower(trim($attribs['']['type']));
11021 return SIMPLEPIE_CONSTRUCT_TEXT;
11024 return SIMPLEPIE_CONSTRUCT_HTML;
11027 return SIMPLEPIE_CONSTRUCT_XHTML;
11029 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
11031 return SIMPLEPIE_CONSTRUCT_NONE;
11035 return SIMPLEPIE_CONSTRUCT_BASE64;
11040 return SIMPLEPIE_CONSTRUCT_TEXT;
11044 function is_isegment_nz_nc($string)
11046 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);
11049 function space_seperated_tokens($string)
11051 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
11052 $string_length = strlen($string);
11054 $position = strspn($string, $space_characters);
11057 while ($position < $string_length)
11059 $len = strcspn($string, $space_characters, $position);
11060 $tokens[] = substr($string, $position, $len);
11062 $position += strspn($string, $space_characters, $position);
11068 function array_unique($array)
11070 if (version_compare(PHP_VERSION, '5.2', '>='))
11072 return array_unique($array);
11076 $array = (array) $array;
11077 $new_array = array();
11078 $new_array_strings = array();
11079 foreach ($array as $key => $value)
11081 if (is_object($value))
11083 if (method_exists($value, '__toString'))
11085 $cmp = $value->__toString();
11089 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
11092 elseif (is_array($value))
11094 $cmp = (string) reset($value);
11098 $cmp = (string) $value;
11100 if (!in_array($cmp, $new_array_strings))
11102 $new_array[$key] = $value;
11103 $new_array_strings[] = $cmp;
11111 * Converts a unicode codepoint to a UTF-8 character
11115 * @param int $codepoint Unicode codepoint
11116 * @return string UTF-8 character
11118 function codepoint_to_utf8($codepoint)
11120 $codepoint = (int) $codepoint;
11121 if ($codepoint < 0)
11125 else if ($codepoint <= 0x7f)
11127 return chr($codepoint);
11129 else if ($codepoint <= 0x7ff)
11131 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
11133 else if ($codepoint <= 0xffff)
11135 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11137 else if ($codepoint <= 0x10ffff)
11139 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11143 // U+FFFD REPLACEMENT CHARACTER
11144 return "\xEF\xBF\xBD";
11149 * Re-implementation of PHP 5's stripos()
11151 * Returns the numeric position of the first occurrence of needle in the
11156 * @param object $haystack
11157 * @param string $needle Note that the needle may be a string of one or more
11158 * characters. If needle is not a string, it is converted to an integer
11159 * and applied as the ordinal value of a character.
11160 * @param int $offset The optional offset parameter allows you to specify which
11161 * character in haystack to start searching. The position returned is still
11162 * relative to the beginning of haystack.
11163 * @return bool If needle is not found, stripos() will return boolean false.
11165 function stripos($haystack, $needle, $offset = 0)
11167 if (function_exists('stripos'))
11169 return stripos($haystack, $needle, $offset);
11173 if (is_string($needle))
11175 $needle = strtolower($needle);
11177 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
11179 $needle = strtolower(chr($needle));
11183 trigger_error('needle is not a string or an integer', E_USER_WARNING);
11187 return strpos(strtolower($haystack), $needle, $offset);
11192 * Similar to parse_str()
11194 * Returns an associative array of name/value pairs, where the value is an
11195 * array of values that have used the same name
11199 * @param string $str The input string.
11202 function parse_str($str)
11205 $str = explode('&', $str);
11207 foreach ($str as $section)
11209 if (strpos($section, '=') !== false)
11211 list($name, $value) = explode('=', $section, 2);
11212 $return[urldecode($name)][] = urldecode($value);
11216 $return[urldecode($section)][] = null;
11224 * Detect XML encoding, as per XML 1.0 Appendix F.1
11226 * @todo Add support for EBCDIC
11227 * @param string $data XML data
11228 * @return array Possible encodings
11230 function xml_encoding($data)
11232 // UTF-32 Big Endian BOM
11233 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
11235 $encoding[] = 'UTF-32BE';
11237 // UTF-32 Little Endian BOM
11238 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
11240 $encoding[] = 'UTF-32LE';
11242 // UTF-16 Big Endian BOM
11243 elseif (substr($data, 0, 2) === "\xFE\xFF")
11245 $encoding[] = 'UTF-16BE';
11247 // UTF-16 Little Endian BOM
11248 elseif (substr($data, 0, 2) === "\xFF\xFE")
11250 $encoding[] = 'UTF-16LE';
11253 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11255 $encoding[] = 'UTF-8';
11257 // UTF-32 Big Endian Without BOM
11258 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")
11260 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11262 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11263 if ($parser->parse())
11265 $encoding[] = $parser->encoding;
11268 $encoding[] = 'UTF-32BE';
11270 // UTF-32 Little Endian Without BOM
11271 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")
11273 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11275 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11276 if ($parser->parse())
11278 $encoding[] = $parser->encoding;
11281 $encoding[] = 'UTF-32LE';
11283 // UTF-16 Big Endian Without BOM
11284 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11286 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11288 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11289 if ($parser->parse())
11291 $encoding[] = $parser->encoding;
11294 $encoding[] = 'UTF-16BE';
11296 // UTF-16 Little Endian Without BOM
11297 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11299 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11301 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11302 if ($parser->parse())
11304 $encoding[] = $parser->encoding;
11307 $encoding[] = 'UTF-16LE';
11309 // US-ASCII (or superset)
11310 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11312 if ($pos = strpos($data, "\x3F\x3E"))
11314 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11315 if ($parser->parse())
11317 $encoding[] = $parser->encoding;
11320 $encoding[] = 'UTF-8';
11322 // Fallback to UTF-8
11325 $encoding[] = 'UTF-8';
11330 function output_javascript()
11332 if (function_exists('ob_gzhandler'))
11334 ob_start('ob_gzhandler');
11336 header('Content-type: text/javascript; charset: UTF-8');
11337 header('Cache-Control: must-revalidate');
11338 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
11340 function embed_odeo(link) {
11341 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>');
11344 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
11345 if (placeholder != '') {
11346 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>');
11349 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>');
11353 function embed_flash(bgcolor, width, height, link, loop, type) {
11354 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>');
11357 function embed_flv(width, height, link, placeholder, loop, player) {
11358 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>');
11361 function embed_wmedia(width, height, link) {
11362 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
11369 * Decode HTML Entities
11371 * This implements HTML5 as of revision 967 (2007-06-28)
11373 * @package SimplePie
11375 class SimplePie_Decode_HTML_Entities
11378 * Data to be parsed
11386 * Currently consumed bytes
11391 var $consumed = '';
11394 * Position of the current byte being parsed
11402 * Create an instance of the class with the input data
11405 * @param string $data Input data
11407 function SimplePie_Decode_HTML_Entities($data)
11409 $this->data = $data;
11413 * Parse the input data
11416 * @return string Output data
11420 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11424 $this->consumed = '';
11426 return $this->data;
11430 * Consume the next byte
11433 * @return mixed The next byte, or false, if there is no more data
11437 if (isset($this->data[$this->position]))
11439 $this->consumed .= $this->data[$this->position];
11440 return $this->data[$this->position++];
11449 * Consume a range of characters
11452 * @param string $chars Characters to consume
11453 * @return mixed A series of characters that match the range, or false
11455 function consume_range($chars)
11457 if ($len = strspn($this->data, $chars, $this->position))
11459 $data = substr($this->data, $this->position, $len);
11460 $this->consumed .= $data;
11461 $this->position += $len;
11471 * Unconsume one byte
11475 function unconsume()
11477 $this->consumed = substr($this->consumed, 0, -1);
11488 switch ($this->consume())
11502 switch ($this->consume())
11506 $range = '0123456789ABCDEFabcdef';
11511 $range = '0123456789';
11513 $this->unconsume();
11517 if ($codepoint = $this->consume_range($range))
11519 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");
11523 $codepoint = hexdec($codepoint);
11527 $codepoint = intval($codepoint);
11530 if (isset($windows_1252_specials[$codepoint]))
11532 $replacement = $windows_1252_specials[$codepoint];
11536 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11539 if (!in_array($this->consume(), array(';', false), true))
11541 $this->unconsume();
11544 $consumed_length = strlen($this->consumed);
11545 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11546 $this->position += strlen($replacement) - $consumed_length;
11551 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");
11553 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11555 $consumed = substr($this->consumed, 1);
11556 if (isset($entities[$consumed]))
11558 $match = $consumed;
11562 if ($match !== null)
11564 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11565 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11573 * IRI parser/serialiser
11575 * @package SimplePie
11577 class SimplePie_IRI
11636 * Whether the object represents a valid IRI
11641 var $valid = array();
11644 * Return the entire IRI when you try and read the object as a string
11649 function __toString()
11651 return $this->get_iri();
11655 * Create a new IRI object, from a specified string
11658 * @param string $iri
11659 * @return SimplePie_IRI
11661 function SimplePie_IRI($iri)
11663 $iri = (string) $iri;
11666 $parsed = $this->parse_iri($iri);
11667 $this->set_scheme($parsed['scheme']);
11668 $this->set_authority($parsed['authority']);
11669 $this->set_path($parsed['path']);
11670 $this->set_query($parsed['query']);
11671 $this->set_fragment($parsed['fragment']);
11676 * Create a new IRI object by resolving a relative IRI
11680 * @param SimplePie_IRI $base Base IRI
11681 * @param string $relative Relative IRI
11682 * @return SimplePie_IRI
11684 function absolutize($base, $relative)
11686 $relative = (string) $relative;
11687 if ($relative !== '')
11689 $relative =& new SimplePie_IRI($relative);
11690 if ($relative->get_scheme() !== null)
11692 $target = $relative;
11694 elseif ($base->get_iri() !== null)
11696 if ($relative->get_authority() !== null)
11698 $target = $relative;
11699 $target->set_scheme($base->get_scheme());
11703 $target =& new SimplePie_IRI('');
11704 $target->set_scheme($base->get_scheme());
11705 $target->set_userinfo($base->get_userinfo());
11706 $target->set_host($base->get_host());
11707 $target->set_port($base->get_port());
11708 if ($relative->get_path() !== null)
11710 if (strpos($relative->get_path(), '/') === 0)
11712 $target->set_path($relative->get_path());
11714 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
11716 $target->set_path('/' . $relative->get_path());
11718 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11720 $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
11724 $target->set_path($relative->get_path());
11726 $target->set_query($relative->get_query());
11730 $target->set_path($base->get_path());
11731 if ($relative->get_query() !== null)
11733 $target->set_query($relative->get_query());
11735 elseif ($base->get_query() !== null)
11737 $target->set_query($base->get_query());
11741 $target->set_fragment($relative->get_fragment());
11745 // No base URL, just return the relative URL
11746 $target = $relative;
11757 * Parse an IRI into scheme/authority/path/query/fragment segments
11760 * @param string $iri
11763 function parse_iri($iri)
11765 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11766 for ($i = count($match); $i <= 9; $i++)
11770 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11774 * Remove dot segments from a path
11777 * @param string $input
11780 function remove_dot_segments($input)
11783 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
11785 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11786 if (strpos($input, '../') === 0)
11788 $input = substr($input, 3);
11790 elseif (strpos($input, './') === 0)
11792 $input = substr($input, 2);
11794 // 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,
11795 elseif (strpos($input, '/./') === 0)
11797 $input = substr_replace($input, '/', 0, 3);
11799 elseif ($input === '/.')
11803 // 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,
11804 elseif (strpos($input, '/../') === 0)
11806 $input = substr_replace($input, '/', 0, 4);
11807 $output = substr_replace($output, '', strrpos($output, '/'));
11809 elseif ($input === '/..')
11812 $output = substr_replace($output, '', strrpos($output, '/'));
11814 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11815 elseif ($input === '.' || $input === '..')
11819 // 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
11820 elseif (($pos = strpos($input, '/', 1)) !== false)
11822 $output .= substr($input, 0, $pos);
11823 $input = substr_replace($input, '', 0, $pos);
11831 return $output . $input;
11835 * Replace invalid character with percent encoding
11838 * @param string $string Input string
11839 * @param string $valid_chars Valid characters
11840 * @param int $case Normalise case
11843 function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
11846 if ($case & SIMPLEPIE_LOWERCASE)
11848 $string = strtolower($string);
11850 elseif ($case & SIMPLEPIE_UPPERCASE)
11852 $string = strtoupper($string);
11855 // Store position and string length (to avoid constantly recalculating this)
11857 $strlen = strlen($string);
11859 // Loop as long as we have invalid characters, advancing the position to the next invalid character
11860 while (($position += strspn($string, $valid_chars, $position)) < $strlen)
11862 // If we have a % character
11863 if ($string[$position] === '%')
11865 // If we have a pct-encoded section
11866 if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
11868 // Get the the represented character
11869 $chr = chr(hexdec(substr($string, $position + 1, 2)));
11871 // If the character is valid, replace the pct-encoded with the actual character while normalising case
11872 if (strpos($valid_chars, $chr) !== false)
11874 if ($case & SIMPLEPIE_LOWERCASE)
11876 $chr = strtolower($chr);
11878 elseif ($case & SIMPLEPIE_UPPERCASE)
11880 $chr = strtoupper($chr);
11882 $string = substr_replace($string, $chr, $position, 3);
11887 // Otherwise just normalise the pct-encoded to uppercase
11890 $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
11894 // If we don't have a pct-encoded section, just replace the % with its own esccaped form
11897 $string = substr_replace($string, '%25', $position, 1);
11902 // If we have an invalid character, change into its pct-encoded form
11905 $replacement = sprintf("%%%02X", ord($string[$position]));
11906 $string = str_replace($string[$position], $replacement, $string);
11907 $strlen = strlen($string);
11914 * Check if the object represents a valid IRI
11919 function is_valid()
11921 return array_sum($this->valid) === count($this->valid);
11925 * Set the scheme. Returns true on success, false on failure (if there are
11926 * any invalid characters).
11929 * @param string $scheme
11932 function set_scheme($scheme)
11934 if ($scheme === null || $scheme === '')
11936 $this->scheme = null;
11940 $len = strlen($scheme);
11944 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
11946 $this->scheme = null;
11947 $this->valid[__FUNCTION__] = false;
11952 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
11954 $this->scheme = null;
11955 $this->valid[__FUNCTION__] = false;
11959 $this->scheme = strtolower($scheme);
11961 $this->valid[__FUNCTION__] = true;
11966 * Set the authority. Returns true on success, false on failure (if there are
11967 * any invalid characters).
11970 * @param string $authority
11973 function set_authority($authority)
11975 if (($userinfo_end = strrpos($authority, '@')) !== false)
11977 $userinfo = substr($authority, 0, $userinfo_end);
11978 $authority = substr($authority, $userinfo_end + 1);
11985 if (($port_start = strpos($authority, ':')) !== false)
11987 $port = substr($authority, $port_start + 1);
11988 $authority = substr($authority, 0, $port_start);
11995 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
11999 * Set the userinfo.
12002 * @param string $userinfo
12005 function set_userinfo($userinfo)
12007 if ($userinfo === null || $userinfo === '')
12009 $this->userinfo = null;
12013 $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
12015 $this->valid[__FUNCTION__] = true;
12020 * Set the host. Returns true on success, false on failure (if there are
12021 * any invalid characters).
12024 * @param string $host
12027 function set_host($host)
12029 if ($host === null || $host === '')
12031 $this->host = null;
12032 $this->valid[__FUNCTION__] = true;
12035 elseif ($host[0] === '[' && substr($host, -1) === ']')
12037 if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
12039 $this->host = $host;
12040 $this->valid[__FUNCTION__] = true;
12045 $this->host = null;
12046 $this->valid[__FUNCTION__] = false;
12052 $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
12053 $this->valid[__FUNCTION__] = true;
12059 * Set the port. Returns true on success, false on failure (if there are
12060 * any invalid characters).
12063 * @param string $port
12066 function set_port($port)
12068 if ($port === null || $port === '')
12070 $this->port = null;
12071 $this->valid[__FUNCTION__] = true;
12074 elseif (strspn($port, '0123456789') === strlen($port))
12076 $this->port = (int) $port;
12077 $this->valid[__FUNCTION__] = true;
12082 $this->port = null;
12083 $this->valid[__FUNCTION__] = false;
12092 * @param string $path
12095 function set_path($path)
12097 if ($path === null || $path === '')
12099 $this->path = null;
12100 $this->valid[__FUNCTION__] = true;
12103 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
12105 $this->path = null;
12106 $this->valid[__FUNCTION__] = false;
12111 $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
12112 if ($this->scheme !== null)
12114 $this->path = $this->remove_dot_segments($this->path);
12116 $this->valid[__FUNCTION__] = true;
12125 * @param string $query
12128 function set_query($query)
12130 if ($query === null || $query === '')
12132 $this->query = null;
12136 $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12138 $this->valid[__FUNCTION__] = true;
12143 * Set the fragment.
12146 * @param string $fragment
12149 function set_fragment($fragment)
12151 if ($fragment === null || $fragment === '')
12153 $this->fragment = null;
12157 $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12159 $this->valid[__FUNCTION__] = true;
12164 * Get the complete IRI
12172 if ($this->scheme !== null)
12174 $iri .= $this->scheme . ':';
12176 if (($authority = $this->get_authority()) !== null)
12178 $iri .= '//' . $authority;
12180 if ($this->path !== null)
12182 $iri .= $this->path;
12184 if ($this->query !== null)
12186 $iri .= '?' . $this->query;
12188 if ($this->fragment !== null)
12190 $iri .= '#' . $this->fragment;
12209 function get_scheme()
12211 return $this->scheme;
12215 * Get the complete authority
12220 function get_authority()
12223 if ($this->userinfo !== null)
12225 $authority .= $this->userinfo . '@';
12227 if ($this->host !== null)
12229 $authority .= $this->host;
12231 if ($this->port !== null)
12233 $authority .= ':' . $this->port;
12236 if ($authority !== '')
12247 * Get the user information
12252 function get_userinfo()
12254 return $this->userinfo;
12263 function get_host()
12265 return $this->host;
12274 function get_port()
12276 return $this->port;
12285 function get_path()
12287 return $this->path;
12296 function get_query()
12298 return $this->query;
12307 function get_fragment()
12309 return $this->fragment;
12314 * Class to validate and to work with IPv6 addresses.
12316 * @package SimplePie
12317 * @copyright 2003-2005 The PHP Group
12318 * @license http://www.opensource.org/licenses/bsd-license.php
12319 * @link http://pear.php.net/package/Net_IPv6
12320 * @author Alexander Merz <alexander.merz@web.de>
12321 * @author elfrink at introweb dot nl
12322 * @author Josh Peck <jmp at joshpeck dot org>
12323 * @author Geoffrey Sneddon <geoffers@gmail.com>
12325 class SimplePie_Net_IPv6
12328 * Removes a possible existing netmask specification of an IP address.
12330 * @param string $ip the (compressed) IP as Hex representation
12331 * @return string the IP the without netmask
12336 function removeNetmaskSpec($ip)
12338 if (strpos($ip, '/') !== false)
12340 list($addr, $nm) = explode('/', $ip);
12350 * Uncompresses an IPv6 address
12352 * RFC 2373 allows you to compress zeros in an address to '::'. This
12353 * function expects an valid IPv6 address and expands the '::' to
12354 * the required zeros.
12356 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
12357 * ::1 -> 0:0:0:0:0:0:0:1
12361 * @param string $ip a valid IPv6-address (hex format)
12362 * @return string the uncompressed IPv6-address (hex format)
12364 function Uncompress($ip)
12366 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
12369 if (strpos($ip, '::') !== false)
12371 list($ip1, $ip2) = explode('::', $ip);
12379 if (($pos = substr_count($ip1, ':')) > 0)
12395 if (($pos = substr_count($ip2, ':')) > 0)
12404 if (strstr($ip2, '.'))
12409 if ($c1 === -1 && $c2 === -1)
12411 $uip = '0:0:0:0:0:0:0:0';
12414 else if ($c1 === -1)
12416 $fill = str_repeat('0:', 7 - $c2);
12417 $uip = str_replace('::', $fill, $uip);
12420 else if ($c2 === -1)
12422 $fill = str_repeat(':0', 7 - $c1);
12423 $uip = str_replace('::', $fill, $uip);
12428 $fill = str_repeat(':0:', 6 - $c2 - $c1);
12429 $uip = str_replace('::', $fill, $uip);
12430 $uip = str_replace('::', ':', $uip);
12437 * Splits an IPv6 address into the IPv6 and a possible IPv4 part
12439 * RFC 2373 allows you to note the last two parts of an IPv6 address as
12440 * an IPv4 compatible address
12442 * Example: 0:0:0:0:0:0:13.1.68.3
12443 * 0:0:0:0:0:FFFF:129.144.52.38
12447 * @param string $ip a valid IPv6-address (hex format)
12448 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
12450 function SplitV64($ip)
12452 $ip = SimplePie_Net_IPv6::Uncompress($ip);
12453 if (strstr($ip, '.'))
12455 $pos = strrpos($ip, ':');
12457 $ipPart = explode('_', $ip);
12462 return array($ip, '');
12467 * Checks an IPv6 address
12469 * Checks if the given IP is IPv6-compatible
12473 * @param string $ip a valid IPv6-address
12474 * @return bool true if $ip is an IPv6 address
12476 function checkIPv6($ip)
12478 $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
12480 if (!empty($ipPart[0]))
12482 $ipv6 = explode(':', $ipPart[0]);
12483 for ($i = 0; $i < count($ipv6); $i++)
12485 $dec = hexdec($ipv6[$i]);
12486 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12487 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12496 elseif ($count === 6 && !empty($ipPart[1]))
12498 $ipv4 = explode('.', $ipPart[1]);
12500 foreach ($ipv4 as $ipv4_part)
12502 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12528 * @package SimplePie
12530 class SimplePie_Parse_Date
12535 * @access protected
12541 * List of days, calendar day name => ordinal day number in the week
12543 * @access protected
12606 'keskiviikko' => 3,
12630 * List of months, calendar month name => calendar month number
12632 * @access protected
12635 var $month = array(
12646 // No long form of May
12775 * List of timezones, abbreviation => offset from UTC
12777 * @access protected
12780 var $timezone = array(
12983 * Cached PCRE for SimplePie_Parse_Date::$day
12985 * @access protected
12991 * Cached PCRE for SimplePie_Parse_Date::$month
12993 * @access protected
12999 * Array of user-added callback methods
13004 var $built_in = array();
13007 * Array of user-added callback methods
13012 var $user = array();
13015 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
13016 * self::month_pcre, and self::built_in
13020 function SimplePie_Parse_Date()
13022 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
13023 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
13026 if (!isset($cache[get_class($this)]))
13028 $all_methods = get_class_methods($this);
13030 foreach ($all_methods as $method)
13032 if (strtolower(substr($method, 0, 5)) === 'date_')
13034 $cache[get_class($this)][] = $method;
13039 foreach ($cache[get_class($this)] as $method)
13041 $this->built_in[] = $method;
13055 $object =& new SimplePie_Parse_Date;
13065 * @param string $date Date to parse
13066 * @return int Timestamp corresponding to date string, or false on failure
13068 function parse($date)
13070 foreach ($this->user as $method)
13072 if (($returned = call_user_func($method, $date)) !== false)
13078 foreach ($this->built_in as $method)
13080 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
13090 * Add a callback method to parse a date
13094 * @param callback $callback
13096 function add_callback($callback)
13098 if (is_callable($callback))
13100 $this->user[] = $callback;
13104 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
13109 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
13110 * well as allowing any of upper or lower case "T", horizontal tabs, or
13111 * spaces to be used as the time seperator (including more than one))
13113 * @access protected
13114 * @return int Timestamp
13116 function date_w3cdtf($date)
13121 $year = '([0-9]{4})';
13122 $month = $day = $hour = $minute = $second = '([0-9]{2})';
13123 $decimal = '([0-9]*)';
13124 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
13125 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
13127 if (preg_match($pcre, $date, $match))
13130 Capturing subpatterns:
13137 7: Decimal fraction of a second
13141 11: Timezone minutes
13144 // Fill in empty matches
13145 for ($i = count($match); $i <= 3; $i++)
13150 for ($i = count($match); $i <= 7; $i++)
13155 // Numeric timezone
13156 if (isset($match[9]) && $match[9] !== '')
13158 $timezone = $match[10] * 3600;
13159 $timezone += $match[11] * 60;
13160 if ($match[9] === '-')
13162 $timezone = 0 - $timezone;
13170 // Convert the number of seconds to an integer, taking decimals into account
13171 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
13173 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
13182 * Remove RFC822 comments
13184 * @access protected
13185 * @param string $data Data to strip comments from
13186 * @return string Comment stripped string
13188 function remove_rfc2822_comments($string)
13190 $string = (string) $string;
13192 $length = strlen($string);
13197 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
13199 $output .= substr($string, $position, $pos - $position);
13200 $position = $pos + 1;
13201 if ($string[$pos - 1] !== '\\')
13204 while ($depth && $position < $length)
13206 $position += strcspn($string, '()', $position);
13207 if ($string[$position - 1] === '\\')
13212 elseif (isset($string[$position]))
13214 switch ($string[$position])
13237 $output .= substr($string, $position);
13243 * Parse RFC2822's date format
13245 * @access protected
13246 * @return int Timestamp
13248 function date_rfc2822($date)
13253 $wsp = '[\x09\x20]';
13254 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
13255 $optional_fws = $fws . '?';
13256 $day_name = $this->day_pcre;
13257 $month = $this->month_pcre;
13258 $day = '([0-9]{1,2})';
13259 $hour = $minute = $second = '([0-9]{2})';
13260 $year = '([0-9]{2,4})';
13261 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
13262 $character_zone = '([A-Z]{1,5})';
13263 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
13264 $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';
13266 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
13269 Capturing subpatterns:
13279 10: Timezone minutes
13280 11: Alphabetic timezone
13283 // Find the month number
13284 $month = $this->month[strtolower($match[3])];
13286 // Numeric timezone
13287 if ($match[8] !== '')
13289 $timezone = $match[9] * 3600;
13290 $timezone += $match[10] * 60;
13291 if ($match[8] === '-')
13293 $timezone = 0 - $timezone;
13296 // Character timezone
13297 elseif (isset($this->timezone[strtoupper($match[11])]))
13299 $timezone = $this->timezone[strtoupper($match[11])];
13301 // Assume everything else to be -0000
13307 // Deal with 2/3 digit years
13308 if ($match[4] < 50)
13312 elseif ($match[4] < 1000)
13317 // Second is optional, if it is empty set it to zero
13318 if ($match[7] !== '')
13320 $second = $match[7];
13327 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
13336 * Parse RFC850's date format
13338 * @access protected
13339 * @return int Timestamp
13341 function date_rfc850($date)
13346 $space = '[\x09\x20]+';
13347 $day_name = $this->day_pcre;
13348 $month = $this->month_pcre;
13349 $day = '([0-9]{1,2})';
13350 $year = $hour = $minute = $second = '([0-9]{2})';
13351 $zone = '([A-Z]{1,5})';
13352 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
13354 if (preg_match($pcre, $date, $match))
13357 Capturing subpatterns:
13369 $month = $this->month[strtolower($match[3])];
13371 // Character timezone
13372 if (isset($this->timezone[strtoupper($match[8])]))
13374 $timezone = $this->timezone[strtoupper($match[8])];
13376 // Assume everything else to be -0000
13382 // Deal with 2 digit year
13383 if ($match[4] < 50)
13392 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
13401 * Parse C99's asctime()'s date format
13403 * @access protected
13404 * @return int Timestamp
13406 function date_asctime($date)
13411 $space = '[\x09\x20]+';
13412 $wday_name = $this->day_pcre;
13413 $mon_name = $this->month_pcre;
13414 $day = '([0-9]{1,2})';
13415 $hour = $sec = $min = '([0-9]{2})';
13416 $year = '([0-9]{4})';
13417 $terminator = '\x0A?\x00?';
13418 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
13420 if (preg_match($pcre, $date, $match))
13423 Capturing subpatterns:
13433 $month = $this->month[strtolower($match[2])];
13434 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
13443 * Parse dates using strtotime()
13445 * @access protected
13446 * @return int Timestamp
13448 function date_strtotime($date)
13450 $strtotime = strtotime($date);
13451 if ($strtotime === -1 || $strtotime === false)
13463 * Content-type sniffing
13465 * @package SimplePie
13467 class SimplePie_Content_Type_Sniffer
13472 * @var SimplePie_File
13478 * Create an instance of the class with the input file
13481 * @param SimplePie_Content_Type_Sniffer $file Input file
13483 function SimplePie_Content_Type_Sniffer($file)
13485 $this->file = $file;
13489 * Get the Content-Type of the specified file
13492 * @return string Actual Content-Type
13494 function get_type()
13496 if (isset($this->file->headers['content-type']))
13498 if (!isset($this->file->headers['content-encoding'])
13499 && ($this->file->headers['content-type'] === 'text/plain'
13500 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
13501 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
13503 return $this->text_or_binary();
13506 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
13508 $official = substr($this->file->headers['content-type'], 0, $pos);
13512 $official = $this->file->headers['content-type'];
13514 $official = strtolower($official);
13516 if ($official === 'unknown/unknown'
13517 || $official === 'application/unknown')
13519 return $this->unknown();
13521 elseif (substr($official, -4) === '+xml'
13522 || $official === 'text/xml'
13523 || $official === 'application/xml')
13527 elseif (substr($official, 0, 6) === 'image/')
13529 if ($return = $this->image())
13538 elseif ($official === 'text/html')
13540 return $this->feed_or_html();
13549 return $this->unknown();
13554 * Sniff text or binary
13557 * @return string Actual Content-Type
13559 function text_or_binary()
13561 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
13562 || substr($this->file->body, 0, 2) === "\xFF\xFE"
13563 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
13564 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
13566 return 'text/plain';
13568 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
13570 return 'application/octect-stream';
13574 return 'text/plain';
13582 * @return string Actual Content-Type
13586 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
13587 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
13588 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
13589 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
13591 return 'text/html';
13593 elseif (substr($this->file->body, 0, 5) === '%PDF-')
13595 return 'application/pdf';
13597 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
13599 return 'application/postscript';
13601 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
13602 || substr($this->file->body, 0, 6) === 'GIF89a')
13604 return 'image/gif';
13606 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13608 return 'image/png';
13610 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13612 return 'image/jpeg';
13614 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13616 return 'image/bmp';
13620 return $this->text_or_binary();
13628 * @return string Actual Content-Type
13632 if (substr($this->file->body, 0, 6) === 'GIF87a'
13633 || substr($this->file->body, 0, 6) === 'GIF89a')
13635 return 'image/gif';
13637 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13639 return 'image/png';
13641 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13643 return 'image/jpeg';
13645 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13647 return 'image/bmp';
13659 * @return string Actual Content-Type
13661 function feed_or_html()
13663 $len = strlen($this->file->body);
13664 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
13666 while ($pos < $len)
13668 switch ($this->file->body[$pos])
13674 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
13682 return 'text/html';
13685 if (substr($this->file->body, $pos, 3) === '!--')
13688 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
13694 return 'text/html';
13697 elseif (substr($this->file->body, $pos, 1) === '!')
13699 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
13705 return 'text/html';
13708 elseif (substr($this->file->body, $pos, 1) === '?')
13710 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
13716 return 'text/html';
13719 elseif (substr($this->file->body, $pos, 3) === 'rss'
13720 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
13722 return 'application/rss+xml';
13724 elseif (substr($this->file->body, $pos, 4) === 'feed')
13726 return 'application/atom+xml';
13730 return 'text/html';
13734 return 'text/html';
13739 * Parses the XML Declaration
13741 * @package SimplePie
13743 class SimplePie_XML_Declaration_Parser
13751 var $version = '1.0';
13759 var $encoding = 'UTF-8';
13767 var $standalone = false;
13770 * Current state of the state machine
13775 var $state = 'before_version_name';
13786 * Input data length (to avoid calling strlen() everytime this is needed)
13791 var $data_length = 0;
13794 * Current position of the pointer
13802 * Create an instance of the class with the input data
13805 * @param string $data Input data
13807 function SimplePie_XML_Declaration_Parser($data)
13809 $this->data = $data;
13810 $this->data_length = strlen($this->data);
13814 * Parse the input data
13817 * @return bool true on success, false on failure
13821 while ($this->state && $this->state !== 'emit' && $this->has_data())
13823 $state = $this->state;
13827 if ($this->state === 'emit')
13833 $this->version = '';
13834 $this->encoding = '';
13835 $this->standalone = '';
13841 * Check whether there is data beyond the pointer
13844 * @return bool true if there is further data, false if not
13846 function has_data()
13848 return (bool) ($this->position < $this->data_length);
13852 * Advance past any whitespace
13854 * @return int Number of whitespace characters passed
13856 function skip_whitespace()
13858 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
13859 $this->position += $whitespace;
13860 return $whitespace;
13866 function get_value()
13868 $quote = substr($this->data, $this->position, 1);
13869 if ($quote === '"' || $quote === "'")
13872 $len = strcspn($this->data, $quote, $this->position);
13873 if ($this->has_data())
13875 $value = substr($this->data, $this->position, $len);
13876 $this->position += $len + 1;
13883 function before_version_name()
13885 if ($this->skip_whitespace())
13887 $this->state = 'version_name';
13891 $this->state = false;
13895 function version_name()
13897 if (substr($this->data, $this->position, 7) === 'version')
13899 $this->position += 7;
13900 $this->skip_whitespace();
13901 $this->state = 'version_equals';
13905 $this->state = false;
13909 function version_equals()
13911 if (substr($this->data, $this->position, 1) === '=')
13914 $this->skip_whitespace();
13915 $this->state = 'version_value';
13919 $this->state = false;
13923 function version_value()
13925 if ($this->version = $this->get_value())
13927 $this->skip_whitespace();
13928 if ($this->has_data())
13930 $this->state = 'encoding_name';
13934 $this->state = 'emit';
13939 $this->state = 'standalone_name';
13943 function encoding_name()
13945 if (substr($this->data, $this->position, 8) === 'encoding')
13947 $this->position += 8;
13948 $this->skip_whitespace();
13949 $this->state = 'encoding_equals';
13953 $this->state = false;
13957 function encoding_equals()
13959 if (substr($this->data, $this->position, 1) === '=')
13962 $this->skip_whitespace();
13963 $this->state = 'encoding_value';
13967 $this->state = false;
13971 function encoding_value()
13973 if ($this->encoding = $this->get_value())
13975 $this->skip_whitespace();
13976 if ($this->has_data())
13978 $this->state = 'standalone_name';
13982 $this->state = 'emit';
13987 $this->state = false;
13991 function standalone_name()
13993 if (substr($this->data, $this->position, 10) === 'standalone')
13995 $this->position += 10;
13996 $this->skip_whitespace();
13997 $this->state = 'standalone_equals';
14001 $this->state = false;
14005 function standalone_equals()
14007 if (substr($this->data, $this->position, 1) === '=')
14010 $this->skip_whitespace();
14011 $this->state = 'standalone_value';
14015 $this->state = false;
14019 function standalone_value()
14021 if ($standalone = $this->get_value())
14023 switch ($standalone)
14026 $this->standalone = true;
14030 $this->standalone = false;
14034 $this->state = false;
14038 $this->skip_whitespace();
14039 if ($this->has_data())
14041 $this->state = false;
14045 $this->state = 'emit';
14050 $this->state = false;
14055 class SimplePie_Locator
14060 var $local = array();
14061 var $elsewhere = array();
14062 var $file_class = 'SimplePie_File';
14063 var $cached_entities = array();
14066 var $base_location = 0;
14067 var $checked_feeds = 0;
14068 var $max_checked_feeds = 10;
14069 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
14071 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
14073 $this->file =& $file;
14074 $this->file_class = $file_class;
14075 $this->useragent = $useragent;
14076 $this->timeout = $timeout;
14077 $this->max_checked_feeds = $max_checked_feeds;
14078 $this->content_type_sniffer_class = $content_type_sniffer_class;
14081 function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
14083 if ($this->is_feed($this->file))
14085 return $this->file;
14088 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14090 $sniffer =& new $this->content_type_sniffer_class($this->file);
14091 if ($sniffer->get_type() !== 'text/html')
14097 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
14102 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
14104 return $working[0];
14107 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
14109 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
14114 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
14119 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
14124 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
14132 function is_feed(&$file)
14134 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14136 $sniffer =& new $this->content_type_sniffer_class($file);
14137 $sniffed = $sniffer->get_type();
14138 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
14147 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
14157 function get_base()
14159 $this->http_base = $this->file->url;
14160 $this->base = $this->http_base;
14161 $elements = SimplePie_Misc::get_element('base', $this->file->body);
14162 foreach ($elements as $element)
14164 if ($element['attribs']['href']['data'] !== '')
14166 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
14167 $this->base_location = $element['offset'];
14173 function autodiscovery()
14175 $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));
14178 foreach ($links as $link)
14180 if ($this->checked_feeds === $this->max_checked_feeds)
14184 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
14186 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
14188 if ($this->base_location < $link['offset'])
14190 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14194 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14197 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]))
14199 $this->checked_feeds++;
14200 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
14201 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))
14203 $feeds[$href] = $feed;
14210 if (!empty($feeds))
14212 return array_values($feeds);
14219 function get_links()
14221 $links = SimplePie_Misc::get_element('a', $this->file->body);
14222 foreach ($links as $link)
14224 if (isset($link['attribs']['href']['data']))
14226 $href = trim($link['attribs']['href']['data']);
14227 $parsed = SimplePie_Misc::parse_url($href);
14228 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
14230 if ($this->base_location < $link['offset'])
14232 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14236 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14239 $current = SimplePie_Misc::parse_url($this->file->url);
14241 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
14243 $this->local[] = $href;
14247 $this->elsewhere[] = $href;
14252 $this->local = array_unique($this->local);
14253 $this->elsewhere = array_unique($this->elsewhere);
14254 if (!empty($this->local) || !empty($this->elsewhere))
14261 function extension(&$array)
14263 foreach ($array as $key => $value)
14265 if ($this->checked_feeds === $this->max_checked_feeds)
14269 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
14271 $this->checked_feeds++;
14272 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14273 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))
14279 unset($array[$key]);
14286 function body(&$array)
14288 foreach ($array as $key => $value)
14290 if ($this->checked_feeds === $this->max_checked_feeds)
14294 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
14296 $this->checked_feeds++;
14297 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14298 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))
14304 unset($array[$key]);
14312 class SimplePie_Parser
14317 var $current_column;
14319 var $separator = ' ';
14320 var $namespace = array('');
14321 var $element = array('');
14322 var $xml_base = array('');
14323 var $xml_base_explicit = array(false);
14324 var $xml_lang = array('');
14325 var $data = array();
14326 var $datas = array(array());
14327 var $current_xhtml_construct = -1;
14330 function parse(&$data, $encoding)
14332 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
14333 if (strtoupper($encoding) === 'US-ASCII')
14335 $this->encoding = 'UTF-8';
14339 $this->encoding = $encoding;
14343 // UTF-32 Big Endian BOM
14344 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
14346 $data = substr($data, 4);
14348 // UTF-32 Little Endian BOM
14349 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
14351 $data = substr($data, 4);
14353 // UTF-16 Big Endian BOM
14354 elseif (substr($data, 0, 2) === "\xFE\xFF")
14356 $data = substr($data, 2);
14358 // UTF-16 Little Endian BOM
14359 elseif (substr($data, 0, 2) === "\xFF\xFE")
14361 $data = substr($data, 2);
14364 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
14366 $data = substr($data, 3);
14369 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
14371 $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
14372 if ($declaration->parse())
14374 $data = substr($data, $pos + 2);
14375 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
14379 $this->error_string = 'SimplePie bug! Please report this!';
14386 static $xml_is_sane = null;
14387 if ($xml_is_sane === null)
14389 $parser_check = xml_parser_create();
14390 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
14391 xml_parser_free($parser_check);
14392 $xml_is_sane = isset($values[0]['value']);
14395 // Create the parser
14398 $xml = xml_parser_create_ns($this->encoding, $this->separator);
14399 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
14400 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
14401 xml_set_object($xml, $this);
14402 xml_set_character_data_handler($xml, 'cdata');
14403 xml_set_element_handler($xml, 'tag_open', 'tag_close');
14406 if (!xml_parse($xml, $data, true))
14408 $this->error_code = xml_get_error_code($xml);
14409 $this->error_string = xml_error_string($this->error_code);
14412 $this->current_line = xml_get_current_line_number($xml);
14413 $this->current_column = xml_get_current_column_number($xml);
14414 $this->current_byte = xml_get_current_byte_index($xml);
14415 xml_parser_free($xml);
14420 libxml_clear_errors();
14421 $xml =& new XMLReader();
14423 while (@$xml->read())
14425 switch ($xml->nodeType)
14428 case constant('XMLReader::END_ELEMENT'):
14429 if ($xml->namespaceURI !== '')
14431 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14435 $tagName = $xml->localName;
14437 $this->tag_close(null, $tagName);
14439 case constant('XMLReader::ELEMENT'):
14440 $empty = $xml->isEmptyElement;
14441 if ($xml->namespaceURI !== '')
14443 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14447 $tagName = $xml->localName;
14449 $attributes = array();
14450 while ($xml->moveToNextAttribute())
14452 if ($xml->namespaceURI !== '')
14454 $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14458 $attrName = $xml->localName;
14460 $attributes[$attrName] = $xml->value;
14462 $this->tag_open(null, $tagName, $attributes);
14465 $this->tag_close(null, $tagName);
14468 case constant('XMLReader::TEXT'):
14470 case constant('XMLReader::CDATA'):
14471 $this->cdata(null, $xml->value);
14475 if ($error = libxml_get_last_error())
14477 $this->error_code = $error->code;
14478 $this->error_string = $error->message;
14479 $this->current_line = $error->line;
14480 $this->current_column = $error->column;
14490 function get_error_code()
14492 return $this->error_code;
14495 function get_error_string()
14497 return $this->error_string;
14500 function get_current_line()
14502 return $this->current_line;
14505 function get_current_column()
14507 return $this->current_column;
14510 function get_current_byte()
14512 return $this->current_byte;
14515 function get_data()
14517 return $this->data;
14520 function tag_open($parser, $tag, $attributes)
14522 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
14524 $attribs = array();
14525 foreach ($attributes as $name => $value)
14527 list($attrib_namespace, $attribute) = $this->split_ns($name);
14528 $attribs[$attrib_namespace][$attribute] = $value;
14531 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
14533 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
14534 $this->xml_base_explicit[] = true;
14538 $this->xml_base[] = end($this->xml_base);
14539 $this->xml_base_explicit[] = end($this->xml_base_explicit);
14542 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
14544 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
14548 $this->xml_lang[] = end($this->xml_lang);
14551 if ($this->current_xhtml_construct >= 0)
14553 $this->current_xhtml_construct++;
14554 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
14556 $this->data['data'] .= '<' . end($this->element);
14557 if (isset($attribs['']))
14559 foreach ($attribs[''] as $name => $value)
14561 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
14564 $this->data['data'] .= '>';
14569 $this->datas[] =& $this->data;
14570 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
14571 $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));
14572 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')
14573 || (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'))
14575 $this->current_xhtml_construct = 0;
14580 function cdata($parser, $cdata)
14582 if ($this->current_xhtml_construct >= 0)
14584 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
14588 $this->data['data'] .= $cdata;
14592 function tag_close($parser, $tag)
14594 if ($this->current_xhtml_construct >= 0)
14596 $this->current_xhtml_construct--;
14597 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')))
14599 $this->data['data'] .= '</' . end($this->element) . '>';
14602 if ($this->current_xhtml_construct === -1)
14604 $this->data =& $this->datas[count($this->datas) - 1];
14605 array_pop($this->datas);
14608 array_pop($this->element);
14609 array_pop($this->namespace);
14610 array_pop($this->xml_base);
14611 array_pop($this->xml_base_explicit);
14612 array_pop($this->xml_lang);
14615 function split_ns($string)
14617 static $cache = array();
14618 if (!isset($cache[$string]))
14620 if ($pos = strpos($string, $this->separator))
14622 static $separator_length;
14623 if (!$separator_length)
14625 $separator_length = strlen($this->separator);
14627 $namespace = substr($string, 0, $pos);
14628 $local_name = substr($string, $pos + $separator_length);
14629 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
14631 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
14634 // Normalize the Media RSS namespaces
14635 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
14637 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
14639 $cache[$string] = array($namespace, $local_name);
14643 $cache[$string] = array('', $string);
14646 return $cache[$string];
14651 * @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
14653 class SimplePie_Sanitize
14659 var $remove_div = true;
14660 var $image_handler = '';
14661 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14662 var $encode_instead_of_strip = false;
14663 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14664 var $strip_comments = false;
14665 var $output_encoding = 'UTF-8';
14666 var $enable_cache = true;
14667 var $cache_location = './cache';
14668 var $cache_name_function = 'md5';
14669 var $cache_class = 'SimplePie_Cache';
14670 var $file_class = 'SimplePie_File';
14672 var $useragent = '';
14673 var $force_fsockopen = false;
14675 var $replace_url_attributes = array(
14678 'blockquote' => 'cite',
14680 'form' => 'action',
14681 'img' => array('longdesc', 'src'),
14687 function remove_div($enable = true)
14689 $this->remove_div = (bool) $enable;
14692 function set_image_handler($page = false)
14696 $this->image_handler = (string) $page;
14700 $this->image_handler = false;
14704 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
14706 if (isset($enable_cache))
14708 $this->enable_cache = (bool) $enable_cache;
14711 if ($cache_location)
14713 $this->cache_location = (string) $cache_location;
14716 if ($cache_name_function)
14718 $this->cache_name_function = (string) $cache_name_function;
14723 $this->cache_class = (string) $cache_class;
14727 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
14731 $this->file_class = (string) $file_class;
14736 $this->timeout = (string) $timeout;
14741 $this->useragent = (string) $useragent;
14744 if ($force_fsockopen)
14746 $this->force_fsockopen = (string) $force_fsockopen;
14750 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
14754 if (is_array($tags))
14756 $this->strip_htmltags = $tags;
14760 $this->strip_htmltags = explode(',', $tags);
14765 $this->strip_htmltags = false;
14769 function encode_instead_of_strip($encode = false)
14771 $this->encode_instead_of_strip = (bool) $encode;
14774 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
14778 if (is_array($attribs))
14780 $this->strip_attributes = $attribs;
14784 $this->strip_attributes = explode(',', $attribs);
14789 $this->strip_attributes = false;
14793 function strip_comments($strip = false)
14795 $this->strip_comments = (bool) $strip;
14798 function set_output_encoding($encoding = 'UTF-8')
14800 $this->output_encoding = (string) $encoding;
14804 * Set element/attribute key/value pairs of HTML attributes
14805 * containing URLs that need to be resolved relative to the feed
14809 * @param array $element_attribute Element/attribute key/value pairs
14811 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'))
14813 $this->replace_url_attributes = (array) $element_attribute;
14816 function sanitize($data, $type, $base = '')
14818 $data = trim($data);
14819 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
14821 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
14823 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))
14825 $type |= SIMPLEPIE_CONSTRUCT_HTML;
14829 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
14833 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
14835 $data = base64_decode($data);
14838 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
14840 if ($this->remove_div)
14842 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
14843 $data = preg_replace('/<\/div>$/', '', $data);
14847 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
14851 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
14854 if ($this->strip_comments)
14856 $data = SimplePie_Misc::strip_comments($data);
14859 // Strip out HTML tags and attributes that might cause various security problems.
14860 // Based on recommendations by Mark Pilgrim at:
14861 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
14862 if ($this->strip_htmltags)
14864 foreach ($this->strip_htmltags as $tag)
14866 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
14867 while (preg_match($pcre, $data))
14869 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
14874 if ($this->strip_attributes)
14876 foreach ($this->strip_attributes as $attrib)
14878 $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);
14882 // Replace relative URLs
14883 $this->base = $base;
14884 foreach ($this->replace_url_attributes as $element => $attributes)
14886 $data = $this->replace_urls($data, $element, $attributes);
14889 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
14890 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
14892 $images = SimplePie_Misc::get_element('img', $data);
14893 foreach ($images as $img)
14895 if (isset($img['attribs']['src']['data']))
14897 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
14898 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
14900 if ($cache->load())
14902 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14903 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14907 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
14908 $headers = $file->headers;
14910 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
14912 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
14914 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14915 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14919 trigger_error("$this->cache_location is not writeable", E_USER_WARNING);
14927 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
14928 $data = trim($data);
14931 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
14933 $data = SimplePie_Misc::absolutize_url($data, $base);
14936 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
14938 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
14941 if ($this->output_encoding !== 'UTF-8')
14943 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
14949 function replace_urls($data, $tag, $attributes)
14951 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
14953 $elements = SimplePie_Misc::get_element($tag, $data);
14954 foreach ($elements as $element)
14956 if (is_array($attributes))
14958 foreach ($attributes as $attribute)
14960 if (isset($element['attribs'][$attribute]['data']))
14962 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
14963 $new_element = SimplePie_Misc::element_implode($element);
14964 $data = str_replace($element['full'], $new_element, $data);
14965 $element['full'] = $new_element;
14969 elseif (isset($element['attribs'][$attributes]['data']))
14971 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
14972 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
14979 function do_strip_htmltags($match)
14981 if ($this->encode_instead_of_strip)
14983 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
14985 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
14986 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
14987 return "<$match[1]$match[2]>$match[3]</$match[1]>";
14991 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
14994 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))