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-2007, 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-2007 Ryan Parman, Geoffrey Sneddon
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 define('SIMPLEPIE_NAME', 'SimplePie');
54 define('SIMPLEPIE_VERSION', '1.1');
59 define('SIMPLEPIE_BUILD', 20080102221556);
62 * SimplePie Website URL
64 define('SIMPLEPIE_URL', 'http://simplepie.org');
68 * @see SimplePie::set_useragent()
70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
79 * @see SimplePie::set_autodiscovery_level()
81 define('SIMPLEPIE_LOCATOR_NONE', 0);
84 * Feed Link Element Autodiscovery
85 * @see SimplePie::set_autodiscovery_level()
87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
90 * Local Feed Extension Autodiscovery
91 * @see SimplePie::set_autodiscovery_level()
93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
96 * Local Feed Body Autodiscovery
97 * @see SimplePie::set_autodiscovery_level()
99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
102 * Remote Feed Extension Autodiscovery
103 * @see SimplePie::set_autodiscovery_level()
105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
108 * Remote Feed Body Autodiscovery
109 * @see SimplePie::set_autodiscovery_level()
111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
114 * All Feed Autodiscovery
115 * @see SimplePie::set_autodiscovery_level()
117 define('SIMPLEPIE_LOCATOR_ALL', 31);
122 define('SIMPLEPIE_TYPE_NONE', 0);
127 define('SIMPLEPIE_TYPE_RSS_090', 1);
130 * RSS 0.91 (Netscape)
132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
135 * RSS 0.91 (Userland)
137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
140 * RSS 0.91 (both Netscape and Userland)
142 define('SIMPLEPIE_TYPE_RSS_091', 6);
147 define('SIMPLEPIE_TYPE_RSS_092', 8);
152 define('SIMPLEPIE_TYPE_RSS_093', 16);
157 define('SIMPLEPIE_TYPE_RSS_094', 32);
162 define('SIMPLEPIE_TYPE_RSS_10', 64);
167 define('SIMPLEPIE_TYPE_RSS_20', 128);
172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
175 * Non-RDF-based RSS (truly intended as syndication format)
177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
202 define('SIMPLEPIE_TYPE_ALL', 1023);
207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
225 * base64-encoded construct
227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
235 * A construct that might be HTML
237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
245 * PCRE for HTML attributes
247 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
250 * PCRE for XML attributes
252 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
257 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
262 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
267 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
272 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
277 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
282 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
285 * RSS 1.0 Content Module Namespace
287 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
292 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
297 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
300 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
302 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
307 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
310 * Media RSS Namespace
312 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
315 * iTunes RSS Namespace
317 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
322 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
325 * IANA Link Relations Registry
327 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
330 * Whether we're running on PHP5
332 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
337 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
342 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
347 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
350 * fsockopen() file source
352 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
357 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
360 * file_get_contents() file source
362 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
368 * @version "Razzleberry"
369 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
370 * @author Ryan Parman
371 * @author Geoffrey Sneddon
372 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
377 * @var array Raw data
383 * @var mixed Error string
389 * @var object Instance of SimplePie_Sanitize (or other class)
390 * @see SimplePie::set_sanitize_class()
396 * @var string SimplePie Useragent
397 * @see SimplePie::set_useragent()
400 var $useragent = SIMPLEPIE_USERAGENT;
403 * @var string Feed URL
404 * @see SimplePie::set_feed_url()
410 * @var object Instance of SimplePie_File to use as a feed
411 * @see SimplePie::set_file()
417 * @var string Raw feed data
418 * @see SimplePie::set_raw_data()
424 * @var int Timeout for fetching remote files
425 * @see SimplePie::set_timeout()
431 * @var bool Forces fsockopen() to be used for remote files instead
432 * of cURL, even if a new enough version is installed
433 * @see SimplePie::force_fsockopen()
436 var $force_fsockopen = false;
439 * @var bool Force the given data/URL to be treated as a feed no matter what
441 * @see SimplePie::force_feed()
444 var $force_feed = false;
447 * @var bool Enable/Disable XML dump
448 * @see SimplePie::enable_xml_dump()
451 var $xml_dump = false;
454 * @var bool Enable/Disable Caching
455 * @see SimplePie::enable_cache()
461 * @var int Cache duration (in seconds)
462 * @see SimplePie::set_cache_duration()
465 var $cache_duration = 3600;
468 * @var int Auto-discovery cache duration (in seconds)
469 * @see SimplePie::set_autodiscovery_cache_duration()
472 var $autodiscovery_cache_duration = 604800; // 7 Days.
475 * @var string Cache location (relative to executing script)
476 * @see SimplePie::set_cache_location()
479 var $cache_location = './cache';
482 * @var string Function that creates the cache filename
483 * @see SimplePie::set_cache_name_function()
486 var $cache_name_function = 'md5';
489 * @var bool Reorder feed by date descending
490 * @see SimplePie::enable_order_by_date()
493 var $order_by_date = true;
496 * @var mixed Force input encoding to be set to the follow value
497 * (false, or anything type-cast to false, disables this feature)
498 * @see SimplePie::set_input_encoding()
501 var $input_encoding = false;
504 * @var int Feed Autodiscovery Level
505 * @see SimplePie::set_autodiscovery_level()
508 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
511 * @var string Class used for caching feeds
512 * @see SimplePie::set_cache_class()
515 var $cache_class = 'SimplePie_Cache';
518 * @var string Class used for locating feeds
519 * @see SimplePie::set_locator_class()
522 var $locator_class = 'SimplePie_Locator';
525 * @var string Class used for parsing feeds
526 * @see SimplePie::set_parser_class()
529 var $parser_class = 'SimplePie_Parser';
532 * @var string Class used for fetching feeds
533 * @see SimplePie::set_file_class()
536 var $file_class = 'SimplePie_File';
539 * @var string Class used for items
540 * @see SimplePie::set_item_class()
543 var $item_class = 'SimplePie_Item';
546 * @var string Class used for authors
547 * @see SimplePie::set_author_class()
550 var $author_class = 'SimplePie_Author';
553 * @var string Class used for categories
554 * @see SimplePie::set_category_class()
557 var $category_class = 'SimplePie_Category';
560 * @var string Class used for enclosures
561 * @see SimplePie::set_enclosures_class()
564 var $enclosure_class = 'SimplePie_Enclosure';
567 * @var string Class used for Media RSS <media:text> captions
568 * @see SimplePie::set_caption_class()
571 var $caption_class = 'SimplePie_Caption';
574 * @var string Class used for Media RSS <media:copyright>
575 * @see SimplePie::set_copyright_class()
578 var $copyright_class = 'SimplePie_Copyright';
581 * @var string Class used for Media RSS <media:credit>
582 * @see SimplePie::set_credit_class()
585 var $credit_class = 'SimplePie_Credit';
588 * @var string Class used for Media RSS <media:rating>
589 * @see SimplePie::set_rating_class()
592 var $rating_class = 'SimplePie_Rating';
595 * @var string Class used for Media RSS <media:restriction>
596 * @see SimplePie::set_restriction_class()
599 var $restriction_class = 'SimplePie_Restriction';
602 * @var string Class used for content-type sniffing
603 * @see SimplePie::set_content_type_sniffer_class()
606 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
609 * @var string Class used for item sources.
610 * @see SimplePie::set_source_class()
613 var $source_class = 'SimplePie_Source';
616 * @var mixed Set javascript query string parameter (false, or
617 * anything type-cast to false, disables this feature)
618 * @see SimplePie::set_javascript()
621 var $javascript = 'js';
624 * @var int Maximum number of feeds to check with autodiscovery
625 * @see SimplePie::set_max_checked_feeds()
628 var $max_checked_feeds = 10;
631 * @var string Web-accessible path to the handler_favicon.php file.
632 * @see SimplePie::set_favicon_handler()
635 var $favicon_handler = '';
638 * @var string Web-accessible path to the handler_image.php file.
639 * @see SimplePie::set_image_handler()
642 var $image_handler = '';
645 * @var array Stores the URLs when multiple feeds are being initialized.
646 * @see SimplePie::set_feed_url()
649 var $multifeed_url = array();
652 * @var array Stores SimplePie objects when multiple feeds initialized.
655 var $multifeed_objects = array();
658 * @var array Stores the get_object_vars() array for use with multifeeds.
659 * @see SimplePie::set_feed_url()
662 var $config_settings = null;
665 * @var integer Stores the number of items to return per-feed with multifeeds.
666 * @see SimplePie::set_item_limit()
672 * @var array Stores the default attributes to be stripped by strip_attributes().
673 * @see SimplePie::strip_attributes()
676 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
679 * @var array Stores the default tags to be stripped by strip_htmltags().
680 * @see SimplePie::strip_htmltags()
683 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
686 * The SimplePie class contains feed level data and options
688 * There are two ways that you can create a new SimplePie object. The first
689 * is by passing a feed URL as a parameter to the SimplePie constructor
690 * (as well as optionally setting the cache location and cache expiry). This
691 * will initialise the whole feed with all of the default settings, and you
692 * can begin accessing methods and properties immediately.
694 * The second way is to create the SimplePie object with no parameters
695 * at all. This will enable you to set configuration options. After setting
696 * them, you must initialise the feed using $feed->init(). At that point the
697 * object's methods and properties will be available to you. This format is
698 * what is used throughout this documentation.
701 * @since 1.0 Preview Release
702 * @param string $feed_url This is the URL you want to parse.
703 * @param string $cache_location This is where you want the cache to be stored.
704 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
706 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
708 // Other objects, instances created here so we can set options on them
709 $this->sanitize =& new SimplePie_Sanitize;
711 // Set options if they're passed to the constructor
712 if ($cache_location !== null)
714 $this->set_cache_location($cache_location);
717 if ($cache_duration !== null)
719 $this->set_cache_duration($cache_duration);
722 // Only init the script if we're passed a feed URL
723 if ($feed_url !== null)
725 $this->set_feed_url($feed_url);
731 * Used for converting object to a string
733 function __toString()
735 return md5(serialize($this->data));
739 * Remove items that link back to this before destroying this object
741 function __destruct()
743 if (!empty($this->data['items']))
745 foreach ($this->data['items'] as $item)
749 unset($this->data['items']);
751 if (!empty($this->data['ordered_items']))
753 foreach ($this->data['ordered_items'] as $item)
757 unset($this->data['ordered_items']);
762 * Force the given data/URL to be treated as a feed no matter what it
767 * @param bool $enable Force the given data/URL to be treated as a feed
769 function force_feed($enable = false)
771 $this->force_feed = (bool) $enable;
775 * This is the URL of the feed you want to parse.
777 * This allows you to enter the URL of the feed you want to parse, or the
778 * website you want to try to use auto-discovery on. This takes priority
779 * over any set raw data.
781 * You can set multiple feeds to mash together by passing an array instead
782 * of a string for the $url. Remember that with each additional feed comes
783 * additional processing and resources.
786 * @since 1.0 Preview Release
787 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
788 * @see SimplePie::set_raw_data()
790 function set_feed_url($url)
794 $this->multifeed_url = array();
795 foreach ($url as $value)
797 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
802 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
807 * Provides an instance of SimplePie_File to use as a feed
810 * @param object &$file Instance of SimplePie_File (or subclass)
811 * @return bool True on success, false on failure
813 function set_file(&$file)
815 if (is_a($file, 'SimplePie_File'))
817 $this->feed_url = $file->url;
818 $this->file =& $file;
825 * Allows you to use a string of RSS/Atom data instead of a remote feed.
827 * If you have a feed available as a string in PHP, you can tell SimplePie
828 * to parse that data string instead of a remote feed. Any set feed URL
833 * @param string $data RSS or Atom data as a string.
834 * @see SimplePie::set_feed_url()
836 function set_raw_data($data)
838 $this->raw_data = trim($data);
842 * Allows you to override the default timeout for fetching remote feeds.
844 * This allows you to change the maximum time the feed's server to respond
845 * and send the feed back.
849 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
851 function set_timeout($timeout = 10)
853 $this->timeout = (int) $timeout;
857 * Forces SimplePie to use fsockopen() instead of the preferred cURL
862 * @param bool $enable Force fsockopen() to be used
864 function force_fsockopen($enable = false)
866 $this->force_fsockopen = (bool) $enable;
870 * Outputs the raw XML content of the feed, after it has gone through
871 * SimplePie's filters.
873 * Used only for debugging, this function will output the XML content as
874 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
875 * before trying to parse it. Many parts of the feed are re-written in
876 * memory, and in the end, you have a parsable feed. XML dump shows you the
877 * actual XML that SimplePie tries to parse, which may or may not be very
878 * different from the original feed.
881 * @since 1.0 Preview Release
882 * @param bool $enable Enable XML dump
884 function enable_xml_dump($enable = false)
886 $this->xml_dump = (bool) $enable;
890 * Enables/disables caching in SimplePie.
892 * This option allows you to disable caching all-together in SimplePie.
893 * However, disabling the cache can lead to longer load times.
896 * @since 1.0 Preview Release
897 * @param bool $enable Enable caching
899 function enable_cache($enable = true)
901 $this->cache = (bool) $enable;
905 * Set the length of time (in seconds) that the contents of a feed
909 * @param int $seconds The feed content cache duration.
911 function set_cache_duration($seconds = 3600)
913 $this->cache_duration = (int) $seconds;
917 * Set the length of time (in seconds) that the autodiscovered feed
918 * URL will be cached.
921 * @param int $seconds The autodiscovered feed URL cache duration.
923 function set_autodiscovery_cache_duration($seconds = 604800)
925 $this->autodiscovery_cache_duration = (int) $seconds;
929 * Set the file system location where the cached files should be stored.
932 * @param string $location The file system location.
934 function set_cache_location($location = './cache')
936 $this->cache_location = (string) $location;
940 * Determines whether feed items should be sorted into reverse chronological order.
943 * @param bool $enable Sort as reverse chronological order.
945 function enable_order_by_date($enable = true)
947 $this->order_by_date = (bool) $enable;
951 * Allows you to override the character encoding reported by the feed.
954 * @param string $encoding Character encoding.
956 function set_input_encoding($encoding = false)
960 $this->input_encoding = (string) $encoding;
964 $this->input_encoding = false;
969 * Set how much feed autodiscovery to do
972 * @see SIMPLEPIE_LOCATOR_NONE
973 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
974 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
975 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
976 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
977 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
978 * @see SIMPLEPIE_LOCATOR_ALL
979 * @param int $level Feed Autodiscovery Level (level can be a
980 * combination of the above constants, see bitwise OR operator)
982 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
984 $this->autodiscovery = (int) $level;
988 * Allows you to change which class SimplePie uses for caching.
989 * Useful when you are overloading or extending SimplePie's default classes.
992 * @param string $class Name of custom class.
993 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
994 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
996 function set_cache_class($class = 'SimplePie_Cache')
998 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1000 $this->cache_class = $class;
1007 * Allows you to change which class SimplePie uses for auto-discovery.
1008 * Useful when you are overloading or extending SimplePie's default classes.
1011 * @param string $class Name of custom class.
1012 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1013 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1015 function set_locator_class($class = 'SimplePie_Locator')
1017 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1019 $this->locator_class = $class;
1026 * Allows you to change which class SimplePie uses for XML parsing.
1027 * Useful when you are overloading or extending SimplePie's default classes.
1030 * @param string $class Name of custom class.
1031 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1032 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1034 function set_parser_class($class = 'SimplePie_Parser')
1036 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1038 $this->parser_class = $class;
1045 * Allows you to change which class SimplePie uses for remote file fetching.
1046 * Useful when you are overloading or extending SimplePie's default classes.
1049 * @param string $class Name of custom class.
1050 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1051 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1053 function set_file_class($class = 'SimplePie_File')
1055 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1057 $this->file_class = $class;
1064 * Allows you to change which class SimplePie uses for data sanitization.
1065 * Useful when you are overloading or extending SimplePie's default classes.
1068 * @param string $class Name of custom class.
1069 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1070 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1072 function set_sanitize_class($class = 'SimplePie_Sanitize')
1074 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1076 $this->sanitize =& new $class;
1083 * Allows you to change which class SimplePie uses for handling feed items.
1084 * Useful when you are overloading or extending SimplePie's default classes.
1087 * @param string $class Name of custom class.
1088 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1089 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1091 function set_item_class($class = 'SimplePie_Item')
1093 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1095 $this->item_class = $class;
1102 * Allows you to change which class SimplePie uses for handling author data.
1103 * Useful when you are overloading or extending SimplePie's default classes.
1106 * @param string $class Name of custom class.
1107 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1108 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1110 function set_author_class($class = 'SimplePie_Author')
1112 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1114 $this->author_class = $class;
1121 * Allows you to change which class SimplePie uses for handling category data.
1122 * Useful when you are overloading or extending SimplePie's default classes.
1125 * @param string $class Name of custom class.
1126 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1127 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1129 function set_category_class($class = 'SimplePie_Category')
1131 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1133 $this->category_class = $class;
1140 * Allows you to change which class SimplePie uses for feed enclosures.
1141 * Useful when you are overloading or extending SimplePie's default classes.
1144 * @param string $class Name of custom class.
1145 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1146 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1148 function set_enclosure_class($class = 'SimplePie_Enclosure')
1150 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1152 $this->enclosure_class = $class;
1159 * Allows you to change which class SimplePie uses for <media:text> captions
1160 * Useful when you are overloading or extending SimplePie's default classes.
1163 * @param string $class Name of custom class.
1164 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1165 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1167 function set_caption_class($class = 'SimplePie_Caption')
1169 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1171 $this->caption_class = $class;
1178 * Allows you to change which class SimplePie uses for <media:copyright>
1179 * Useful when you are overloading or extending SimplePie's default classes.
1182 * @param string $class Name of custom class.
1183 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1184 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1186 function set_copyright_class($class = 'SimplePie_Copyright')
1188 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1190 $this->copyright_class = $class;
1197 * Allows you to change which class SimplePie uses for <media:credit>
1198 * Useful when you are overloading or extending SimplePie's default classes.
1201 * @param string $class Name of custom class.
1202 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1203 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1205 function set_credit_class($class = 'SimplePie_Credit')
1207 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1209 $this->credit_class = $class;
1216 * Allows you to change which class SimplePie uses for <media:rating>
1217 * Useful when you are overloading or extending SimplePie's default classes.
1220 * @param string $class Name of custom class.
1221 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1222 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1224 function set_rating_class($class = 'SimplePie_Rating')
1226 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1228 $this->rating_class = $class;
1235 * Allows you to change which class SimplePie uses for <media:restriction>
1236 * Useful when you are overloading or extending SimplePie's default classes.
1239 * @param string $class Name of custom class.
1240 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1241 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1243 function set_restriction_class($class = 'SimplePie_Restriction')
1245 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1247 $this->restriction_class = $class;
1254 * Allows you to change which class SimplePie uses for content-type sniffing.
1255 * Useful when you are overloading or extending SimplePie's default classes.
1258 * @param string $class Name of custom class.
1259 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1260 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1262 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1264 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1266 $this->content_type_sniffer_class = $class;
1273 * Allows you to change which class SimplePie uses item sources.
1274 * Useful when you are overloading or extending SimplePie's default classes.
1277 * @param string $class Name of custom class.
1278 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1279 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1281 function set_source_class($class = 'SimplePie_Source')
1283 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1285 $this->source_class = $class;
1292 * Allows you to override the default user agent string.
1295 * @param string $ua New user agent string.
1297 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1299 $this->useragent = (string) $ua;
1303 * Set callback function to create cache filename with
1306 * @param mixed $function Callback function
1308 function set_cache_name_function($function = 'md5')
1310 if (is_callable($function))
1312 $this->cache_name_function = $function;
1317 * Set javascript query string parameter
1320 * @param mixed $get Javascript query string parameter
1322 function set_javascript($get = 'js')
1326 $this->javascript = (string) $get;
1330 $this->javascript = false;
1335 * Set options to make SP as fast as possible. Forgoes a
1336 * substantial amount of data sanitization in favor of speed.
1339 * @param bool $set Whether to set them or not
1341 function set_stupidly_fast($set = false)
1345 $this->enable_order_by_date(false);
1346 $this->remove_div(false);
1347 $this->strip_comments(false);
1348 $this->strip_htmltags(false);
1349 $this->strip_attributes(false);
1350 $this->set_image_handler(false);
1355 * Set maximum number of feeds to check with autodiscovery
1358 * @param int $max Maximum number of feeds to check
1360 function set_max_checked_feeds($max = 10)
1362 $this->max_checked_feeds = (int) $max;
1365 function remove_div($enable = true)
1367 $this->sanitize->remove_div($enable);
1370 function strip_htmltags($tags = '', $encode = null)
1374 $tags = $this->strip_htmltags;
1376 $this->sanitize->strip_htmltags($tags);
1377 if ($encode !== null)
1379 $this->sanitize->encode_instead_of_strip($tags);
1383 function encode_instead_of_strip($enable = true)
1385 $this->sanitize->encode_instead_of_strip($enable);
1388 function strip_attributes($attribs = '')
1390 if ($attribs === '')
1392 $attribs = $this->strip_attributes;
1394 $this->sanitize->strip_attributes($attribs);
1397 function set_output_encoding($encoding = 'UTF-8')
1399 $this->sanitize->set_output_encoding($encoding);
1402 function strip_comments($strip = false)
1404 $this->sanitize->strip_comments($strip);
1408 * Set element/attribute key/value pairs of HTML attributes
1409 * containing URLs that need to be resolved relative to the feed
1413 * @param array $element_attribute Element/attribute key/value pairs
1415 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'))
1417 $this->sanitize->set_url_replacements($element_attribute);
1421 * Set the handler to enable the display of cached favicons.
1424 * @param str $page Web-accessible path to the handler_favicon.php file.
1425 * @param str $qs The query string that the value should be passed to.
1427 function set_favicon_handler($page = false, $qs = 'i')
1431 $this->favicon_handler = $page . '?' . $qs . '=';
1435 $this->favicon_handler = '';
1440 * Set the handler to enable the display of cached images.
1443 * @param str $page Web-accessible path to the handler_image.php file.
1444 * @param str $qs The query string that the value should be passed to.
1446 function set_image_handler($page = false, $qs = 'i')
1450 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1454 $this->image_handler = '';
1459 * Set the limit for items returned per-feed with multifeeds.
1462 * @param integer $limit The maximum number of items to return.
1464 function set_item_limit($limit = 0)
1466 $this->item_limit = (int) $limit;
1471 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1475 if (isset($_GET[$this->javascript]))
1477 if (function_exists('ob_gzhandler'))
1479 ob_start('ob_gzhandler');
1481 header('Content-type: text/javascript; charset: UTF-8');
1482 header('Cache-Control: must-revalidate');
1483 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1485 function embed_odeo(link) {
1486 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>');
1489 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1490 if (placeholder != '') {
1491 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>');
1494 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>');
1498 function embed_flash(bgcolor, width, height, link, loop, type) {
1499 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>');
1502 function embed_flv(width, height, link, placeholder, loop, player) {
1503 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>');
1506 function embed_wmedia(width, height, link) {
1507 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1513 // Pass whatever was set with config options over to the sanitizer.
1514 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1515 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1517 if ($this->feed_url !== null || $this->raw_data !== null)
1519 $this->data = array();
1520 $this->multifeed_objects = array();
1523 if ($this->feed_url !== null)
1525 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1526 // Decide whether to enable caching
1527 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1529 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1531 // If it's enabled and we don't want an XML dump, use the cache
1532 if ($cache && !$this->xml_dump)
1535 $this->data = $cache->load();
1536 if (!empty($this->data))
1538 // If the cache is for an outdated build of SimplePie
1539 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1542 $this->data = array();
1544 // If we've hit a collision just rerun it with caching disabled
1545 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1548 $this->data = array();
1550 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1551 elseif (isset($this->data['feed_url']))
1553 // If the autodiscovery cache is still valid use it.
1554 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1556 // Do not need to do feed autodiscovery yet.
1557 if ($this->data['feed_url'] == $this->data['url'])
1560 $this->data = array();
1564 $this->set_feed_url($this->data['feed_url']);
1565 return $this->init();
1569 // Check if the cache has been updated
1570 elseif ($cache->mtime() + $this->cache_duration < time())
1572 // If we have last-modified and/or etag set
1573 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1576 if (isset($this->data['headers']['last-modified']))
1578 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1580 if (isset($this->data['headers']['etag']))
1582 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1584 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1587 if ($file->status_code == 304)
1594 $headers = $file->headers;
1603 // If the cache is still valid, just return true
1609 // If the cache is empty, delete it
1613 $this->data = array();
1616 // 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.
1619 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1621 $file =& $this->file;
1625 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1628 // If the file connection has an error, set SimplePie::error to that and quit
1629 if (!$file->success)
1631 $this->error = $file->error;
1632 if (!empty($this->data))
1642 if (!$this->force_feed)
1644 // Check if the supplied URL is a feed, if it isn't, look for it.
1645 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1646 if (!$locate->is_feed($file))
1648 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1650 if ($file = $locate->find($this->autodiscovery))
1654 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1655 if (!$cache->save($this))
1657 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1659 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1661 $this->feed_url = $file->url;
1665 $this->error = "A feed could not be found at $this->feed_url";
1666 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1673 $headers = $file->headers;
1674 $data = $file->body;
1675 $sniffer = new $this->content_type_sniffer_class($file);
1676 $sniffed = $sniffer->get_type();
1680 $data = $this->raw_data;
1683 // Set up array of possible encodings
1684 $encodings = array();
1686 // First check to see if input has been overridden.
1687 if ($this->input_encoding !== false)
1689 $encodings[] = $this->input_encoding;
1692 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1693 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1695 // RFC 3023 (only applies to sniffed content)
1696 if (isset($sniffed))
1698 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1700 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1702 $encodings[] = strtoupper($charset[1]);
1704 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1705 $encodings[] = 'UTF-8';
1707 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1709 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1711 $encodings[] = $charset[1];
1713 $encodings[] = 'US-ASCII';
1715 // Text MIME-type default
1716 elseif (substr($sniffed, 0, 5) === 'text/')
1718 $encodings[] = 'US-ASCII';
1722 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1723 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1724 $encodings[] = 'UTF-8';
1725 $encodings[] = 'ISO-8859-1';
1727 // There's no point in trying an encoding twice
1728 $encodings = array_unique($encodings);
1730 // If we want the XML, just output that with the most likely encoding and quit
1731 if ($this->xml_dump)
1733 header('Content-type: text/xml; charset=' . $encodings[0]);
1738 // Loop through each possible encoding, till we return something, or run out of possibilities
1739 foreach ($encodings as $encoding)
1741 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1742 $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1744 // Create new parser
1745 $parser =& new $this->parser_class();
1747 // If it's parsed fine
1748 if ($parser->parse($utf8_data, 'UTF-8'))
1750 $this->data = $parser->get_data();
1751 if (isset($this->data['child']))
1753 if (isset($headers))
1755 $this->data['headers'] = $headers;
1757 $this->data['build'] = SIMPLEPIE_BUILD;
1759 // Cache the file if caching is enabled
1760 if ($cache && !$cache->save($this))
1762 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1768 $this->error = "A feed could not be found at $this->feed_url";
1769 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1774 // We have an error, just set SimplePie::error to it and quit
1775 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1776 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1779 elseif (!empty($this->multifeed_url))
1783 $this->multifeed_objects = array();
1784 foreach ($this->multifeed_url as $url)
1788 // This keyword needs to defy coding standards for PHP4 compatibility
1789 $this->multifeed_objects[$i] = clone($this);
1793 $this->multifeed_objects[$i] = $this;
1795 $this->multifeed_objects[$i]->set_feed_url($url);
1796 $success |= $this->multifeed_objects[$i]->init();
1799 return (bool) $success;
1808 * Return the error message for the occured error
1811 * @return string Error message
1815 return $this->error;
1818 function get_encoding()
1820 return $this->sanitize->output_encoding;
1823 function handle_content_type($mime = 'text/html')
1825 if (!headers_sent())
1827 $header = "Content-type: $mime;";
1828 if ($this->get_encoding())
1830 $header .= ' charset=' . $this->get_encoding();
1834 $header .= ' charset=UTF-8';
1842 if (!isset($this->data['type']))
1844 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1845 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1847 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1849 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1851 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1853 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1855 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1856 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1857 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1858 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1860 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1862 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1863 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1864 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1865 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1867 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1870 elseif (isset($this->data['child']['']['rss']))
1872 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1873 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1875 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1878 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1879 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1881 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1884 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1888 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1895 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1899 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1907 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1914 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1917 return $this->data['type'];
1921 * Returns the URL for the favicon of the feed's website.
1923 * @todo Cache atom:icon
1927 function get_favicon()
1929 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1931 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1933 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1935 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1937 if ($this->cache && $this->favicon_handler)
1939 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1940 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1944 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1948 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1950 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1952 $sniffer = new $this->content_type_sniffer_class($file);
1953 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1955 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1957 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1961 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1962 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1970 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1977 * @todo If we have a perm redirect we should return the new URL
1978 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1979 * @todo Also, |atom:link|@rel=self
1981 function subscribe_url()
1983 if ($this->feed_url !== null)
1985 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1993 function subscribe_feed()
1995 if ($this->feed_url !== null)
1997 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2005 function subscribe_outlook()
2007 if ($this->feed_url !== null)
2009 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2017 function subscribe_podcast()
2019 if ($this->feed_url !== null)
2021 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2029 function subscribe_itunes()
2031 if ($this->feed_url !== null)
2033 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2042 * Creates the subscribe_* methods' return data
2045 * @param string $feed_url String to prefix to the feed URL
2046 * @param string $site_url String to prefix to the site URL (and
2047 * suffix to the feed URL)
2048 * @return mixed URL if feed exists, false otherwise
2050 function subscribe_service($feed_url, $site_url = null)
2052 if ($this->subscribe_url())
2054 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2055 if ($site_url !== null && $this->get_link() !== null)
2057 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2067 function subscribe_aol()
2069 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2072 function subscribe_bloglines()
2074 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2077 function subscribe_eskobo()
2079 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2082 function subscribe_feedfeeds()
2084 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2087 function subscribe_feedster()
2089 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2092 function subscribe_google()
2094 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2097 function subscribe_gritwire()
2099 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2102 function subscribe_msn()
2104 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2107 function subscribe_netvibes()
2109 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2112 function subscribe_newsburst()
2114 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2117 function subscribe_newsgator()
2119 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2122 function subscribe_odeo()
2124 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2127 function subscribe_podnova()
2129 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2132 function subscribe_rojo()
2134 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2137 function subscribe_yahoo()
2139 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2142 function get_feed_tags($namespace, $tag)
2144 $type = $this->get_type();
2145 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2147 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2149 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2152 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2154 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2156 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2159 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2161 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2163 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2166 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2168 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2170 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2176 function get_channel_tags($namespace, $tag)
2178 $type = $this->get_type();
2179 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2181 if ($return = $this->get_feed_tags($namespace, $tag))
2186 if ($type & SIMPLEPIE_TYPE_RSS_10)
2188 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2190 if (isset($channel[0]['child'][$namespace][$tag]))
2192 return $channel[0]['child'][$namespace][$tag];
2196 if ($type & SIMPLEPIE_TYPE_RSS_090)
2198 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2200 if (isset($channel[0]['child'][$namespace][$tag]))
2202 return $channel[0]['child'][$namespace][$tag];
2206 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2208 if ($channel = $this->get_feed_tags('', 'channel'))
2210 if (isset($channel[0]['child'][$namespace][$tag]))
2212 return $channel[0]['child'][$namespace][$tag];
2219 function get_image_tags($namespace, $tag)
2221 $type = $this->get_type();
2222 if ($type & SIMPLEPIE_TYPE_RSS_10)
2224 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2226 if (isset($image[0]['child'][$namespace][$tag]))
2228 return $image[0]['child'][$namespace][$tag];
2232 if ($type & SIMPLEPIE_TYPE_RSS_090)
2234 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2236 if (isset($image[0]['child'][$namespace][$tag]))
2238 return $image[0]['child'][$namespace][$tag];
2242 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2244 if ($image = $this->get_channel_tags('', 'image'))
2246 if (isset($image[0]['child'][$namespace][$tag]))
2248 return $image[0]['child'][$namespace][$tag];
2255 function get_base($element = array())
2257 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2259 return $element['xml_base'];
2261 elseif ($this->get_link() !== null)
2263 return $this->get_link();
2267 return $this->subscribe_url();
2271 function sanitize($data, $type, $base = '')
2273 return $this->sanitize->sanitize($data, $type, $base);
2276 function get_title()
2278 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2280 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2282 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2284 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2286 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2288 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2290 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2292 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2294 elseif ($return = $this->get_channel_tags('', 'title'))
2296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2312 function get_category($key = 0)
2314 $categories = $this->get_categories();
2315 if (isset($categories[$key]))
2317 return $categories[$key];
2325 function get_categories()
2327 $categories = array();
2329 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2334 if (isset($category['attribs']['']['term']))
2336 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2338 if (isset($category['attribs']['']['scheme']))
2340 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2342 if (isset($category['attribs']['']['label']))
2344 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2346 $categories[] =& new $this->category_class($term, $scheme, $label);
2348 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2350 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2352 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2354 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2356 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2358 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2361 if (!empty($categories))
2363 return SimplePie_Misc::array_unique($categories);
2371 function get_author($key = 0)
2373 $authors = $this->get_authors();
2374 if (isset($authors[$key]))
2376 return $authors[$key];
2384 function get_authors()
2387 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2392 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2394 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2396 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2398 $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]));
2400 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2402 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2404 if ($name !== null || $email !== null || $uri !== null)
2406 $authors[] =& new $this->author_class($name, $uri, $email);
2409 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2414 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2416 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2418 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2420 $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]));
2422 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2424 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2426 if ($name !== null || $email !== null || $url !== null)
2428 $authors[] =& new $this->author_class($name, $url, $email);
2431 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2433 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2435 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2437 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2439 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2441 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2444 if (!empty($authors))
2446 return SimplePie_Misc::array_unique($authors);
2454 function get_contributor($key = 0)
2456 $contributors = $this->get_contributors();
2457 if (isset($contributors[$key]))
2459 return $contributors[$key];
2467 function get_contributors()
2469 $contributors = array();
2470 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2475 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2477 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2479 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2481 $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]));
2483 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2485 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2487 if ($name !== null || $email !== null || $uri !== null)
2489 $contributors[] =& new $this->author_class($name, $uri, $email);
2492 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2497 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2499 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2501 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2503 $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]));
2505 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2507 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2509 if ($name !== null || $email !== null || $url !== null)
2511 $contributors[] =& new $this->author_class($name, $url, $email);
2515 if (!empty($contributors))
2517 return SimplePie_Misc::array_unique($contributors);
2525 function get_link($key = 0, $rel = 'alternate')
2527 $links = $this->get_links($rel);
2528 if (isset($links[$key]))
2530 return $links[$key];
2539 * Added for parity between the parent-level and the item/entry-level.
2541 function get_permalink()
2543 return $this->get_link(0);
2546 function get_links($rel = 'alternate')
2548 if (!isset($this->data['links']))
2550 $this->data['links'] = array();
2551 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2553 foreach ($links as $link)
2555 if (isset($link['attribs']['']['href']))
2557 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2558 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2562 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2564 foreach ($links as $link)
2566 if (isset($link['attribs']['']['href']))
2568 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2569 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2574 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2576 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2578 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2580 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2582 if ($links = $this->get_channel_tags('', 'link'))
2584 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2587 $keys = array_keys($this->data['links']);
2588 foreach ($keys as $key)
2590 if (SimplePie_Misc::is_isegment_nz_nc($key))
2592 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2594 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2595 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2599 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2602 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2604 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2606 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2610 if (isset($this->data['links'][$rel]))
2612 return $this->data['links'][$rel];
2620 function get_description()
2622 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2624 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2626 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2628 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2630 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2632 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2634 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2636 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2638 elseif ($return = $this->get_channel_tags('', 'description'))
2640 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2642 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2644 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2646 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2648 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2650 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2652 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2654 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2656 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2664 function get_copyright()
2666 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2668 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2670 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2672 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2674 elseif ($return = $this->get_channel_tags('', 'copyright'))
2676 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2678 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2680 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2682 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2684 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2692 function get_language()
2694 if ($return = $this->get_channel_tags('', 'language'))
2696 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2698 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2700 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2702 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2704 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2706 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2708 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2710 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2712 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2714 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2716 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2718 elseif (isset($this->data['headers']['content-language']))
2720 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2728 function get_latitude()
2730 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2732 return (float) $return[0]['data'];
2734 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2736 return (float) $match[1];
2744 function get_longitude()
2746 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2748 return (float) $return[0]['data'];
2750 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2752 return (float) $return[0]['data'];
2754 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2756 return (float) $match[2];
2764 function get_image_title()
2766 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2768 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2770 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2772 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2774 elseif ($return = $this->get_image_tags('', 'title'))
2776 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2778 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2780 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2782 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2792 function get_image_url()
2794 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2796 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2798 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2800 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2802 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2804 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2806 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2808 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2810 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2812 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2814 elseif ($return = $this->get_image_tags('', 'url'))
2816 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2824 function get_image_link()
2826 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2828 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2830 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2832 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2834 elseif ($return = $this->get_image_tags('', 'link'))
2836 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2844 function get_image_width()
2846 if ($return = $this->get_image_tags('', 'width'))
2848 return round($return[0]['data']);
2850 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2860 function get_image_height()
2862 if ($return = $this->get_image_tags('', 'height'))
2864 return round($return[0]['data']);
2866 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2876 function get_item_quantity($max = 0)
2878 $qty = count($this->get_items());
2885 return ($qty > $max) ? $max : $qty;
2889 function get_item($key = 0)
2891 $items = $this->get_items();
2892 if (isset($items[$key]))
2894 return $items[$key];
2902 function get_items($start = 0, $end = 0)
2904 if (!empty($this->multifeed_objects))
2906 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2908 elseif (!isset($this->data['items']))
2910 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2912 $keys = array_keys($items);
2913 foreach ($keys as $key)
2915 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2918 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2920 $keys = array_keys($items);
2921 foreach ($keys as $key)
2923 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2926 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2928 $keys = array_keys($items);
2929 foreach ($keys as $key)
2931 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2934 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2936 $keys = array_keys($items);
2937 foreach ($keys as $key)
2939 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2942 if ($items = $this->get_channel_tags('', 'item'))
2944 $keys = array_keys($items);
2945 foreach ($keys as $key)
2947 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2952 if (!empty($this->data['items']))
2954 // If we want to order it by date, check if all items have a date, and then sort it
2955 if ($this->order_by_date)
2957 if (!isset($this->data['ordered_items']))
2960 foreach ($this->data['items'] as $item)
2962 if (!$item->get_date('U'))
2969 $this->data['ordered_items'] = $this->data['items'];
2972 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2975 $items = $this->data['ordered_items'];
2979 $items = $this->data['items'];
2982 // Slice the data as desired
2985 return array_slice($items, $start);
2989 return array_slice($items, $start, $end);
2998 function sort_items($a, $b)
3000 return $a->get_date('U') <= $b->get_date('U');
3003 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3005 if (is_array($urls) && sizeof($urls) > 0)
3008 foreach ($urls as $arg)
3010 if (is_a($arg, 'SimplePie'))
3012 $items = array_merge($items, $arg->get_items(0, $limit));
3016 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3021 foreach ($items as $item)
3023 if (!$item->get_date('U'))
3032 usort($items, array('SimplePie', 'sort_items'));
3037 return array_slice($items, $start);
3041 return array_slice($items, $start, $end);
3046 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3052 class SimplePie_Item
3055 var $data = array();
3057 function SimplePie_Item($feed, $data)
3059 $this->feed = $feed;
3060 $this->data = $data;
3063 function __toString()
3065 return md5(serialize($this->data));
3069 * Remove items that link back to this before destroying this object
3071 function __destruct()
3076 function get_item_tags($namespace, $tag)
3078 if (isset($this->data['child'][$namespace][$tag]))
3080 return $this->data['child'][$namespace][$tag];
3088 function get_base($element = array())
3090 return $this->feed->get_base($element);
3093 function sanitize($data, $type, $base = '')
3095 return $this->feed->sanitize($data, $type, $base);
3103 function get_id($hash = false)
3107 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3109 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3111 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3113 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3115 elseif ($return = $this->get_item_tags('', 'guid'))
3117 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3119 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3121 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3123 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3125 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3127 elseif (($return = $this->get_permalink()) !== null)
3131 elseif (($return = $this->get_title()) !== null)
3136 if ($this->get_permalink() !== null || $this->get_title() !== null)
3138 return md5($this->get_permalink() . $this->get_title());
3142 return md5(serialize($this->data));
3146 function get_title()
3148 if (!isset($this->data['title']))
3150 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3152 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3154 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3156 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3158 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3160 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3162 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3164 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3166 elseif ($return = $this->get_item_tags('', 'title'))
3168 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3170 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3172 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3174 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3176 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3180 $this->data['title'] = null;
3183 return $this->data['title'];
3186 function get_description($description_only = false)
3188 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3190 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3192 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3194 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3196 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3198 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3200 elseif ($return = $this->get_item_tags('', 'description'))
3202 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3204 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3206 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3208 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3210 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3212 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3214 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3216 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3218 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3220 elseif (!$description_only)
3222 return $this->get_content(true);
3230 function get_content($content_only = false)
3232 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3234 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3236 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3238 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3240 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3242 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3244 elseif (!$content_only)
3246 return $this->get_description(true);
3254 function get_category($key = 0)
3256 $categories = $this->get_categories();
3257 if (isset($categories[$key]))
3259 return $categories[$key];
3267 function get_categories()
3269 $categories = array();
3271 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3276 if (isset($category['attribs']['']['term']))
3278 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3280 if (isset($category['attribs']['']['scheme']))
3282 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3284 if (isset($category['attribs']['']['label']))
3286 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3288 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3290 foreach ((array) $this->get_item_tags('', 'category') as $category)
3292 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3294 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3296 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3298 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3300 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3303 if (!empty($categories))
3305 return SimplePie_Misc::array_unique($categories);
3313 function get_author($key = 0)
3315 $authors = $this->get_authors();
3316 if (isset($authors[$key]))
3318 return $authors[$key];
3326 function get_contributor($key = 0)
3328 $contributors = $this->get_contributors();
3329 if (isset($contributors[$key]))
3331 return $contributors[$key];
3339 function get_contributors()
3341 $contributors = array();
3342 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3347 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3349 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3351 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3353 $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]));
3355 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3357 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3359 if ($name !== null || $email !== null || $uri !== null)
3361 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3364 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3369 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3371 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3373 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3375 $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]));
3377 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3379 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3381 if ($name !== null || $email !== null || $url !== null)
3383 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3387 if (!empty($contributors))
3389 return SimplePie_Misc::array_unique($contributors);
3398 * @todo Atom inheritance (item author, source author, feed author)
3400 function get_authors()
3403 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3408 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3410 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3412 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3414 $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]));
3416 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3418 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3420 if ($name !== null || $email !== null || $uri !== null)
3422 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3425 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3430 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3432 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3434 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3436 $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]));
3438 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3440 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3442 if ($name !== null || $email !== null || $url !== null)
3444 $authors[] =& new $this->feed->author_class($name, $url, $email);
3447 if ($author = $this->get_item_tags('', 'author'))
3449 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3451 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3453 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3455 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3457 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3459 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3461 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3464 if (!empty($authors))
3466 return SimplePie_Misc::array_unique($authors);
3468 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3472 elseif ($authors = $this->feed->get_authors())
3482 function get_copyright()
3484 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3486 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3488 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3490 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3492 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3494 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3502 function get_date($date_format = 'j F Y, g:i a')
3504 if (!isset($this->data['date']))
3506 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3508 $this->data['date']['raw'] = $return[0]['data'];
3510 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3512 $this->data['date']['raw'] = $return[0]['data'];
3514 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3516 $this->data['date']['raw'] = $return[0]['data'];
3518 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3520 $this->data['date']['raw'] = $return[0]['data'];
3522 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3524 $this->data['date']['raw'] = $return[0]['data'];
3526 elseif ($return = $this->get_item_tags('', 'pubDate'))
3528 $this->data['date']['raw'] = $return[0]['data'];
3530 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3532 $this->data['date']['raw'] = $return[0]['data'];
3534 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3536 $this->data['date']['raw'] = $return[0]['data'];
3539 if (!empty($this->data['date']['raw']))
3541 $parser = SimplePie_Parse_Date::get();
3542 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3546 $this->data['date'] = null;
3549 if ($this->data['date'])
3551 $date_format = (string) $date_format;
3552 switch ($date_format)
3555 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3558 return $this->data['date']['parsed'];
3561 return date($date_format, $this->data['date']['parsed']);
3570 function get_local_date($date_format = '%c')
3574 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3576 elseif (($date = $this->get_date('U')) !== null)
3578 return strftime($date_format, $date);
3586 function get_permalink()
3588 $link = $this->get_link();
3589 $enclosure = $this->get_enclosure(0);
3594 elseif ($enclosure !== null)
3596 return $enclosure->get_link();
3604 function get_link($key = 0, $rel = 'alternate')
3606 $links = $this->get_links($rel);
3607 if ($links[$key] !== null)
3609 return $links[$key];
3617 function get_links($rel = 'alternate')
3619 if (!isset($this->data['links']))
3621 $this->data['links'] = array();
3622 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3624 if (isset($link['attribs']['']['href']))
3626 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3627 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3631 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3633 if (isset($link['attribs']['']['href']))
3635 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3636 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3639 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3641 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3643 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3645 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3647 if ($links = $this->get_item_tags('', 'link'))
3649 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3651 if ($links = $this->get_item_tags('', 'guid'))
3653 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3655 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3659 $keys = array_keys($this->data['links']);
3660 foreach ($keys as $key)
3662 if (SimplePie_Misc::is_isegment_nz_nc($key))
3664 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3666 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3667 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3671 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3674 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3676 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3678 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3681 if (isset($this->data['links'][$rel]))
3683 return $this->data['links'][$rel];
3692 * @todo Add ability to prefer one type of content over another (in a media group).
3694 function get_enclosure($key = 0, $prefer = null)
3696 $enclosures = $this->get_enclosures();
3697 if (isset($enclosures[$key]))
3699 return $enclosures[$key];
3708 * Grabs all available enclosures (podcasts, etc.)
3710 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3712 * 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.
3714 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3715 * @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).
3717 function get_enclosures()
3719 if (!isset($this->data['enclosures']))
3721 $this->data['enclosures'] = array();
3724 $captions_parent = null;
3725 $categories_parent = null;
3726 $copyrights_parent = null;
3727 $credits_parent = null;
3728 $description_parent = null;
3729 $duration_parent = null;
3730 $hashes_parent = null;
3731 $keywords_parent = null;
3732 $player_parent = null;
3733 $ratings_parent = null;
3734 $restrictions_parent = null;
3735 $thumbnails_parent = null;
3736 $title_parent = null;
3738 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3739 $parent = $this->get_feed();
3742 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3744 foreach ($captions as $caption)
3746 $caption_type = null;
3747 $caption_lang = null;
3748 $caption_startTime = null;
3749 $caption_endTime = null;
3750 $caption_text = null;
3751 if (isset($caption['attribs']['']['type']))
3753 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3755 if (isset($caption['attribs']['']['lang']))
3757 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3759 if (isset($caption['attribs']['']['start']))
3761 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3763 if (isset($caption['attribs']['']['end']))
3765 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3767 if (isset($caption['data']))
3769 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3771 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3774 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3776 foreach ($captions as $caption)
3778 $caption_type = null;
3779 $caption_lang = null;
3780 $caption_startTime = null;
3781 $caption_endTime = null;
3782 $caption_text = null;
3783 if (isset($caption['attribs']['']['type']))
3785 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3787 if (isset($caption['attribs']['']['lang']))
3789 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3791 if (isset($caption['attribs']['']['start']))
3793 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3795 if (isset($caption['attribs']['']['end']))
3797 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3799 if (isset($caption['data']))
3801 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3803 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3806 if (is_array($captions_parent))
3808 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3812 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3817 if (isset($category['data']))
3819 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3821 if (isset($category['attribs']['']['scheme']))
3823 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3827 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3829 if (isset($category['attribs']['']['label']))
3831 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3833 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3835 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3840 if (isset($category['data']))
3842 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3844 if (isset($category['attribs']['']['scheme']))
3846 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3850 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3852 if (isset($category['attribs']['']['label']))
3854 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3856 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3858 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3861 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3863 if (isset($category['attribs']['']['text']))
3865 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3867 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3869 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3871 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3873 if (isset($subcategory['attribs']['']['text']))
3875 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3877 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3881 if (is_array($categories_parent))
3883 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3887 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3889 $copyright_url = null;
3890 $copyright_label = null;
3891 if (isset($copyright[0]['attribs']['']['url']))
3893 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3895 if (isset($copyright[0]['data']))
3897 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3899 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3901 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3903 $copyright_url = null;
3904 $copyright_label = null;
3905 if (isset($copyright[0]['attribs']['']['url']))
3907 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3909 if (isset($copyright[0]['data']))
3911 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3913 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3917 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3919 foreach ($credits as $credit)
3921 $credit_role = null;
3922 $credit_scheme = null;
3923 $credit_name = null;
3924 if (isset($credit['attribs']['']['role']))
3926 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3928 if (isset($credit['attribs']['']['scheme']))
3930 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3934 $credit_scheme = 'urn:ebu';
3936 if (isset($credit['data']))
3938 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3940 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3943 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3945 foreach ($credits as $credit)
3947 $credit_role = null;
3948 $credit_scheme = null;
3949 $credit_name = null;
3950 if (isset($credit['attribs']['']['role']))
3952 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3954 if (isset($credit['attribs']['']['scheme']))
3956 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3960 $credit_scheme = 'urn:ebu';
3962 if (isset($credit['data']))
3964 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3966 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3969 if (is_array($credits_parent))
3971 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3975 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3977 if (isset($description_parent[0]['data']))
3979 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3982 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3984 if (isset($description_parent[0]['data']))
3986 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3991 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3996 if (isset($duration_parent[0]['data']))
3998 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3999 if (sizeof($temp) > 0)
4001 (int) $seconds = array_pop($temp);
4003 if (sizeof($temp) > 0)
4005 (int) $minutes = array_pop($temp);
4006 $seconds += $minutes * 60;
4008 if (sizeof($temp) > 0)
4010 (int) $hours = array_pop($temp);
4011 $seconds += $hours * 3600;
4014 $duration_parent = $seconds;
4019 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4021 foreach ($hashes_iterator as $hash)
4025 if (isset($hash['data']))
4027 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4029 if (isset($hash['attribs']['']['algo']))
4031 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4037 $hashes_parent[] = $algo.':'.$value;
4040 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4042 foreach ($hashes_iterator as $hash)
4046 if (isset($hash['data']))
4048 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4050 if (isset($hash['attribs']['']['algo']))
4052 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4058 $hashes_parent[] = $algo.':'.$value;
4061 if (is_array($hashes_parent))
4063 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4067 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4069 if (isset($keywords[0]['data']))
4071 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4072 foreach ($temp as $word)
4074 $keywords_parent[] = trim($word);
4079 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4081 if (isset($keywords[0]['data']))
4083 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4084 foreach ($temp as $word)
4086 $keywords_parent[] = trim($word);
4091 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4093 if (isset($keywords[0]['data']))
4095 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4096 foreach ($temp as $word)
4098 $keywords_parent[] = trim($word);
4103 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4105 if (isset($keywords[0]['data']))
4107 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4108 foreach ($temp as $word)
4110 $keywords_parent[] = trim($word);
4115 if (is_array($keywords_parent))
4117 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4121 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4123 if (isset($player_parent[0]['attribs']['']['url']))
4125 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4128 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4130 if (isset($player_parent[0]['attribs']['']['url']))
4132 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4137 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4139 foreach ($ratings as $rating)
4141 $rating_scheme = null;
4142 $rating_value = null;
4143 if (isset($rating['attribs']['']['scheme']))
4145 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4149 $rating_scheme = 'urn:simple';
4151 if (isset($rating['data']))
4153 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4155 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4158 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4160 foreach ($ratings as $rating)
4162 $rating_scheme = 'urn:itunes';
4163 $rating_value = null;
4164 if (isset($rating['data']))
4166 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4168 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4171 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4173 foreach ($ratings as $rating)
4175 $rating_scheme = null;
4176 $rating_value = null;
4177 if (isset($rating['attribs']['']['scheme']))
4179 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4183 $rating_scheme = 'urn:simple';
4185 if (isset($rating['data']))
4187 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4189 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4192 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4194 foreach ($ratings as $rating)
4196 $rating_scheme = 'urn:itunes';
4197 $rating_value = null;
4198 if (isset($rating['data']))
4200 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4202 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4205 if (is_array($ratings_parent))
4207 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4211 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4213 foreach ($restrictions as $restriction)
4215 $restriction_relationship = null;
4216 $restriction_type = null;
4217 $restriction_value = null;
4218 if (isset($restriction['attribs']['']['relationship']))
4220 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4222 if (isset($restriction['attribs']['']['type']))
4224 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4226 if (isset($restriction['data']))
4228 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4230 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4233 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4235 foreach ($restrictions as $restriction)
4237 $restriction_relationship = 'allow';
4238 $restriction_type = null;
4239 $restriction_value = 'itunes';
4240 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4242 $restriction_relationship = 'deny';
4244 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4247 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4249 foreach ($restrictions as $restriction)
4251 $restriction_relationship = null;
4252 $restriction_type = null;
4253 $restriction_value = null;
4254 if (isset($restriction['attribs']['']['relationship']))
4256 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4258 if (isset($restriction['attribs']['']['type']))
4260 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4262 if (isset($restriction['data']))
4264 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4266 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4269 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4271 foreach ($restrictions as $restriction)
4273 $restriction_relationship = 'allow';
4274 $restriction_type = null;
4275 $restriction_value = 'itunes';
4276 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4278 $restriction_relationship = 'deny';
4280 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4283 if (is_array($restrictions_parent))
4285 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4289 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4291 foreach ($thumbnails as $thumbnail)
4293 if (isset($thumbnail['attribs']['']['url']))
4295 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4299 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4301 foreach ($thumbnails as $thumbnail)
4303 if (isset($thumbnail['attribs']['']['url']))
4305 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4311 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4313 if (isset($title_parent[0]['data']))
4315 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4318 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4320 if (isset($title_parent[0]['data']))
4322 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4329 // If we have media:group tags, loop through them.
4330 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4332 // If we have media:content tags, loop through them.
4333 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4335 if (isset($content['attribs']['']['url']))
4348 $samplingrate = null;
4358 $description = null;
4363 $restrictions = null;
4367 // Start checking the attributes of media:content
4368 if (isset($content['attribs']['']['bitrate']))
4370 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4372 if (isset($content['attribs']['']['channels']))
4374 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4376 if (isset($content['attribs']['']['duration']))
4378 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4382 $duration = $duration_parent;
4384 if (isset($content['attribs']['']['expression']))
4386 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4388 if (isset($content['attribs']['']['framerate']))
4390 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4392 if (isset($content['attribs']['']['height']))
4394 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4396 if (isset($content['attribs']['']['lang']))
4398 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4400 if (isset($content['attribs']['']['fileSize']))
4402 $length = ceil($content['attribs']['']['fileSize']);
4404 if (isset($content['attribs']['']['medium']))
4406 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4408 if (isset($content['attribs']['']['samplingrate']))
4410 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4412 if (isset($content['attribs']['']['type']))
4414 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4416 if (isset($content['attribs']['']['width']))
4418 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4420 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4422 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4425 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4427 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4429 $caption_type = null;
4430 $caption_lang = null;
4431 $caption_startTime = null;
4432 $caption_endTime = null;
4433 $caption_text = null;
4434 if (isset($caption['attribs']['']['type']))
4436 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4438 if (isset($caption['attribs']['']['lang']))
4440 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4442 if (isset($caption['attribs']['']['start']))
4444 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4446 if (isset($caption['attribs']['']['end']))
4448 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4450 if (isset($caption['data']))
4452 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4454 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4456 if (is_array($captions))
4458 $captions = array_values(SimplePie_Misc::array_unique($captions));
4461 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4463 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4465 $caption_type = null;
4466 $caption_lang = null;
4467 $caption_startTime = null;
4468 $caption_endTime = null;
4469 $caption_text = null;
4470 if (isset($caption['attribs']['']['type']))
4472 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4474 if (isset($caption['attribs']['']['lang']))
4476 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4478 if (isset($caption['attribs']['']['start']))
4480 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4482 if (isset($caption['attribs']['']['end']))
4484 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4486 if (isset($caption['data']))
4488 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4490 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4492 if (is_array($captions))
4494 $captions = array_values(SimplePie_Misc::array_unique($captions));
4499 $captions = $captions_parent;
4503 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4505 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4510 if (isset($category['data']))
4512 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4514 if (isset($category['attribs']['']['scheme']))
4516 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4520 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4522 if (isset($category['attribs']['']['label']))
4524 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4526 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4529 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4531 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4536 if (isset($category['data']))
4538 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4540 if (isset($category['attribs']['']['scheme']))
4542 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4546 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4548 if (isset($category['attribs']['']['label']))
4550 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4552 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4555 if (is_array($categories) && is_array($categories_parent))
4557 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4559 elseif (is_array($categories))
4561 $categories = array_values(SimplePie_Misc::array_unique($categories));
4563 elseif (is_array($categories_parent))
4565 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4569 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4571 $copyright_url = null;
4572 $copyright_label = null;
4573 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4575 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4577 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4579 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4581 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4583 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4585 $copyright_url = null;
4586 $copyright_label = null;
4587 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4589 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4591 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4593 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4595 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4599 $copyrights = $copyrights_parent;
4603 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4605 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4607 $credit_role = null;
4608 $credit_scheme = null;
4609 $credit_name = null;
4610 if (isset($credit['attribs']['']['role']))
4612 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4614 if (isset($credit['attribs']['']['scheme']))
4616 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4620 $credit_scheme = 'urn:ebu';
4622 if (isset($credit['data']))
4624 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4626 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4628 if (is_array($credits))
4630 $credits = array_values(SimplePie_Misc::array_unique($credits));
4633 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4635 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4637 $credit_role = null;
4638 $credit_scheme = null;
4639 $credit_name = null;
4640 if (isset($credit['attribs']['']['role']))
4642 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4644 if (isset($credit['attribs']['']['scheme']))
4646 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4650 $credit_scheme = 'urn:ebu';
4652 if (isset($credit['data']))
4654 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4656 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4658 if (is_array($credits))
4660 $credits = array_values(SimplePie_Misc::array_unique($credits));
4665 $credits = $credits_parent;
4669 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4671 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4673 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4675 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4679 $description = $description_parent;
4683 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4685 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4689 if (isset($hash['data']))
4691 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4693 if (isset($hash['attribs']['']['algo']))
4695 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4701 $hashes[] = $algo.':'.$value;
4703 if (is_array($hashes))
4705 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4708 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4710 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4714 if (isset($hash['data']))
4716 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4718 if (isset($hash['attribs']['']['algo']))
4720 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4726 $hashes[] = $algo.':'.$value;
4728 if (is_array($hashes))
4730 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4735 $hashes = $hashes_parent;
4739 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4741 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4743 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4744 foreach ($temp as $word)
4746 $keywords[] = trim($word);
4750 if (is_array($keywords))
4752 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4755 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4757 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4759 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4760 foreach ($temp as $word)
4762 $keywords[] = trim($word);
4766 if (is_array($keywords))
4768 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4773 $keywords = $keywords_parent;
4777 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4779 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4781 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4783 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4787 $player = $player_parent;
4791 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4793 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4795 $rating_scheme = null;
4796 $rating_value = null;
4797 if (isset($rating['attribs']['']['scheme']))
4799 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4803 $rating_scheme = 'urn:simple';
4805 if (isset($rating['data']))
4807 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4809 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4811 if (is_array($ratings))
4813 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4816 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4818 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4820 $rating_scheme = null;
4821 $rating_value = null;
4822 if (isset($rating['attribs']['']['scheme']))
4824 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4828 $rating_scheme = 'urn:simple';
4830 if (isset($rating['data']))
4832 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4834 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4836 if (is_array($ratings))
4838 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4843 $ratings = $ratings_parent;
4847 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4849 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4851 $restriction_relationship = null;
4852 $restriction_type = null;
4853 $restriction_value = null;
4854 if (isset($restriction['attribs']['']['relationship']))
4856 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4858 if (isset($restriction['attribs']['']['type']))
4860 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4862 if (isset($restriction['data']))
4864 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4866 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4868 if (is_array($restrictions))
4870 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4873 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4875 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4877 $restriction_relationship = null;
4878 $restriction_type = null;
4879 $restriction_value = null;
4880 if (isset($restriction['attribs']['']['relationship']))
4882 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4884 if (isset($restriction['attribs']['']['type']))
4886 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4888 if (isset($restriction['data']))
4890 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4892 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4894 if (is_array($restrictions))
4896 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4901 $restrictions = $restrictions_parent;
4905 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4907 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4909 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4911 if (is_array($thumbnails))
4913 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4916 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4918 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4920 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4922 if (is_array($thumbnails))
4924 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4929 $thumbnails = $thumbnails_parent;
4933 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4935 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4937 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4939 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4943 $title = $title_parent;
4946 $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);
4951 // If we have standalone media:content tags, loop through them.
4952 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4954 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4956 if (isset($content['attribs']['']['url']))
4969 $samplingrate = null;
4979 $description = null;
4984 $restrictions = null;
4988 // Start checking the attributes of media:content
4989 if (isset($content['attribs']['']['bitrate']))
4991 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4993 if (isset($content['attribs']['']['channels']))
4995 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4997 if (isset($content['attribs']['']['duration']))
4999 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5003 $duration = $duration_parent;
5005 if (isset($content['attribs']['']['expression']))
5007 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5009 if (isset($content['attribs']['']['framerate']))
5011 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5013 if (isset($content['attribs']['']['height']))
5015 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5017 if (isset($content['attribs']['']['lang']))
5019 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5021 if (isset($content['attribs']['']['fileSize']))
5023 $length = ceil($content['attribs']['']['fileSize']);
5025 if (isset($content['attribs']['']['medium']))
5027 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5029 if (isset($content['attribs']['']['samplingrate']))
5031 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5033 if (isset($content['attribs']['']['type']))
5035 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5037 if (isset($content['attribs']['']['width']))
5039 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5041 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5043 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5046 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5048 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5050 $caption_type = null;
5051 $caption_lang = null;
5052 $caption_startTime = null;
5053 $caption_endTime = null;
5054 $caption_text = null;
5055 if (isset($caption['attribs']['']['type']))
5057 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5059 if (isset($caption['attribs']['']['lang']))
5061 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5063 if (isset($caption['attribs']['']['start']))
5065 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5067 if (isset($caption['attribs']['']['end']))
5069 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5071 if (isset($caption['data']))
5073 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5075 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5077 if (is_array($captions))
5079 $captions = array_values(SimplePie_Misc::array_unique($captions));
5084 $captions = $captions_parent;
5088 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5090 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5095 if (isset($category['data']))
5097 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5099 if (isset($category['attribs']['']['scheme']))
5101 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5105 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5107 if (isset($category['attribs']['']['label']))
5109 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5111 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5114 if (is_array($categories) && is_array($categories_parent))
5116 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5118 elseif (is_array($categories))
5120 $categories = array_values(SimplePie_Misc::array_unique($categories));
5122 elseif (is_array($categories_parent))
5124 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5132 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5134 $copyright_url = null;
5135 $copyright_label = null;
5136 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5138 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5140 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5142 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5144 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5148 $copyrights = $copyrights_parent;
5152 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5154 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5156 $credit_role = null;
5157 $credit_scheme = null;
5158 $credit_name = null;
5159 if (isset($credit['attribs']['']['role']))
5161 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5163 if (isset($credit['attribs']['']['scheme']))
5165 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5169 $credit_scheme = 'urn:ebu';
5171 if (isset($credit['data']))
5173 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5175 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5177 if (is_array($credits))
5179 $credits = array_values(SimplePie_Misc::array_unique($credits));
5184 $credits = $credits_parent;
5188 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5190 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5194 $description = $description_parent;
5198 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5200 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5204 if (isset($hash['data']))
5206 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5208 if (isset($hash['attribs']['']['algo']))
5210 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5216 $hashes[] = $algo.':'.$value;
5218 if (is_array($hashes))
5220 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5225 $hashes = $hashes_parent;
5229 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5231 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5233 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5234 foreach ($temp as $word)
5236 $keywords[] = trim($word);
5240 if (is_array($keywords))
5242 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5247 $keywords = $keywords_parent;
5251 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5253 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5257 $player = $player_parent;
5261 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5263 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5265 $rating_scheme = null;
5266 $rating_value = null;
5267 if (isset($rating['attribs']['']['scheme']))
5269 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5273 $rating_scheme = 'urn:simple';
5275 if (isset($rating['data']))
5277 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5279 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5281 if (is_array($ratings))
5283 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5288 $ratings = $ratings_parent;
5292 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5294 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5296 $restriction_relationship = null;
5297 $restriction_type = null;
5298 $restriction_value = null;
5299 if (isset($restriction['attribs']['']['relationship']))
5301 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5303 if (isset($restriction['attribs']['']['type']))
5305 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5307 if (isset($restriction['data']))
5309 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5311 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5313 if (is_array($restrictions))
5315 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5320 $restrictions = $restrictions_parent;
5324 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5326 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5328 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5330 if (is_array($thumbnails))
5332 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5337 $thumbnails = $thumbnails_parent;
5341 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5343 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5347 $title = $title_parent;
5350 $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);
5355 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5357 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5370 $samplingrate = null;
5375 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5376 if (isset($link['attribs']['']['type']))
5378 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5380 if (isset($link['attribs']['']['length']))
5382 $length = ceil($link['attribs']['']['length']);
5385 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5386 $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);
5390 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5392 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5405 $samplingrate = null;
5410 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5411 if (isset($link['attribs']['']['type']))
5413 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5415 if (isset($link['attribs']['']['length']))
5417 $length = ceil($link['attribs']['']['length']);
5420 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5421 $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);
5425 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5427 if (isset($enclosure[0]['attribs']['']['url']))
5440 $samplingrate = null;
5445 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5446 if (isset($enclosure[0]['attribs']['']['type']))
5448 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5450 if (isset($enclosure[0]['attribs']['']['length']))
5452 $length = ceil($enclosure[0]['attribs']['']['length']);
5455 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5456 $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);
5460 if (sizeof($this->data['enclosures']) == 0)
5462 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5463 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5466 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5468 if (!empty($this->data['enclosures']))
5470 return $this->data['enclosures'];
5478 function get_latitude()
5480 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5482 return (float) $return[0]['data'];
5484 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5486 return (float) $match[1];
5494 function get_longitude()
5496 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5498 return (float) $return[0]['data'];
5500 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5502 return (float) $return[0]['data'];
5504 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5506 return (float) $match[2];
5514 function get_source()
5516 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5518 return new $this->feed->source_class($this, $return[0]);
5527 * Creates the add_to_* methods' return data
5530 * @param string $item_url String to prefix to the item permalink
5531 * @param string $title_url String to prefix to the item title
5532 * (and suffix to the item permalink)
5533 * @return mixed URL if feed exists, false otherwise
5535 function add_to_service($item_url, $title_url = null)
5537 if ($this->get_permalink() !== null)
5539 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5540 if ($title_url !== null && $this->get_title() !== null)
5542 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5552 function add_to_blinklist()
5554 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5557 function add_to_blogmarks()
5559 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5562 function add_to_delicious()
5564 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5567 function add_to_digg()
5569 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5572 function add_to_furl()
5574 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5577 function add_to_magnolia()
5579 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5582 function add_to_myweb20()
5584 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5587 function add_to_newsvine()
5589 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5592 function add_to_reddit()
5594 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5597 function add_to_segnalo()
5599 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5602 function add_to_simpy()
5604 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5607 function add_to_spurl()
5609 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5612 function add_to_wists()
5614 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5617 function search_technorati()
5619 return $this->add_to_service('http://www.technorati.com/search/');
5623 class SimplePie_Source
5626 var $data = array();
5628 function SimplePie_Source($item, $data)
5630 $this->item = $item;
5631 $this->data = $data;
5634 function __toString()
5636 return md5(serialize($this->data));
5640 * Remove items that link back to this before destroying this object
5642 function __destruct()
5647 function get_source_tags($namespace, $tag)
5649 if (isset($this->data['child'][$namespace][$tag]))
5651 return $this->data['child'][$namespace][$tag];
5659 function get_base($element = array())
5661 return $this->item->get_base($element);
5664 function sanitize($data, $type, $base = '')
5666 return $this->item->sanitize($data, $type, $base);
5674 function get_title()
5676 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5678 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5680 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5682 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5684 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5688 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5692 elseif ($return = $this->get_source_tags('', 'title'))
5694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5696 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5700 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5710 function get_category($key = 0)
5712 $categories = $this->get_categories();
5713 if (isset($categories[$key]))
5715 return $categories[$key];
5723 function get_categories()
5725 $categories = array();
5727 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5732 if (isset($category['attribs']['']['term']))
5734 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5736 if (isset($category['attribs']['']['scheme']))
5738 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5740 if (isset($category['attribs']['']['label']))
5742 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5744 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5746 foreach ((array) $this->get_source_tags('', 'category') as $category)
5748 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5750 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5752 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5754 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5756 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5759 if (!empty($categories))
5761 return SimplePie_Misc::array_unique($categories);
5769 function get_author($key = 0)
5771 $authors = $this->get_authors();
5772 if (isset($authors[$key]))
5774 return $authors[$key];
5782 function get_authors()
5785 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5790 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5792 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5794 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5796 $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]));
5798 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5800 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5802 if ($name !== null || $email !== null || $uri !== null)
5804 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5807 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5812 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5814 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5816 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5818 $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]));
5820 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5822 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5824 if ($name !== null || $email !== null || $url !== null)
5826 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5829 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5831 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5833 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5835 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5837 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5839 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5842 if (!empty($authors))
5844 return SimplePie_Misc::array_unique($authors);
5852 function get_contributor($key = 0)
5854 $contributors = $this->get_contributors();
5855 if (isset($contributors[$key]))
5857 return $contributors[$key];
5865 function get_contributors()
5867 $contributors = array();
5868 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5873 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5875 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5877 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5879 $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]));
5881 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5883 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5885 if ($name !== null || $email !== null || $uri !== null)
5887 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5890 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5895 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5897 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5899 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5901 $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]));
5903 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5905 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5907 if ($name !== null || $email !== null || $url !== null)
5909 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5913 if (!empty($contributors))
5915 return SimplePie_Misc::array_unique($contributors);
5923 function get_link($key = 0, $rel = 'alternate')
5925 $links = $this->get_links($rel);
5926 if (isset($links[$key]))
5928 return $links[$key];
5937 * Added for parity between the parent-level and the item/entry-level.
5939 function get_permalink()
5941 return $this->get_link(0);
5944 function get_links($rel = 'alternate')
5946 if (!isset($this->data['links']))
5948 $this->data['links'] = array();
5949 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5951 foreach ($links as $link)
5953 if (isset($link['attribs']['']['href']))
5955 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5956 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5960 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
5962 foreach ($links as $link)
5964 if (isset($link['attribs']['']['href']))
5966 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5967 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5972 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
5974 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5976 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
5978 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5980 if ($links = $this->get_source_tags('', 'link'))
5982 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
5985 $keys = array_keys($this->data['links']);
5986 foreach ($keys as $key)
5988 if (SimplePie_Misc::is_isegment_nz_nc($key))
5990 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
5992 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
5993 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
5997 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6000 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6002 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6004 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6008 if (isset($this->data['links'][$rel]))
6010 return $this->data['links'][$rel];
6018 function get_description()
6020 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6022 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6024 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6026 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6028 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6030 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6032 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6034 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6036 elseif ($return = $this->get_source_tags('', 'description'))
6038 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6040 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6042 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6044 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6046 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6048 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6050 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6052 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6054 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6062 function get_copyright()
6064 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6066 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6068 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6070 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6072 elseif ($return = $this->get_source_tags('', 'copyright'))
6074 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6076 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6078 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6080 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6082 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6090 function get_language()
6092 if ($return = $this->get_source_tags('', 'language'))
6094 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6096 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6098 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6100 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6102 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6104 elseif (isset($this->data['xml_lang']))
6106 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6114 function get_latitude()
6116 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6118 return (float) $return[0]['data'];
6120 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6122 return (float) $match[1];
6130 function get_longitude()
6132 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6134 return (float) $return[0]['data'];
6136 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6138 return (float) $return[0]['data'];
6140 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6142 return (float) $match[2];
6150 function get_image_url()
6152 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6154 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6156 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6158 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6160 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6162 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6171 class SimplePie_Author
6177 // Constructor, used to input the data
6178 function SimplePie_Author($name = null, $link = null, $email = null)
6180 $this->name = $name;
6181 $this->link = $link;
6182 $this->email = $email;
6185 function __toString()
6187 // There is no $this->data here
6188 return md5(serialize($this));
6193 if ($this->name !== null)
6205 if ($this->link !== null)
6215 function get_email()
6217 if ($this->email !== null)
6219 return $this->email;
6228 class SimplePie_Category
6234 // Constructor, used to input the data
6235 function SimplePie_Category($term = null, $scheme = null, $label = null)
6237 $this->term = $term;
6238 $this->scheme = $scheme;
6239 $this->label = $label;
6242 function __toString()
6244 // There is no $this->data here
6245 return md5(serialize($this));
6250 if ($this->term !== null)
6260 function get_scheme()
6262 if ($this->scheme !== null)
6264 return $this->scheme;
6272 function get_label()
6274 if ($this->label !== null)
6276 return $this->label;
6280 return $this->get_term();
6285 class SimplePie_Enclosure
6315 // Constructor, used to input the data
6316 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)
6318 $this->bitrate = $bitrate;
6319 $this->captions = $captions;
6320 $this->categories = $categories;
6321 $this->channels = $channels;
6322 $this->copyright = $copyright;
6323 $this->credits = $credits;
6324 $this->description = $description;
6325 $this->duration = $duration;
6326 $this->expression = $expression;
6327 $this->framerate = $framerate;
6328 $this->hashes = $hashes;
6329 $this->height = $height;
6330 $this->javascript = $javascript;
6331 $this->keywords = $keywords;
6332 $this->lang = $lang;
6333 $this->length = $length;
6334 $this->link = $link;
6335 $this->medium = $medium;
6336 $this->player = $player;
6337 $this->ratings = $ratings;
6338 $this->restrictions = $restrictions;
6339 $this->samplingrate = $samplingrate;
6340 $this->thumbnails = $thumbnails;
6341 $this->title = $title;
6342 $this->type = $type;
6343 $this->width = $width;
6344 if (class_exists('idna_convert'))
6346 $idn =& new idna_convert;
6347 $parsed = SimplePie_Misc::parse_url($link);
6348 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6350 $this->handler = $this->get_handler(); // Needs to load last
6353 function __toString()
6355 // There is no $this->data here
6356 return md5(serialize($this));
6359 function get_bitrate()
6361 if ($this->bitrate !== null)
6363 return $this->bitrate;
6371 function get_caption($key = 0)
6373 $captions = $this->get_captions();
6374 if (isset($captions[$key]))
6376 return $captions[$key];
6384 function get_captions()
6386 if ($this->captions !== null)
6388 return $this->captions;
6396 function get_category($key = 0)
6398 $categories = $this->get_categories();
6399 if (isset($categories[$key]))
6401 return $categories[$key];
6409 function get_categories()
6411 if ($this->categories !== null)
6413 return $this->categories;
6421 function get_channels()
6423 if ($this->channels !== null)
6425 return $this->channels;
6433 function get_copyright()
6435 if ($this->copyright !== null)
6437 return $this->copyright;
6445 function get_credit($key = 0)
6447 $credits = $this->get_credits();
6448 if (isset($credits[$key]))
6450 return $credits[$key];
6458 function get_credits()
6460 if ($this->credits !== null)
6462 return $this->credits;
6470 function get_description()
6472 if ($this->description !== null)
6474 return $this->description;
6482 function get_duration($convert = false)
6484 if ($this->duration !== null)
6488 $time = SimplePie_Misc::time_hms($this->duration);
6493 return $this->duration;
6502 function get_expression()
6504 if ($this->expression !== null)
6506 return $this->expression;
6514 function get_extension()
6516 if ($this->link !== null)
6518 $url = SimplePie_Misc::parse_url($this->link);
6519 if ($url['path'] !== '')
6521 return pathinfo($url['path'], PATHINFO_EXTENSION);
6527 function get_framerate()
6529 if ($this->framerate !== null)
6531 return $this->framerate;
6539 function get_handler()
6541 return $this->get_real_type(true);
6544 function get_hash($key = 0)
6546 $hashes = $this->get_hashes();
6547 if (isset($hashes[$key]))
6549 return $hashes[$key];
6557 function get_hashes()
6559 if ($this->hashes !== null)
6561 return $this->hashes;
6569 function get_height()
6571 if ($this->height !== null)
6573 return $this->height;
6581 function get_language()
6583 if ($this->lang !== null)
6593 function get_keyword($key = 0)
6595 $keywords = $this->get_keywords();
6596 if (isset($keywords[$key]))
6598 return $keywords[$key];
6606 function get_keywords()
6608 if ($this->keywords !== null)
6610 return $this->keywords;
6618 function get_length()
6620 if ($this->length !== null)
6622 return $this->length;
6632 if ($this->link !== null)
6634 return urldecode($this->link);
6642 function get_medium()
6644 if ($this->medium !== null)
6646 return $this->medium;
6654 function get_player()
6656 if ($this->player !== null)
6658 return $this->player;
6666 function get_rating($key = 0)
6668 $ratings = $this->get_ratings();
6669 if (isset($ratings[$key]))
6671 return $ratings[$key];
6679 function get_ratings()
6681 if ($this->ratings !== null)
6683 return $this->ratings;
6691 function get_restriction($key = 0)
6693 $restrictions = $this->get_restrictions();
6694 if (isset($restrictions[$key]))
6696 return $restrictions[$key];
6704 function get_restrictions()
6706 if ($this->restrictions !== null)
6708 return $this->restrictions;
6716 function get_sampling_rate()
6718 if ($this->samplingrate !== null)
6720 return $this->samplingrate;
6730 $length = $this->get_length();
6731 if ($length !== null)
6733 return round($length/1048576, 2);
6741 function get_thumbnail($key = 0)
6743 $thumbnails = $this->get_thumbnails();
6744 if (isset($thumbnails[$key]))
6746 return $thumbnails[$key];
6754 function get_thumbnails()
6756 if ($this->thumbnails !== null)
6758 return $this->thumbnails;
6766 function get_title()
6768 if ($this->title !== null)
6770 return $this->title;
6780 if ($this->type !== null)
6790 function get_width()
6792 if ($this->width !== null)
6794 return $this->width;
6802 function native_embed($options='')
6804 return $this->embed($options, true);
6808 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6810 function embed($options = '', $native = false)
6820 $bgcolor = '#ffffff';
6822 $widescreen = false;
6823 $handler = $this->get_handler();
6824 $type = $this->get_real_type();
6826 // Process options and reassign values as necessary
6827 if (is_array($options))
6833 $options = explode(',', $options);
6834 foreach($options as $option)
6836 $opt = explode(':', $option, 2);
6837 if (isset($opt[0], $opt[1]))
6839 $opt[0] = trim($opt[0]);
6840 $opt[1] = trim($opt[1]);
6856 $altclass = $opt[1];
6876 $mediaplayer = $opt[1];
6880 $widescreen = $opt[1];
6887 $mime = explode('/', $type, 2);
6890 // Process values for 'auto'
6891 if ($width == 'auto')
6893 if ($mime == 'video')
6895 if ($height == 'auto')
6899 elseif ($widescreen)
6901 $width = round((intval($height)/9)*16);
6905 $width = round((intval($height)/3)*4);
6914 if ($height == 'auto')
6916 if ($mime == 'audio')
6920 elseif ($mime == 'video')
6922 if ($width == 'auto')
6933 elseif ($widescreen)
6935 $height = round((intval($width)/16)*9);
6939 $height = round((intval($width)/4)*3);
6947 elseif ($mime == 'audio')
6952 // Set proper placeholder value
6953 if ($mime == 'audio')
6955 $placeholder = $audio;
6957 elseif ($mime == 'video')
6959 $placeholder = $video;
6964 // Make sure the JS library is included
6967 static $javascript_outputted = null;
6968 if (!$javascript_outputted && $this->javascript)
6970 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
6971 $javascript_outputted = true;
6976 if ($handler == 'odeo')
6980 $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>';
6984 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
6989 elseif ($handler == 'flash')
6993 $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>";
6997 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7001 // Flash Media Player file types.
7002 // Preferred handler for MP3 file types.
7003 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7008 $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>";
7012 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7016 // QuickTime 7 file types. Need to test with QuickTime 6.
7017 // Only handle MP3's if the Flash Media Player is not present.
7018 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7023 if ($placeholder != ""){
7024 $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>";
7027 $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>";
7032 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7037 elseif ($handler == 'wmedia')
7042 $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>";
7046 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7051 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7056 function get_real_type($find_handler = false)
7058 // If it's Odeo, let's get it out of the way.
7059 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7064 // Mime-types by handler.
7065 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7066 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
7067 $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
7068 $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
7069 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7071 if ($this->get_type() !== null)
7073 $type = strtolower($this->type);
7080 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7081 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7083 switch (strtolower($this->get_extension()))
7088 $type = 'audio/acc';
7095 $type = 'audio/aiff';
7099 $type = 'audio/wav';
7106 $type = 'audio/midi';
7110 $type = 'audio/x-m4a';
7115 $type = 'audio/mp3';
7119 $type = 'audio/wav';
7123 $type = 'audio/x-ms-wax';
7127 $type = 'audio/x-ms-wma';
7133 $type = 'video/3gpp';
7138 $type = 'video/3gpp2';
7142 $type = 'video/x-ms-asf';
7146 $type = 'video/x-flv';
7160 $type = 'video/mpeg';
7164 $type = 'video/x-m4v';
7169 $type = 'video/quicktime';
7174 $type = 'video/mp4';
7178 $type = 'video/sd-video';
7182 $type = 'video/x-ms-wm';
7186 $type = 'video/x-ms-wmv';
7190 $type = 'video/x-ms-wvx';
7195 $type = 'application/futuresplash';
7199 $type = 'application/x-shockwave-flash';
7206 if (in_array($type, $types_flash))
7210 elseif (in_array($type, $types_fmedia))
7214 elseif (in_array($type, $types_quicktime))
7218 elseif (in_array($type, $types_wmedia))
7222 elseif (in_array($type, $types_mp3))
7238 class SimplePie_Caption
7246 // Constructor, used to input the data
7247 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7249 $this->type = $type;
7250 $this->lang = $lang;
7251 $this->startTime = $startTime;
7252 $this->endTime = $endTime;
7253 $this->text = $text;
7256 function __toString()
7258 // There is no $this->data here
7259 return md5(serialize($this));
7262 function get_endtime()
7264 if ($this->endTime !== null)
7266 return $this->endTime;
7274 function get_language()
7276 if ($this->lang !== null)
7286 function get_starttime()
7288 if ($this->startTime !== null)
7290 return $this->startTime;
7300 if ($this->text !== null)
7312 if ($this->type !== null)
7323 class SimplePie_Credit
7329 // Constructor, used to input the data
7330 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7332 $this->role = $role;
7333 $this->scheme = $scheme;
7334 $this->name = $name;
7337 function __toString()
7339 // There is no $this->data here
7340 return md5(serialize($this));
7345 if ($this->role !== null)
7355 function get_scheme()
7357 if ($this->scheme !== null)
7359 return $this->scheme;
7369 if ($this->name !== null)
7380 class SimplePie_Copyright
7385 // Constructor, used to input the data
7386 function SimplePie_Copyright($url = null, $label = null)
7389 $this->label = $label;
7392 function __toString()
7394 // There is no $this->data here
7395 return md5(serialize($this));
7400 if ($this->url !== null)
7410 function get_attribution()
7412 if ($this->label !== null)
7414 return $this->label;
7423 class SimplePie_Rating
7428 // Constructor, used to input the data
7429 function SimplePie_Rating($scheme = null, $value = null)
7431 $this->scheme = $scheme;
7432 $this->value = $value;
7435 function __toString()
7437 // There is no $this->data here
7438 return md5(serialize($this));
7441 function get_scheme()
7443 if ($this->scheme !== null)
7445 return $this->scheme;
7453 function get_value()
7455 if ($this->value !== null)
7457 return $this->value;
7466 class SimplePie_Restriction
7472 // Constructor, used to input the data
7473 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7475 $this->relationship = $relationship;
7476 $this->type = $type;
7477 $this->value = $value;
7480 function __toString()
7482 // There is no $this->data here
7483 return md5(serialize($this));
7486 function get_relationship()
7488 if ($this->relationship !== null)
7490 return $this->relationship;
7500 if ($this->type !== null)
7510 function get_value()
7512 if ($this->value !== null)
7514 return $this->value;
7524 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7526 class SimplePie_File
7530 var $success = true;
7531 var $headers = array();
7536 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7538 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7540 if (class_exists('idna_convert'))
7542 $idn =& new idna_convert;
7543 $parsed = SimplePie_Misc::parse_url($url);
7544 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7547 $this->useragent = $useragent;
7548 if (preg_match('/^http(s)?:\/\//i', $url))
7550 if ($useragent === null)
7552 $useragent = ini_get('user_agent');
7553 $this->useragent = $useragent;
7555 if (!is_array($headers))
7559 if (!$force_fsockopen && function_exists('curl_exec'))
7561 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7563 $headers2 = array();
7564 foreach ($headers as $key => $value)
7566 $headers2[] = "$key: $value";
7568 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7570 curl_setopt($fp, CURLOPT_ENCODING, '');
7572 curl_setopt($fp, CURLOPT_URL, $url);
7573 curl_setopt($fp, CURLOPT_HEADER, 1);
7574 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7575 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7576 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7577 curl_setopt($fp, CURLOPT_REFERER, $url);
7578 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7579 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7580 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7582 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7583 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7586 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
7587 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
7589 $this->headers = curl_exec($fp);
7590 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7592 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7593 $this->headers = curl_exec($fp);
7595 if (curl_errno($fp))
7597 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7598 $this->success = false;
7602 $info = curl_getinfo($fp);
7604 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7605 $this->headers = array_pop($this->headers);
7606 $parser =& new SimplePie_HTTP_Parser($this->headers);
7607 if ($parser->parse())
7609 $this->headers = $parser->headers;
7610 $this->body = $parser->body;
7611 $this->status_code = $parser->status_code;
7612 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7615 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7616 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7619 // No feed fount at error correction.
7620 // according to http://simplepie.org/support/viewtopic.php?id=1430
7622 $this->success = false;
7628 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7629 $url_parts = parse_url($url);
7630 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7632 $url_parts['host'] = "ssl://$url_parts[host]";
7633 $url_parts['port'] = 443;
7635 if (!isset($url_parts['port']))
7637 $url_parts['port'] = 80;
7639 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7642 $this->error = 'fsockopen error: ' . $errstr;
7643 $this->success = false;
7647 stream_set_timeout($fp, $timeout);
7648 if (isset($url_parts['path']))
7650 if (isset($url_parts['query']))
7652 $get = "$url_parts[path]?$url_parts[query]";
7656 $get = $url_parts['path'];
7663 $out = "GET $get HTTP/1.0\r\n";
7664 $out .= "Host: $url_parts[host]\r\n";
7665 $out .= "User-Agent: $useragent\r\n";
7666 if (function_exists('gzinflate'))
7668 $out .= "Accept-Encoding: gzip,deflate\r\n";
7671 if (isset($url_parts['user']) && isset($url_parts['pass']))
7673 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7675 foreach ($headers as $key => $value)
7677 $out .= "$key: $value\r\n";
7679 $out .= "Connection: Close\r\n\r\n";
7682 $info = stream_get_meta_data($fp);
7684 $this->headers = '';
7685 while (!$info['eof'] && !$info['timed_out'])
7687 $this->headers .= fread($fp, 1160);
7688 $info = stream_get_meta_data($fp);
7690 if (!$info['timed_out'])
7692 $parser =& new SimplePie_HTTP_Parser($this->headers);
7693 if ($parser->parse())
7695 $this->headers = $parser->headers;
7696 $this->body = $parser->body;
7697 $this->status_code = $parser->status_code;
7698 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7701 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7702 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7704 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
7706 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
7708 $this->body = substr($this->body, 10);
7710 $this->body = gzinflate($this->body);
7716 $this->error = 'fsocket timed out';
7717 $this->success = false;
7725 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7726 if (!$this->body = file_get_contents($url))
7728 $this->error = 'file_get_contents could not read the file';
7729 $this->success = false;
7736 * HTTP Response Parser
7738 * @package SimplePie
7740 class SimplePie_HTTP_Parser
7748 var $http_version = 0.0;
7756 var $status_code = 0;
7767 * Key/value pairs of the headers
7772 var $headers = array();
7775 * Body of the response
7783 * Current state of the state machine
7788 var $state = 'http_version';
7799 * Input data length (to avoid calling strlen() everytime this is needed)
7804 var $data_length = 0;
7807 * Current position of the pointer
7815 * Name of the hedaer currently being parsed
7823 * Value of the hedaer currently being parsed
7831 * Create an instance of the class with the input data
7834 * @param string $data Input data
7836 function SimplePie_HTTP_Parser($data)
7838 $this->data = $data;
7839 $this->data_length = strlen($this->data);
7843 * Parse the input data
7846 * @return bool true on success, false on failure
7850 while ($this->state && $this->state !== 'emit' && $this->has_data())
7852 $state = $this->state;
7856 if ($this->state === 'emit')
7862 $this->http_version = '';
7863 $this->status_code = '';
7865 $this->headers = array();
7872 * Check whether there is data beyond the pointer
7875 * @return bool true if there is further data, false if not
7879 return (bool) ($this->position < $this->data_length);
7883 * See if the next character is LWS
7886 * @return bool true if the next character is LWS, false if not
7888 function is_linear_whitespace()
7890 return (bool) ($this->data[$this->position] === "\x09"
7891 || $this->data[$this->position] === "\x20"
7892 || ($this->data[$this->position] === "\x0A"
7893 && isset($this->data[$this->position + 1])
7894 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7898 * Parse the HTTP version
7902 function http_version()
7904 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7906 $len = strspn($this->data, '0123456789.', 5);
7907 $this->http_version = substr($this->data, 5, $len);
7908 $this->position += 5 + $len;
7909 if (substr_count($this->http_version, '.') <= 1)
7911 $this->http_version = (float) $this->http_version;
7912 $this->position += strspn($this->data, "\x09\x20", $this->position);
7913 $this->state = 'status';
7917 $this->state = false;
7922 $this->state = false;
7927 * Parse the status code
7933 if ($len = strspn($this->data, '0123456789', $this->position))
7935 $this->status_code = (int) substr($this->data, $this->position, $len);
7936 $this->position += $len;
7937 $this->state = 'reason';
7941 $this->state = false;
7946 * Parse the reason phrase
7952 $len = strcspn($this->data, "\x0A", $this->position);
7953 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
7954 $this->position += $len + 1;
7955 $this->state = 'new_line';
7959 * Deal with a new line, shifting data around as needed
7965 $this->value = trim($this->value, "\x0D\x20");
7966 if ($this->name !== '' && $this->value !== '')
7968 $this->name = strtolower($this->name);
7969 if (isset($this->headers[$this->name]))
7971 $this->headers[$this->name] .= ', ' . $this->value;
7975 $this->headers[$this->name] = $this->value;
7980 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
7982 $this->position += 2;
7983 $this->state = 'body';
7985 elseif ($this->data[$this->position] === "\x0A")
7988 $this->state = 'body';
7992 $this->state = 'name';
7997 * Parse a header name
8003 $len = strcspn($this->data, "\x0A:", $this->position);
8004 if (isset($this->data[$this->position + $len]))
8006 if ($this->data[$this->position + $len] === "\x0A")
8008 $this->position += $len;
8009 $this->state = 'new_line';
8013 $this->name = substr($this->data, $this->position, $len);
8014 $this->position += $len + 1;
8015 $this->state = 'value';
8020 $this->state = false;
8025 * Parse LWS, replacing consecutive LWS characters with a single space
8029 function linear_whitespace()
8033 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8035 $this->position += 2;
8037 elseif ($this->data[$this->position] === "\x0A")
8041 $this->position += strspn($this->data, "\x09\x20", $this->position);
8042 } while ($this->has_data() && $this->is_linear_whitespace());
8043 $this->value .= "\x20";
8047 * See what state to move to while within non-quoted header values
8053 if ($this->is_linear_whitespace())
8055 $this->linear_whitespace();
8059 switch ($this->data[$this->position])
8063 $this->state = 'quote';
8068 $this->state = 'new_line';
8072 $this->state = 'value_char';
8079 * Parse a header value while outside quotes
8083 function value_char()
8085 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8086 $this->value .= substr($this->data, $this->position, $len);
8087 $this->position += $len;
8088 $this->state = 'value';
8092 * See what state to move to while within quoted header values
8098 if ($this->is_linear_whitespace())
8100 $this->linear_whitespace();
8104 switch ($this->data[$this->position])
8108 $this->state = 'value';
8113 $this->state = 'new_line';
8118 $this->state = 'quote_escaped';
8122 $this->state = 'quote_char';
8129 * Parse a header value while within quotes
8133 function quote_char()
8135 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8136 $this->value .= substr($this->data, $this->position, $len);
8137 $this->position += $len;
8138 $this->state = 'value';
8142 * Parse an escaped character within quotes
8146 function quote_escaped()
8148 $this->value .= $this->data[$this->position];
8150 $this->state = 'quote';
8160 $this->body = substr($this->data, $this->position);
8161 $this->state = 'emit';
8165 class SimplePie_Cache
8168 * Don't call the constructor. Please.
8172 function SimplePie_Cache()
8174 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8178 * Create a new SimplePie_Cache object
8183 function create($location, $filename, $extension)
8185 return new SimplePie_Cache_File($location, $filename, $extension);
8189 class SimplePie_Cache_File
8196 function SimplePie_Cache_File($location, $filename, $extension)
8198 $this->location = $location;
8199 $this->filename = rawurlencode($filename);
8200 $this->extension = rawurlencode($extension);
8201 $this->name = "$location/$this->filename.$this->extension";
8204 function save($data)
8206 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8208 if (is_a($data, 'SimplePie'))
8210 $data = $data->data;
8213 $data = serialize($data);
8215 if (function_exists('file_put_contents'))
8217 return (bool) file_put_contents($this->name, $data);
8221 $fp = fopen($this->name, 'wb');
8235 if (file_exists($this->name) && is_readable($this->name))
8237 return unserialize(file_get_contents($this->name));
8244 if (file_exists($this->name))
8246 return filemtime($this->name);
8253 if (file_exists($this->name))
8255 return touch($this->name);
8262 if (file_exists($this->name))
8264 return unlink($this->name);
8270 class SimplePie_Misc
8272 function time_hms($seconds)
8276 $hours = floor($seconds / 3600);
8277 $remainder = $seconds % 3600;
8280 $time .= $hours.':';
8283 $minutes = floor($remainder / 60);
8284 $seconds = $remainder % 60;
8285 if ($minutes < 10 && $hours > 0)
8287 $minutes = '0' . $minutes;
8291 $seconds = '0' . $seconds;
8294 $time .= $minutes.':';
8300 function absolutize_url($relative, $base)
8302 if ($relative !== '')
8304 $relative = SimplePie_Misc::parse_url($relative);
8305 if ($relative['scheme'] !== '')
8307 $target = $relative;
8309 elseif ($base !== '')
8311 $base = SimplePie_Misc::parse_url($base);
8312 $target = SimplePie_Misc::parse_url('');
8313 if ($relative['authority'] !== '')
8315 $target = $relative;
8316 $target['scheme'] = $base['scheme'];
8320 $target['scheme'] = $base['scheme'];
8321 $target['authority'] = $base['authority'];
8322 if ($relative['path'] !== '')
8324 if (strpos($relative['path'], '/') === 0)
8326 $target['path'] = $relative['path'];
8328 elseif ($base['authority'] !== '' && $base['path'] === '')
8330 $target['path'] = '/' . $relative['path'];
8332 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8334 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8338 $target['path'] = $relative['path'];
8340 $target['query'] = $relative['query'];
8344 $target['path'] = $base['path'];
8345 if ($relative['query'] !== '')
8347 $target['query'] = $relative['query'];
8349 elseif ($base['query'] !== '')
8351 $target['query'] = $base['query'];
8355 $target['fragment'] = $relative['fragment'];
8359 // No base URL, just return the relative URL
8360 $target = $relative;
8362 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8368 $return = SimplePie_Misc::normalize_url($return);
8372 function remove_dot_segments($input)
8375 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8377 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8378 if (strpos($input, '../') === 0)
8380 $input = substr($input, 3);
8382 elseif (strpos($input, './') === 0)
8384 $input = substr($input, 2);
8386 // 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,
8387 elseif (strpos($input, '/./') === 0)
8389 $input = substr_replace($input, '/', 0, 3);
8391 elseif ($input == '/.')
8395 // 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,
8396 elseif (strpos($input, '/../') === 0)
8398 $input = substr_replace($input, '/', 0, 4);
8399 $output = substr_replace($output, '', strrpos($output, '/'));
8401 elseif ($input == '/..')
8404 $output = substr_replace($output, '', strrpos($output, '/'));
8406 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8407 elseif ($input == '.' || $input == '..')
8411 // 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
8412 elseif (($pos = strpos($input, '/', 1)) !== false)
8414 $output .= substr($input, 0, $pos);
8415 $input = substr_replace($input, '', 0, $pos);
8423 return $output . $input;
8426 function get_element($realname, $string)
8429 $name = preg_quote($realname, '/');
8430 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8432 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8434 $return[$i]['tag'] = $realname;
8435 $return[$i]['full'] = $matches[$i][0][0];
8436 $return[$i]['offset'] = $matches[$i][0][1];
8437 if (strlen($matches[$i][3][0]) <= 2)
8439 $return[$i]['self_closing'] = true;
8443 $return[$i]['self_closing'] = false;
8444 $return[$i]['content'] = $matches[$i][4][0];
8446 $return[$i]['attribs'] = array();
8447 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))
8449 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8451 if (count($attribs[$j]) == 2)
8453 $attribs[$j][2] = $attribs[$j][1];
8455 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8463 function element_implode($element)
8465 $full = "<$element[tag]";
8466 foreach ($element['attribs'] as $key => $value)
8468 $key = strtolower($key);
8469 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8471 if ($element['self_closing'])
8477 $full .= ">$element[content]</$element[tag]>";
8482 function error($message, $level, $file, $line)
8487 $note = 'PHP Error';
8489 case E_USER_WARNING:
8490 $note = 'PHP Warning';
8493 $note = 'PHP Notice';
8496 $note = 'Unknown Error';
8499 error_log("$note: $message in $file on line $line", 0);
8504 * If a file has been cached, retrieve and display it.
8506 * This is most useful for caching images (get_favicon(), etc.),
8507 * however it works for all cached files. This WILL NOT display ANY
8508 * file/image/page/whatever, but rather only display what has already
8509 * been cached by SimplePie.
8512 * @see SimplePie::get_favicon()
8513 * @param str $identifier_url URL that is used to identify the content.
8514 * This may or may not be the actual URL of the live content.
8515 * @param str $cache_location Location of SimplePie's cache. Defaults
8517 * @param str $cache_extension The file extension that the file was
8518 * cached with. Defaults to 'spc'.
8519 * @param str $cache_class Name of the cache-handling class being used
8520 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8521 * as-is unless you've overloaded the class.
8522 * @param str $cache_name_function Obsolete. Exists for backwards
8523 * compatibility reasons only.
8525 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8527 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8529 if ($file = $cache->load())
8531 if (isset($file['headers']['content-type']))
8533 header('Content-type:' . $file['headers']['content-type']);
8537 header('Content-type: application/octet-stream');
8539 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8544 die('Cached file for ' . $identifier_url . ' cannot be found.');
8547 function fix_protocol($url, $http = 1)
8549 $url = SimplePie_Misc::normalize_url($url);
8550 $parsed = SimplePie_Misc::parse_url($url);
8551 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8553 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8556 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8558 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8561 if ($http == 2 && $parsed['scheme'] !== '')
8565 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8567 return substr_replace($url, 'podcast', 0, 4);
8569 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8571 return substr_replace($url, 'itpc', 0, 4);
8579 function parse_url($url)
8581 static $cache = array();
8582 if (isset($cache[$url]))
8584 return $cache[$url];
8586 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8588 for ($i = count($match); $i <= 9; $i++)
8592 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8596 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8600 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8605 $return .= "$scheme:";
8607 if ($authority !== '')
8609 $return .= "//$authority";
8617 $return .= "?$query";
8619 if ($fragment !== '')
8621 $return .= "#$fragment";
8626 function normalize_url($url)
8628 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8629 $url = SimplePie_Misc::parse_url($url);
8630 $url['scheme'] = strtolower($url['scheme']);
8631 if ($url['authority'] !== '')
8633 $url['authority'] = strtolower($url['authority']);
8634 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8636 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
8639 function percent_encoding_normalization($match)
8641 $integer = hexdec($match[1]);
8642 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
8644 return chr($integer);
8648 return strtoupper($match[0]);
8653 * Remove bad UTF-8 bytes
8655 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
8656 * FAQ: Multilingual Forms (modified to include full ASCII range)
8658 * @author Geoffrey Sneddon
8659 * @see http://www.w3.org/International/questions/qa-forms-utf-8
8660 * @param string $str String to remove bad UTF-8 bytes from
8661 * @return string UTF-8 string
8663 function utf8_bad_replace($str)
8665 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
8669 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
8673 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))
8675 return implode("\xEF\xBF\xBD", $matches[0]);
8677 elseif ($str !== '')
8679 return "\xEF\xBF\xBD";
8688 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8692 * @param string $string Windows-1252 encoded string
8693 * @return string UTF-8 encoded string
8695 function windows_1252_to_utf8($string)
8697 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");
8699 return strtr($string, $convert_table);
8702 function change_encoding($data, $input, $output)
8704 $input = SimplePie_Misc::encoding($input);
8705 $output = SimplePie_Misc::encoding($output);
8707 // We fail to fail on non US-ASCII bytes
8708 if ($input === 'US-ASCII')
8710 static $non_ascii_octects = '';
8711 if (!$non_ascii_octects)
8713 for ($i = 0x80; $i <= 0xFF; $i++)
8715 $non_ascii_octects .= chr($i);
8718 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8721 if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
8725 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
8729 elseif ($input == 'windows-1252' && $output == 'UTF-8')
8731 return SimplePie_Misc::windows_1252_to_utf8($data);
8733 elseif ($input == 'UTF-8' && $output == 'windows-1252')
8735 return utf8_decode($data);
8740 function encoding($encoding)
8742 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
8743 switch (strtoupper($encoding))
8745 case 'ANSI_X3.110-1983':
8746 case 'CSA_T500-1983':
8747 case 'CSISO99NAPLPS':
8750 return 'ANSI_X3.110-1983';
8754 case 'CSISO89ASMO449':
8759 case 'ADOBE-STANDARD-ENCODING':
8760 case 'CSADOBESTANDARDENCODING':
8761 return 'Adobe-Standard-Encoding';
8763 case 'ADOBE-SYMBOL-ENCODING':
8765 return 'Adobe-Symbol-Encoding';
8771 return 'Amiga-1251';
8782 case 'CSISO4UNITEDKINGDOM':
8790 case 'CSISO47BSVIEWDATA':
8792 return 'BS_viewdata';
8799 return 'Big5-HKSCS';
8807 case 'CSA_Z243.4-1985-1':
8808 case 'CSISO121CANADIAN1':
8811 return 'CSA_Z243.4-1985-1';
8814 case 'CSA_Z243.4-1985-2':
8815 case 'CSISO122CANADIAN2':
8818 return 'CSA_Z243.4-1985-2';
8820 case 'CSA_Z243.4-1985-GR':
8821 case 'CSISO123CSAZ24341985GR':
8823 return 'CSA_Z243.4-1985-gr';
8825 case 'CSISO139CSN369103':
8828 return 'CSN_369103';
8835 case 'CSISO21GERMAN':
8842 case 'CSISO646DANISH':
8849 case 'CSIBMEBCDICATDE':
8850 case 'EBCDIC-AT-DE':
8851 return 'EBCDIC-AT-DE';
8853 case 'CSEBCDICATDEA':
8854 case 'EBCDIC-AT-DE-A':
8855 return 'EBCDIC-AT-DE-A';
8857 case 'CSEBCDICCAFR':
8858 case 'EBCDIC-CA-FR':
8859 return 'EBCDIC-CA-FR';
8861 case 'CSEBCDICDKNO':
8862 case 'EBCDIC-DK-NO':
8863 return 'EBCDIC-DK-NO';
8865 case 'CSEBCDICDKNOA':
8866 case 'EBCDIC-DK-NO-A':
8867 return 'EBCDIC-DK-NO-A';
8875 return 'EBCDIC-ES-A';
8879 return 'EBCDIC-ES-S';
8881 case 'CSEBCDICFISE':
8882 case 'EBCDIC-FI-SE':
8883 return 'EBCDIC-FI-SE';
8885 case 'CSEBCDICFISEA':
8886 case 'EBCDIC-FI-SE-A':
8887 return 'EBCDIC-FI-SE-A';
8909 case 'CSISO111ECMACYRILLIC':
8910 case 'ECMA-CYRILLIC':
8913 return 'ECMA-cyrillic';
8915 case 'CSISO17SPANISH':
8921 case 'CSISO85SPANISH2':
8927 case 'CSEUCPKDFMTJAPANESE':
8929 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
8936 case 'CSEUCFIXWIDJAPANESE':
8937 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
8938 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
8954 case 'CSISO57GB1988':
8958 return 'GB_1988-80';
8961 case 'CSISO58GB231280':
8964 return 'GB_2312-80';
8966 case 'CSISO153GOST1976874':
8967 case 'GOST_19768-74':
8969 case 'ST_SEV_358-88':
8970 return 'GOST_19768-74';
8974 return 'HP-DeskTop';
8986 return 'HP-Pi-font';
8989 return 'HZ-GB-2312';
8991 case 'CSIBMSYMBOLS':
8993 return 'IBM-Symbols';
9002 case 'PC-MULTILINGUAL-850+EURO':
9007 case 'EBCDIC-LATIN9--EURO':
9013 case 'EBCDIC-US-37+EURO':
9019 case 'EBCDIC-DE-273+EURO':
9025 case 'EBCDIC-DK-277+EURO':
9026 case 'EBCDIC-NO-277+EURO':
9032 case 'EBCDIC-FI-278+EURO':
9033 case 'EBCDIC-SE-278+EURO':
9039 case 'EBCDIC-IT-280+EURO':
9045 case 'EBCDIC-ES-284+EURO':
9051 case 'EBCDIC-GB-285+EURO':
9057 case 'EBCDIC-FR-297+EURO':
9063 case 'EBCDIC-INTERNATIONAL-500+EURO':
9069 case 'EBCDIC-IS-871+EURO':
9075 case 'EBCDIC-CP-CA':
9076 case 'EBCDIC-CP-NL':
9077 case 'EBCDIC-CP-US':
9078 case 'EBCDIC-CP-WT':
9115 case 'EBCDIC-CP-DK':
9116 case 'EBCDIC-CP-NO':
9122 case 'EBCDIC-CP-FI':
9123 case 'EBCDIC-CP-SE':
9129 case 'EBCDIC-CP-IT':
9141 case 'EBCDIC-CP-ES':
9147 case 'EBCDIC-CP-GB':
9153 case 'EBCDIC-JP-KANA':
9159 case 'EBCDIC-CP-FR':
9165 case 'EBCDIC-CP-AR1':
9171 case 'EBCDIC-CP-GR':
9177 case 'EBCDIC-CP-HE':
9183 case 'CSPC8CODEPAGE437':
9189 case 'EBCDIC-CP-BE':
9190 case 'EBCDIC-CP-CH':
9195 case 'CSPC775BALTIC':
9201 case 'CSPC850MULTILINGUAL':
9244 case 'CSPC862LATINHEBREW':
9286 case 'EBCDIC-CP-ROECE':
9287 case 'EBCDIC-CP-YU':
9293 case 'EBCDIC-CP-IS':
9299 case 'EBCDIC-CYRILLIC':
9321 case 'EBCDIC-CP-TR':
9327 case 'EBCDIC-CP-AR2':
9331 case 'CSISO143IECP271':
9341 case 'CSISO50INIS8':
9346 case 'CSISO51INISCYRILLIC':
9347 case 'INIS-CYRILLIC':
9349 return 'INIS-cyrillic';
9355 case 'ISO-10646-J-1':
9356 return 'ISO-10646-J-1';
9359 case 'ISO-10646-UCS-2':
9360 return 'ISO-10646-UCS-2';
9363 case 'ISO-10646-UCS-4':
9364 return 'ISO-10646-UCS-4';
9366 case 'CSUNICODEASCII':
9367 case 'ISO-10646-UCS-BASIC':
9368 return 'ISO-10646-UCS-Basic';
9370 case 'CSISO10646UTF1':
9371 case 'ISO-10646-UTF-1':
9372 return 'ISO-10646-UTF-1';
9374 case 'CSUNICODELATIN1':
9376 case 'ISO-10646-UNICODE-LATIN1':
9377 return 'ISO-10646-Unicode-Latin1';
9382 case 'ISO_TR_11548-1':
9383 return 'ISO-11548-1';
9386 return 'ISO-2022-CN';
9388 case 'ISO-2022-CN-EXT':
9389 return 'ISO-2022-CN-EXT';
9393 return 'ISO-2022-JP';
9395 case 'CSISO2022JP2':
9396 case 'ISO-2022-JP-2':
9397 return 'ISO-2022-JP-2';
9401 return 'ISO-2022-KR';
9403 case 'CSWINDOWS30LATIN1':
9404 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
9405 return 'ISO-8859-1-Windows-3.0-Latin-1';
9407 case 'CSWINDOWS31LATIN1':
9408 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
9409 return 'ISO-8859-1-Windows-3.1-Latin-1';
9414 case 'ISO_8859-10:1992':
9417 return 'ISO-8859-10';
9420 return 'ISO-8859-13';
9426 case 'ISO_8859-14:1998':
9429 return 'ISO-8859-14';
9434 return 'ISO-8859-15';
9439 case 'ISO_8859-16:2001':
9442 return 'ISO-8859-16';
9448 case 'ISO_8859-2:1987':
9451 return 'ISO-8859-2';
9453 case 'CSWINDOWS31LATIN2':
9454 case 'ISO-8859-2-WINDOWS-LATIN-2':
9455 return 'ISO-8859-2-Windows-Latin-2';
9461 case 'ISO_8859-3:1988':
9464 return 'ISO-8859-3';
9470 case 'ISO_8859-4:1988':
9473 return 'ISO-8859-4';
9475 case 'CSISOLATINCYRILLIC':
9480 case 'ISO_8859-5:1988':
9481 return 'ISO-8859-5';
9485 case 'CSISOLATINARABIC':
9490 case 'ISO_8859-6:1987':
9491 return 'ISO-8859-6';
9494 case 'ISO-8859-6-E':
9495 case 'ISO_8859-6-E':
9496 return 'ISO-8859-6-E';
9499 case 'ISO-8859-6-I':
9500 case 'ISO_8859-6-I':
9501 return 'ISO-8859-6-I';
9503 case 'CSISOLATINGREEK':
9511 case 'ISO_8859-7:1987':
9512 return 'ISO-8859-7';
9514 case 'CSISOLATINHEBREW':
9519 case 'ISO_8859-8:1988':
9520 return 'ISO-8859-8';
9523 case 'ISO-8859-8-E':
9524 case 'ISO_8859-8-E':
9525 return 'ISO-8859-8-E';
9528 case 'ISO-8859-8-I':
9529 case 'ISO_8859-8-I':
9530 return 'ISO-8859-8-I';
9536 case 'ISO_8859-9:1989':
9539 return 'ISO-8859-9';
9541 case 'CSWINDOWS31LATIN5':
9542 case 'ISO-8859-9-WINDOWS-LATIN-5':
9543 return 'ISO-8859-9-Windows-Latin-5';
9545 case 'CSUNICODEIBM1261':
9546 case 'ISO-UNICODE-IBM-1261':
9547 return 'ISO-Unicode-IBM-1261';
9549 case 'CSUNICODEIBM1264':
9550 case 'ISO-UNICODE-IBM-1264':
9551 return 'ISO-Unicode-IBM-1264';
9553 case 'CSUNICODEIBM1265':
9554 case 'ISO-UNICODE-IBM-1265':
9555 return 'ISO-Unicode-IBM-1265';
9557 case 'CSUNICODEIBM1268':
9558 case 'ISO-UNICODE-IBM-1268':
9559 return 'ISO-Unicode-IBM-1268';
9561 case 'CSUNICODEIBM1276':
9562 case 'ISO-UNICODE-IBM-1276':
9563 return 'ISO-Unicode-IBM-1276';
9565 case 'CSISO10367BOX':
9567 case 'ISO_10367-BOX':
9568 return 'ISO_10367-box';
9573 case 'ISO_2033-1983':
9574 return 'ISO_2033-1983';
9576 case 'CSISO5427CYRILLIC':
9582 case 'ISO5427CYRILLIC1981':
9583 case 'ISO_5427:1981':
9584 return 'ISO_5427:1981';
9586 case 'CSISO5428GREEK':
9588 case 'ISO_5428:1980':
9589 return 'ISO_5428:1980';
9591 case 'CSISO646BASIC1983':
9592 case 'ISO_646.BASIC:1983':
9594 return 'ISO_646.basic:1983';
9596 case 'CSISO2INTLREFVERSION':
9599 case 'ISO_646.IRV:1983':
9600 return 'ISO_646.irv:1983';
9602 case 'CSISO6937ADD':
9604 case 'ISO_6937-2-25':
9605 return 'ISO_6937-2-25';
9607 case 'CSISOTEXTCOMM':
9609 case 'ISO_6937-2-ADD':
9610 return 'ISO_6937-2-add';
9612 case 'CSISO8859SUPP':
9614 case 'ISO_8859-SUPP':
9616 return 'ISO_8859-supp';
9618 case 'CSISO15ITALIAN':
9624 case 'CSISO13JISC6220JP':
9626 case 'JIS_C6220-1969':
9627 case 'JIS_C6220-1969-JP':
9630 return 'JIS_C6220-1969-jp';
9632 case 'CSISO14JISC6220RO':
9635 case 'JIS_C6220-1969-RO':
9637 return 'JIS_C6220-1969-ro';
9639 case 'CSISO42JISC62261978':
9641 case 'JIS_C6226-1978':
9642 return 'JIS_C6226-1978';
9644 case 'CSISO87JISX0208':
9646 case 'JIS_C6226-1983':
9647 case 'JIS_X0208-1983':
9649 return 'JIS_C6226-1983';
9651 case 'CSISO91JISC62291984A':
9653 case 'JIS_C6229-1984-A':
9655 return 'JIS_C6229-1984-a';
9657 case 'CSISO92JISC62991984B':
9659 case 'ISO646-JP-OCR-B':
9660 case 'JIS_C6229-1984-B':
9662 return 'JIS_C6229-1984-b';
9664 case 'CSISO93JIS62291984BADD':
9666 case 'JIS_C6229-1984-B-ADD':
9667 case 'JP-OCR-B-ADD':
9668 return 'JIS_C6229-1984-b-add';
9670 case 'CSISO94JIS62291984HAND':
9672 case 'JIS_C6229-1984-HAND':
9674 return 'JIS_C6229-1984-hand';
9676 case 'CSISO95JIS62291984HANDADD':
9678 case 'JIS_C6229-1984-HAND-ADD':
9679 case 'JP-OCR-HAND-ADD':
9680 return 'JIS_C6229-1984-hand-add';
9682 case 'CSISO96JISC62291984KANA':
9684 case 'JIS_C6229-1984-KANA':
9685 return 'JIS_C6229-1984-kana';
9687 case 'CSJISENCODING':
9688 case 'JIS_ENCODING':
9689 return 'JIS_Encoding';
9691 case 'CSHALFWIDTHKATAKANA':
9696 case 'CSISO159JISX02121990':
9698 case 'JIS_X0212-1990':
9700 return 'JIS_X0212-1990';
9702 case 'CSISO141JUSIB1002':
9706 case 'JUS_I.B1.002':
9708 return 'JUS_I.B1.002';
9710 case 'CSISO147MACEDONIAN':
9712 case 'JUS_I.B1.003-MAC':
9714 return 'JUS_I.B1.003-mac';
9716 case 'CSISO146SERBIAN':
9718 case 'JUS_I.B1.003-SERB':
9720 return 'JUS_I.B1.003-serb';
9722 case 'KOI7-SWITCHED':
9723 return 'KOI7-switched';
9737 case 'CSKSC56011987':
9741 case 'KS_C_5601-1987':
9742 case 'KS_C_5601-1989':
9743 return 'KS_C_5601-1987';
9748 case 'STRK1048-2002':
9751 case 'CSISO27LATINGREEK1':
9753 case 'LATIN-GREEK-1':
9754 return 'Latin-greek-1';
9764 case 'CSISO86HUNGARIAN':
9769 return 'MSZ_7795.3';
9771 case 'CSMICROSOFTPUBLISHING':
9772 case 'MICROSOFT-PUBLISHING':
9773 return 'Microsoft-Publishing';
9780 case 'CSNATSDANOADD':
9782 case 'NATS-DANO-ADD':
9783 return 'NATS-DANO-ADD';
9790 case 'CSNATSSEFIADD':
9792 case 'NATS-SEFI-ADD':
9793 return 'NATS-SEFI-ADD';
9795 case 'CSISO151CUBA':
9799 case 'NC_NC00-10:81':
9800 return 'NC_NC00-10:81';
9802 case 'CSISO69FRENCH':
9807 return 'NF_Z_62-010';
9809 case 'CSISO25FRENCH':
9812 case 'NF_Z_62-010_(1973)':
9813 return 'NF_Z_62-010_(1973)';
9815 case 'CSISO60DANISHNORWEGIAN':
9816 case 'CSISO60NORWEGIAN1':
9823 case 'CSISO61NORWEGIAN2':
9830 case 'OSD_EBCDIC_DF03_IRV':
9831 return 'OSD_EBCDIC_DF03_IRV';
9833 case 'OSD_EBCDIC_DF04_1':
9834 return 'OSD_EBCDIC_DF04_1';
9836 case 'OSD_EBCDIC_DF04_15':
9837 return 'OSD_EBCDIC_DF04_15';
9839 case 'CSPC8DANISHNORWEGIAN':
9840 case 'PC8-DANISH-NORWEGIAN':
9841 return 'PC8-Danish-Norwegian';
9843 case 'CSPC8TURKISH':
9845 return 'PC8-Turkish';
9847 case 'CSISO16PORTUGUESE':
9853 case 'CSISO84PORTUGUESE2':
9861 case 'CYRILLIC-ASIAN':
9869 case 'CSISO10SWEDISH':
9875 case 'SEN_850200_B':
9876 return 'SEN_850200_B';
9878 case 'CSISO11SWEDISHFORNAMES':
9882 case 'SEN_850200_C':
9883 return 'SEN_850200_C';
9890 case 'CSISO128T101G2':
9895 case 'CSISO102T617BIT':
9900 case 'CSISO103T618BIT':
9912 return 'UNICODE-1-1';
9914 case 'CSUNICODE11UTF7':
9915 case 'UNICODE-1-1-UTF-7':
9916 return 'UNICODE-1-1-UTF-7';
9918 case 'CSUNKNOWN8BIT':
9919 case 'UNKNOWN-8BIT':
9920 return 'UNKNOWN-8BIT';
9923 case 'ANSI_X3.4-1968':
9924 case 'ANSI_X3.4-1986':
9931 case 'ISO_646.IRV:1991':
9968 case 'CSVENTURAINTERNATIONAL':
9969 case 'VENTURA-INTERNATIONAL':
9970 return 'Ventura-International';
9972 case 'CSVENTURAMATH':
9973 case 'VENTURA-MATH':
9974 return 'Ventura-Math';
9978 return 'Ventura-US';
9980 case 'CSWINDOWS31J':
9982 return 'Windows-31J';
9989 case 'CSISO150GREEKCCITT':
9992 return 'greek-ccitt';
9994 case 'CSISO88GREEK7':
9999 case 'CSISO18GREEK7OLD':
10002 return 'greek7-old';
10008 return 'hp-roman8';
10012 return 'iso-ir-90';
10014 case 'CSISO19LATINGREEK':
10016 case 'LATIN-GREEK':
10017 return 'latin-greek';
10019 case 'CSISO158LAP':
10023 return 'latin-lap';
10025 case 'CSMACINTOSH':
10028 return 'macintosh';
10034 case 'CSISO70VIDEOTEXSUPP1':
10036 case 'VIDEOTEX-SUPPL':
10037 return 'videotex-suppl';
10039 case 'WINDOWS-1250':
10040 return 'windows-1250';
10042 case 'WINDOWS-1251':
10043 return 'windows-1251';
10046 case 'CSISOLATIN1':
10051 case 'ISO_8859-1:1987':
10054 case 'WINDOWS-1252':
10055 return 'windows-1252';
10057 case 'WINDOWS-1253':
10058 return 'windows-1253';
10060 case 'WINDOWS-1254':
10061 return 'windows-1254';
10063 case 'WINDOWS-1255':
10064 return 'windows-1255';
10066 case 'WINDOWS-1256':
10067 return 'windows-1256';
10069 case 'WINDOWS-1257':
10070 return 'windows-1257';
10072 case 'WINDOWS-1258':
10073 return 'windows-1258';
10080 function get_curl_version()
10082 if (is_array($curl = curl_version()))
10084 $curl = $curl['version'];
10086 elseif (substr($curl, 0, 5) == 'curl/')
10088 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10090 elseif (substr($curl, 0, 8) == 'libcurl/')
10092 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10101 function is_subclass_of($class1, $class2)
10103 if (func_num_args() != 2)
10105 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10107 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10109 return is_subclass_of($class1, $class2);
10111 elseif (is_string($class1) && is_string($class2))
10113 if (class_exists($class1))
10115 if (class_exists($class2))
10117 $class2 = strtolower($class2);
10118 while ($class1 = strtolower(get_parent_class($class1)))
10120 if ($class1 == $class2)
10129 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10136 * Strip HTML comments
10139 * @param string $data Data to strip comments from
10140 * @return string Comment stripped string
10142 function strip_comments($data)
10145 while (($start = strpos($data, '<!--')) !== false)
10147 $output .= substr($data, 0, $start);
10148 if (($end = strpos($data, '-->', $start)) !== false)
10150 $data = substr_replace($data, '', 0, $end + 3);
10157 return $output . $data;
10160 function parse_date($dt)
10162 $parser = SimplePie_Parse_Date::get();
10163 return $parser->parse($dt);
10167 * Decode HTML entities
10171 * @param string $data Input data
10172 * @return string Output data
10174 function entities_decode($data)
10176 $decoder = new SimplePie_Decode_HTML_Entities($data);
10177 return $decoder->parse();
10181 * Remove RFC822 comments
10184 * @param string $data Data to strip comments from
10185 * @return string Comment stripped string
10187 function uncomment_rfc822($string)
10189 $string = (string) $string;
10191 $length = strlen($string);
10196 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10198 $output .= substr($string, $position, $pos - $position);
10199 $position = $pos + 1;
10200 if ($string[$pos - 1] !== '\\')
10203 while ($depth && $position < $length)
10205 $position += strcspn($string, '()', $position);
10206 if ($string[$position - 1] === '\\')
10211 elseif (isset($string[$position]))
10213 switch ($string[$position])
10236 $output .= substr($string, $position);
10241 function parse_mime($mime)
10243 if (($pos = strpos($mime, ';')) === false)
10245 return trim($mime);
10249 return trim(substr($mime, 0, $pos));
10253 function htmlspecialchars_decode($string, $quote_style)
10255 if (function_exists('htmlspecialchars_decode'))
10257 return htmlspecialchars_decode($string, $quote_style);
10261 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10265 function atom_03_construct_type($attribs)
10267 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10269 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10273 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10275 if (isset($attribs['']['type']))
10277 switch (strtolower(trim($attribs['']['type'])))
10281 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10285 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10288 case 'application/xhtml+xml':
10289 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10292 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10297 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10301 function atom_10_construct_type($attribs)
10303 if (isset($attribs['']['type']))
10305 switch (strtolower(trim($attribs['']['type'])))
10308 return SIMPLEPIE_CONSTRUCT_TEXT;
10311 return SIMPLEPIE_CONSTRUCT_HTML;
10314 return SIMPLEPIE_CONSTRUCT_XHTML;
10317 return SIMPLEPIE_CONSTRUCT_NONE;
10320 return SIMPLEPIE_CONSTRUCT_TEXT;
10323 function atom_10_content_construct_type($attribs)
10325 if (isset($attribs['']['type']))
10327 $type = strtolower(trim($attribs['']['type']));
10331 return SIMPLEPIE_CONSTRUCT_TEXT;
10334 return SIMPLEPIE_CONSTRUCT_HTML;
10337 return SIMPLEPIE_CONSTRUCT_XHTML;
10339 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10341 return SIMPLEPIE_CONSTRUCT_NONE;
10345 return SIMPLEPIE_CONSTRUCT_BASE64;
10350 return SIMPLEPIE_CONSTRUCT_TEXT;
10354 function is_isegment_nz_nc($string)
10356 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);
10359 function space_seperated_tokens($string)
10361 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10362 $string_length = strlen($string);
10364 $position = strspn($string, $space_characters);
10367 while ($position < $string_length)
10369 $len = strcspn($string, $space_characters, $position);
10370 $tokens[] = substr($string, $position, $len);
10372 $position += strspn($string, $space_characters, $position);
10378 function array_unique($array)
10380 if (version_compare(PHP_VERSION, '5.2', '>='))
10382 return array_unique($array);
10386 $array = (array) $array;
10387 $new_array = array();
10388 $new_array_strings = array();
10389 foreach ($array as $key => $value)
10391 if (is_object($value))
10393 if (method_exists($value, '__toString'))
10395 $cmp = $value->__toString();
10399 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10402 elseif (is_array($value))
10404 $cmp = (string) reset($value);
10408 $cmp = (string) $value;
10410 if (!in_array($cmp, $new_array_strings))
10412 $new_array[$key] = $value;
10413 $new_array_strings[] = $cmp;
10421 * Converts a unicode codepoint to a UTF-8 character
10425 * @param int $codepoint Unicode codepoint
10426 * @return string UTF-8 character
10428 function codepoint_to_utf8($codepoint)
10430 static $cache = array();
10431 $codepoint = (int) $codepoint;
10432 if (isset($cache[$codepoint]))
10434 return $cache[$codepoint];
10436 elseif ($codepoint < 0)
10438 return $cache[$codepoint] = false;
10440 else if ($codepoint <= 0x7f)
10442 return $cache[$codepoint] = chr($codepoint);
10444 else if ($codepoint <= 0x7ff)
10446 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10448 else if ($codepoint <= 0xffff)
10450 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10452 else if ($codepoint <= 0x10ffff)
10454 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10458 // U+FFFD REPLACEMENT CHARACTER
10459 return $cache[$codepoint] = "\xEF\xBF\xBD";
10464 * Re-implementation of PHP 5's stripos()
10466 * Returns the numeric position of the first occurrence of needle in the
10471 * @param object $haystack
10472 * @param string $needle Note that the needle may be a string of one or more
10473 * characters. If needle is not a string, it is converted to an integer
10474 * and applied as the ordinal value of a character.
10475 * @param int $offset The optional offset parameter allows you to specify which
10476 * character in haystack to start searching. The position returned is still
10477 * relative to the beginning of haystack.
10478 * @return bool If needle is not found, stripos() will return boolean false.
10480 function stripos($haystack, $needle, $offset = 0)
10482 if (function_exists('stripos'))
10484 return stripos($haystack, $needle, $offset);
10488 if (is_string($needle))
10490 $needle = strtolower($needle);
10492 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10494 $needle = strtolower(chr($needle));
10498 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10502 return strpos(strtolower($haystack), $needle, $offset);
10507 * Similar to parse_str()
10509 * Returns an associative array of name/value pairs, where the value is an
10510 * array of values that have used the same name
10514 * @param string $str The input string.
10517 function parse_str($str)
10520 $str = explode('&', $str);
10522 foreach ($str as $section)
10524 if (strpos($section, '=') !== false)
10526 list($name, $value) = explode('=', $section, 2);
10527 $return[urldecode($name)][] = urldecode($value);
10531 $return[urldecode($section)][] = null;
10539 * Detect XML encoding, as per XML 1.0 Appendix F.1
10541 * @todo Add support for EBCDIC
10542 * @param string $data XML data
10543 * @return array Possible encodings
10545 function xml_encoding($data)
10547 // UTF-32 Big Endian BOM
10548 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10550 $encoding[] = 'UTF-32BE';
10552 // UTF-32 Little Endian BOM
10553 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10555 $encoding[] = 'UTF-32LE';
10557 // UTF-16 Big Endian BOM
10558 elseif (substr($data, 0, 2) === "\xFE\xFF")
10560 $encoding[] = 'UTF-16BE';
10562 // UTF-16 Little Endian BOM
10563 elseif (substr($data, 0, 2) === "\xFF\xFE")
10565 $encoding[] = 'UTF-16LE';
10568 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10570 $encoding[] = 'UTF-8';
10572 // UTF-32 Big Endian Without BOM
10573 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")
10575 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10577 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10578 if ($parser->parse())
10580 $encoding[] = $parser->encoding;
10583 $encoding[] = 'UTF-32BE';
10585 // UTF-32 Little Endian Without BOM
10586 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")
10588 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10590 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10591 if ($parser->parse())
10593 $encoding[] = $parser->encoding;
10596 $encoding[] = 'UTF-32LE';
10598 // UTF-16 Big Endian Without BOM
10599 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10601 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10603 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10604 if ($parser->parse())
10606 $encoding[] = $parser->encoding;
10609 $encoding[] = 'UTF-16BE';
10611 // UTF-16 Little Endian Without BOM
10612 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10614 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10616 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10617 if ($parser->parse())
10619 $encoding[] = $parser->encoding;
10622 $encoding[] = 'UTF-16LE';
10624 // US-ASCII (or superset)
10625 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10627 if ($pos = strpos($data, "\x3F\x3E"))
10629 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10630 if ($parser->parse())
10632 $encoding[] = $parser->encoding;
10635 $encoding[] = 'UTF-8';
10637 // Fallback to UTF-8
10640 $encoding[] = 'UTF-8';
10647 * Decode HTML Entities
10649 * This implements HTML5 as of revision 967 (2007-06-28)
10651 * @package SimplePie
10653 class SimplePie_Decode_HTML_Entities
10656 * Data to be parsed
10664 * Currently consumed bytes
10669 var $consumed = '';
10672 * Position of the current byte being parsed
10680 * Create an instance of the class with the input data
10683 * @param string $data Input data
10685 function SimplePie_Decode_HTML_Entities($data)
10687 $this->data = $data;
10691 * Parse the input data
10694 * @return string Output data
10698 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
10702 $this->consumed = '';
10704 return $this->data;
10708 * Consume the next byte
10711 * @return mixed The next byte, or false, if there is no more data
10715 if (isset($this->data[$this->position]))
10717 $this->consumed .= $this->data[$this->position];
10718 return $this->data[$this->position++];
10722 $this->consumed = false;
10728 * Consume a range of characters
10731 * @param string $chars Characters to consume
10732 * @return mixed A series of characters that match the range, or false
10734 function consume_range($chars)
10736 if ($len = strspn($this->data, $chars, $this->position))
10738 $data = substr($this->data, $this->position, $len);
10739 $this->consumed .= $data;
10740 $this->position += $len;
10745 $this->consumed = false;
10751 * Unconsume one byte
10755 function unconsume()
10757 $this->consumed = substr($this->consumed, 0, -1);
10768 switch ($this->consume())
10782 switch ($this->consume())
10786 $range = '0123456789ABCDEFabcdef';
10791 $range = '0123456789';
10793 $this->unconsume();
10797 if ($codepoint = $this->consume_range($range))
10799 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");
10803 $codepoint = hexdec($codepoint);
10807 $codepoint = intval($codepoint);
10810 if (isset($windows_1252_specials[$codepoint]))
10812 $replacement = $windows_1252_specials[$codepoint];
10816 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
10819 if ($this->consume() != ';')
10821 $this->unconsume();
10824 $consumed_length = strlen($this->consumed);
10825 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
10826 $this->position += strlen($replacement) - $consumed_length;
10831 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");
10833 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
10835 $consumed = substr($this->consumed, 1);
10836 if (isset($entities[$consumed]))
10838 $match = $consumed;
10842 if ($match !== null)
10844 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
10845 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
10855 * @package SimplePie
10857 class SimplePie_Parse_Date
10862 * @access protected
10868 * List of days, calendar day name => ordinal day number in the week
10870 * @access protected
10933 'keskiviikko' => 3,
10957 * List of months, calendar month name => calendar month number
10959 * @access protected
10962 var $month = array(
10973 // No long form of May
11102 * List of timezones, abbreviation => offset from UTC
11104 * @access protected
11107 var $timezone = array(
11310 * Cached PCRE for SimplePie_Parse_Date::$day
11312 * @access protected
11318 * Cached PCRE for SimplePie_Parse_Date::$month
11320 * @access protected
11326 * Array of user-added callback methods
11331 var $built_in = array();
11334 * Array of user-added callback methods
11339 var $user = array();
11342 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11343 * self::month_pcre, and self::built_in
11347 function SimplePie_Parse_Date()
11349 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11350 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11353 if (!isset($cache[get_class($this)]))
11355 if (extension_loaded('Reflection'))
11357 $class = new ReflectionClass(get_class($this));
11358 $methods = $class->getMethods();
11359 $all_methods = array();
11360 foreach ($methods as $method)
11362 $all_methods[] = $method->getName();
11367 $all_methods = get_class_methods($this);
11370 foreach ($all_methods as $method)
11372 if (strtolower(substr($method, 0, 5)) === 'date_')
11374 $cache[get_class($this)][] = $method;
11379 foreach ($cache[get_class($this)] as $method)
11381 $this->built_in[] = $method;
11395 $object = new SimplePie_Parse_Date;
11405 * @param string $date Date to parse
11406 * @return int Timestamp corresponding to date string, or false on failure
11408 function parse($date)
11410 foreach ($this->user as $method)
11412 if (($returned = call_user_func($method, $date)) !== false)
11418 foreach ($this->built_in as $method)
11420 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11430 * Add a callback method to parse a date
11434 * @param callback $callback
11436 function add_callback($callback)
11438 if (is_callable($callback))
11440 $this->user[] = $callback;
11444 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11449 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11450 * well as allowing any of upper or lower case "T", horizontal tabs, or
11451 * spaces to be used as the time seperator (including more than one))
11453 * @access protected
11454 * @return int Timestamp
11456 function date_w3cdtf($date)
11461 $year = '([0-9]{4})';
11462 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11463 $decimal = '([0-9]*)';
11464 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11465 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11467 if (preg_match($pcre, $date, $match))
11470 Capturing subpatterns:
11477 7: Decimal fraction of a second
11481 11: Timezone minutes
11484 // Fill in empty matches
11485 for ($i = count($match); $i <= 3; $i++)
11490 for ($i = count($match); $i <= 7; $i++)
11495 // Numeric timezone
11496 if (isset($match[9]) && $match[9] !== '')
11498 $timezone = $match[10] * 3600;
11499 $timezone += $match[11] * 60;
11500 if ($match[9] === '-')
11502 $timezone = 0 - $timezone;
11510 // Convert the number of seconds to an integer, taking decimals into account
11511 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11513 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11522 * Remove RFC822 comments
11524 * @access protected
11525 * @param string $data Data to strip comments from
11526 * @return string Comment stripped string
11528 function remove_rfc2822_comments($string)
11530 $string = (string) $string;
11532 $length = strlen($string);
11537 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11539 $output .= substr($string, $position, $pos - $position);
11540 $position = $pos + 1;
11541 if ($string[$pos - 1] !== '\\')
11544 while ($depth && $position < $length)
11546 $position += strcspn($string, '()', $position);
11547 if ($string[$position - 1] === '\\')
11552 elseif (isset($string[$position]))
11554 switch ($string[$position])
11577 $output .= substr($string, $position);
11583 * Parse RFC2822's date format
11585 * @access protected
11586 * @return int Timestamp
11588 function date_rfc2822($date)
11593 $wsp = '[\x09\x20]';
11594 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11595 $optional_fws = $fws . '?';
11596 $day_name = $this->day_pcre;
11597 $month = $this->month_pcre;
11598 $day = '([0-9]{1,2})';
11599 $hour = $minute = $second = '([0-9]{2})';
11600 $year = '([0-9]{2,4})';
11601 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11602 $character_zone = '([A-Z]{1,5})';
11603 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11604 $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';
11606 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11609 Capturing subpatterns:
11619 10: Timezone minutes
11620 11: Alphabetic timezone
11623 // Find the month number
11624 $month = $this->month[strtolower($match[3])];
11626 // Numeric timezone
11627 if ($match[8] !== '')
11629 $timezone = $match[9] * 3600;
11630 $timezone += $match[10] * 60;
11631 if ($match[8] === '-')
11633 $timezone = 0 - $timezone;
11636 // Character timezone
11637 elseif (isset($this->timezone[strtoupper($match[11])]))
11639 $timezone = $this->timezone[strtoupper($match[11])];
11641 // Assume everything else to be -0000
11647 // Deal with 2/3 digit years
11648 if ($match[4] < 50)
11652 elseif ($match[4] < 1000)
11657 // Second is optional, if it is empty set it to zero
11658 if ($match[7] !== '')
11660 $second = $match[7];
11667 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
11676 * Parse RFC850's date format
11678 * @access protected
11679 * @return int Timestamp
11681 function date_rfc850($date)
11686 $space = '[\x09\x20]+';
11687 $day_name = $this->day_pcre;
11688 $month = $this->month_pcre;
11689 $day = '([0-9]{1,2})';
11690 $year = $hour = $minute = $second = '([0-9]{2})';
11691 $zone = '([A-Z]{1,5})';
11692 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
11694 if (preg_match($pcre, $date, $match))
11697 Capturing subpatterns:
11709 $month = $this->month[strtolower($match[3])];
11711 // Character timezone
11712 if (isset($this->timezone[strtoupper($match[8])]))
11714 $timezone = $this->timezone[strtoupper($match[8])];
11716 // Assume everything else to be -0000
11722 // Deal with 2 digit year
11723 if ($match[4] < 50)
11732 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
11741 * Parse C99's asctime()'s date format
11743 * @access protected
11744 * @return int Timestamp
11746 function date_asctime($date)
11751 $space = '[\x09\x20]+';
11752 $wday_name = $this->day_pcre;
11753 $mon_name = $this->month_pcre;
11754 $day = '([0-9]{1,2})';
11755 $hour = $sec = $min = '([0-9]{2})';
11756 $year = '([0-9]{4})';
11757 $terminator = '\x0A?\x00?';
11758 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
11760 if (preg_match($pcre, $date, $match))
11763 Capturing subpatterns:
11773 $month = $this->month[strtolower($match[2])];
11774 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
11783 * Parse dates using strtotime()
11785 * @access protected
11786 * @return int Timestamp
11788 function date_strtotime($date)
11790 $strtotime = strtotime($date);
11791 if ($strtotime === -1 || $strtotime === false)
11803 * Content-type sniffing
11805 * @package SimplePie
11807 class SimplePie_Content_Type_Sniffer
11812 * @var SimplePie_File
11818 * Create an instance of the class with the input file
11821 * @param SimplePie_Content_Type_Sniffer $file Input file
11823 function SimplePie_Content_Type_Sniffer($file)
11825 $this->file = $file;
11829 * Get the Content-Type of the specified file
11832 * @return string Actual Content-Type
11834 function get_type()
11836 if (isset($this->file->headers['content-type']))
11838 if (!isset($this->file->headers['content-encoding'])
11839 && ($this->file->headers['content-type'] === 'text/plain'
11840 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
11841 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
11843 return $this->text_or_binary();
11846 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
11848 $official = substr($this->file->headers['content-type'], 0, $pos);
11852 $official = $this->file->headers['content-type'];
11854 $official = strtolower($official);
11856 if ($official === 'unknown/unknown'
11857 || $official === 'application/unknown')
11859 return $this->unknown();
11861 elseif (substr($official, -4) === '+xml'
11862 || $official === 'text/xml'
11863 || $official === 'application/xml')
11867 elseif (substr($official, 0, 6) === 'image/')
11869 if ($return = $this->image())
11878 elseif ($official === 'text/html')
11880 return $this->feed_or_html();
11889 return $this->unknown();
11894 * Sniff text or binary
11897 * @return string Actual Content-Type
11899 function text_or_binary()
11901 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
11902 || substr($this->file->body, 0, 2) === "\xFF\xFE"
11903 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
11904 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
11906 return 'text/plain';
11908 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
11910 return 'application/octect-stream';
11914 return 'text/plain';
11922 * @return string Actual Content-Type
11926 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
11927 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
11928 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
11929 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
11931 return 'text/html';
11933 elseif (substr($this->file->body, 0, 5) === '%PDF-')
11935 return 'application/pdf';
11937 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
11939 return 'application/postscript';
11941 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
11942 || substr($this->file->body, 0, 6) === 'GIF89a')
11944 return 'image/gif';
11946 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11948 return 'image/png';
11950 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11952 return 'image/jpeg';
11954 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11956 return 'image/bmp';
11960 return $this->text_or_binary();
11968 * @return string Actual Content-Type
11972 if (substr($this->file->body, 0, 6) === 'GIF87a'
11973 || substr($this->file->body, 0, 6) === 'GIF89a')
11975 return 'image/gif';
11977 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11979 return 'image/png';
11981 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11983 return 'image/jpeg';
11985 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11987 return 'image/bmp';
11999 * @return string Actual Content-Type
12001 function feed_or_html()
12003 $len = strlen($this->file->body);
12004 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12006 while ($pos < $len)
12008 switch ($this->file->body[$pos])
12014 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12022 return 'text/html';
12025 if (substr($this->file->body, $pos, 3) === '!--')
12028 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12034 return 'text/html';
12037 elseif (substr($this->file->body, $pos, 1) === '!')
12039 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12045 return 'text/html';
12048 elseif (substr($this->file->body, $pos, 1) === '?')
12050 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12056 return 'text/html';
12059 elseif (substr($this->file->body, $pos, 3) === 'rss'
12060 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12062 return 'application/rss+xml';
12064 elseif (substr($this->file->body, $pos, 4) === 'feed')
12066 return 'application/atom+xml';
12070 return 'text/html';
12074 return 'text/html';
12079 * Parses the XML Declaration
12081 * @package SimplePie
12083 class SimplePie_XML_Declaration_Parser
12091 var $version = '1.0';
12099 var $encoding = 'UTF-8';
12107 var $standalone = false;
12110 * Current state of the state machine
12115 var $state = 'before_version_name';
12126 * Input data length (to avoid calling strlen() everytime this is needed)
12131 var $data_length = 0;
12134 * Current position of the pointer
12142 * Create an instance of the class with the input data
12145 * @param string $data Input data
12147 function SimplePie_XML_Declaration_Parser($data)
12149 $this->data = $data;
12150 $this->data_length = strlen($this->data);
12154 * Parse the input data
12157 * @return bool true on success, false on failure
12161 while ($this->state && $this->state !== 'emit' && $this->has_data())
12163 $state = $this->state;
12167 if ($this->state === 'emit')
12173 $this->version = '';
12174 $this->encoding = '';
12175 $this->standalone = '';
12181 * Check whether there is data beyond the pointer
12184 * @return bool true if there is further data, false if not
12186 function has_data()
12188 return (bool) ($this->position < $this->data_length);
12192 * Advance past any whitespace
12194 * @return int Number of whitespace characters passed
12196 function skip_whitespace()
12198 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12199 $this->position += $whitespace;
12200 return $whitespace;
12206 function get_value()
12208 $quote = substr($this->data, $this->position, 1);
12209 if ($quote === '"' || $quote === "'")
12212 $len = strcspn($this->data, $quote, $this->position);
12213 if ($this->has_data())
12215 $value = substr($this->data, $this->position, $len);
12216 $this->position += $len + 1;
12223 function before_version_name()
12225 if ($this->skip_whitespace())
12227 $this->state = 'version_name';
12231 $this->state = false;
12235 function version_name()
12237 if (substr($this->data, $this->position, 7) === 'version')
12239 $this->position += 7;
12240 $this->skip_whitespace();
12241 $this->state = 'version_equals';
12245 $this->state = false;
12249 function version_equals()
12251 if (substr($this->data, $this->position, 1) === '=')
12254 $this->skip_whitespace();
12255 $this->state = 'version_value';
12259 $this->state = false;
12263 function version_value()
12265 if ($this->version = $this->get_value())
12267 $this->skip_whitespace();
12268 if ($this->has_data())
12270 $this->state = 'encoding_name';
12274 $this->state = 'emit';
12279 $this->state = 'standalone_name';
12283 function encoding_name()
12285 if (substr($this->data, $this->position, 8) === 'encoding')
12287 $this->position += 8;
12288 $this->skip_whitespace();
12289 $this->state = 'encoding_equals';
12293 $this->state = false;
12297 function encoding_equals()
12299 if (substr($this->data, $this->position, 1) === '=')
12302 $this->skip_whitespace();
12303 $this->state = 'encoding_value';
12307 $this->state = false;
12311 function encoding_value()
12313 if ($this->encoding = $this->get_value())
12315 $this->skip_whitespace();
12316 if ($this->has_data())
12318 $this->state = 'standalone_name';
12322 $this->state = 'emit';
12327 $this->state = false;
12331 function standalone_name()
12333 if (substr($this->data, $this->position, 10) === 'standalone')
12335 $this->position += 10;
12336 $this->skip_whitespace();
12337 $this->state = 'standalone_equals';
12341 $this->state = false;
12345 function standalone_equals()
12347 if (substr($this->data, $this->position, 1) === '=')
12350 $this->skip_whitespace();
12351 $this->state = 'standalone_value';
12355 $this->state = false;
12359 function standalone_value()
12361 if ($standalone = $this->get_value())
12363 switch ($standalone)
12366 $this->standalone = true;
12370 $this->standalone = false;
12374 $this->state = false;
12378 $this->skip_whitespace();
12379 if ($this->has_data())
12381 $this->state = false;
12385 $this->state = 'emit';
12390 $this->state = false;
12395 class SimplePie_Locator
12400 var $local = array();
12401 var $elsewhere = array();
12402 var $file_class = 'SimplePie_File';
12403 var $cached_entities = array();
12406 var $base_location = 0;
12407 var $checked_feeds = 0;
12408 var $max_checked_feeds = 10;
12409 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12411 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12413 $this->file =& $file;
12414 $this->file_class = $file_class;
12415 $this->useragent = $useragent;
12416 $this->timeout = $timeout;
12417 $this->max_checked_feeds = $max_checked_feeds;
12418 $this->content_type_sniffer_class;
12421 function find($type = SIMPLEPIE_LOCATOR_ALL)
12423 if ($this->is_feed($this->file))
12425 return $this->file;
12428 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12430 $sniffer = new $this->content_type_sniffer_class($this->file);
12431 if ($sniffer->get_type() !== 'text/html')
12437 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12442 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12447 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12449 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12454 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12459 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12464 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12472 function is_feed(&$file)
12474 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12476 $sniffer = new $this->content_type_sniffer_class($file);
12477 $sniffed = $sniffer->get_type();
12478 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
12487 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12497 function get_base()
12499 $this->http_base = $this->file->url;
12500 $this->base = $this->http_base;
12501 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12502 foreach ($elements as $element)
12504 if ($element['attribs']['href']['data'] !== '')
12506 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12507 $this->base_location = $element['offset'];
12513 function autodiscovery()
12515 $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));
12517 foreach ($links as $link)
12519 if ($this->checked_feeds == $this->max_checked_feeds)
12523 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12525 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12527 if ($this->base_location < $link['offset'])
12529 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12533 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12536 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'))))
12538 $this->checked_feeds++;
12539 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12540 if ($this->is_feed($feed))
12551 function get_links()
12553 $links = SimplePie_Misc::get_element('a', $this->file->body);
12554 foreach ($links as $link)
12556 if (isset($link['attribs']['href']['data']))
12558 $href = trim($link['attribs']['href']['data']);
12559 $parsed = SimplePie_Misc::parse_url($href);
12560 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12562 if ($this->base_location < $link['offset'])
12564 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12568 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12571 $current = SimplePie_Misc::parse_url($this->file->url);
12573 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12575 $this->local[] = $href;
12579 $this->elsewhere[] = $href;
12584 $this->local = array_unique($this->local);
12585 $this->elsewhere = array_unique($this->elsewhere);
12586 if (!empty($this->local) || !empty($this->elsewhere))
12593 function extension(&$array)
12595 foreach ($array as $key => $value)
12597 if ($this->checked_feeds == $this->max_checked_feeds)
12601 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12603 $this->checked_feeds++;
12604 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12605 if ($this->is_feed($feed))
12611 unset($array[$key]);
12618 function body(&$array)
12620 foreach ($array as $key => $value)
12622 if ($this->checked_feeds == $this->max_checked_feeds)
12626 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12628 $this->checked_feeds++;
12629 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12630 if ($this->is_feed($feed))
12636 unset($array[$key]);
12644 class SimplePie_Parser
12649 var $current_column;
12651 var $separator = ' ';
12653 var $namespace = array('');
12654 var $element = array('');
12655 var $xml_base = array('');
12656 var $xml_base_explicit = array(false);
12657 var $xml_lang = array('');
12658 var $data = array();
12659 var $datas = array(array());
12660 var $current_xhtml_construct = -1;
12663 function parse(&$data, $encoding)
12665 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
12666 if (strtoupper($encoding) == 'US-ASCII')
12668 $this->encoding = 'UTF-8';
12672 $this->encoding = $encoding;
12676 // UTF-32 Big Endian BOM
12677 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
12679 $data = substr($data, 4);
12681 // UTF-32 Little Endian BOM
12682 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
12684 $data = substr($data, 4);
12686 // UTF-16 Big Endian BOM
12687 elseif (substr($data, 0, 2) === "\xFE\xFF")
12689 $data = substr($data, 2);
12691 // UTF-16 Little Endian BOM
12692 elseif (substr($data, 0, 2) === "\xFF\xFE")
12694 $data = substr($data, 2);
12697 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
12699 $data = substr($data, 3);
12702 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
12704 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
12705 if ($declaration->parse())
12707 $data = substr($data, $pos + 2);
12708 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
12712 $this->error_string = 'SimplePie bug! Please report this!';
12719 // Create the parser
12720 $xml = xml_parser_create_ns($this->encoding, $this->separator);
12721 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
12722 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
12723 xml_set_object($xml, $this);
12724 xml_set_character_data_handler($xml, 'cdata');
12725 xml_set_element_handler($xml, 'tag_open', 'tag_close');
12728 if (!xml_parse($xml, $data, true))
12730 $this->error_code = xml_get_error_code($xml);
12731 $this->error_string = xml_error_string($this->error_code);
12734 $this->current_line = xml_get_current_line_number($xml);
12735 $this->current_column = xml_get_current_column_number($xml);
12736 $this->current_byte = xml_get_current_byte_index($xml);
12737 xml_parser_free($xml);
12741 function get_error_code()
12743 return $this->error_code;
12746 function get_error_string()
12748 return $this->error_string;
12751 function get_current_line()
12753 return $this->current_line;
12756 function get_current_column()
12758 return $this->current_column;
12761 function get_current_byte()
12763 return $this->current_byte;
12766 function get_data()
12768 return $this->data;
12771 function tag_open($parser, $tag, $attributes)
12773 if ($this->feed === 0)
12777 elseif ($this->feed == false)
12779 if (in_array($tag, array(
12780 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
12781 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
12783 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
12794 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
12796 $attribs = array();
12797 foreach ($attributes as $name => $value)
12799 list($attrib_namespace, $attribute) = $this->split_ns($name);
12800 $attribs[$attrib_namespace][$attribute] = $value;
12803 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
12805 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
12806 $this->xml_base_explicit[] = true;
12810 $this->xml_base[] = end($this->xml_base);
12811 $this->xml_base_explicit[] = end($this->xml_base_explicit);
12814 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
12816 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
12820 $this->xml_lang[] = end($this->xml_lang);
12823 if ($this->current_xhtml_construct >= 0)
12825 $this->current_xhtml_construct++;
12826 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
12828 $this->data['data'] .= '<' . end($this->element);
12829 if (isset($attribs['']))
12831 foreach ($attribs[''] as $name => $value)
12833 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
12836 $this->data['data'] .= '>';
12841 $this->datas[] =& $this->data;
12842 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
12843 $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));
12844 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')
12845 || (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'))
12847 $this->current_xhtml_construct = 0;
12852 function cdata($parser, $cdata)
12854 if ($this->current_xhtml_construct >= 0)
12856 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
12858 elseif ($this->feed > 1)
12860 $this->data['data'] .= $cdata;
12864 function tag_close($parser, $tag)
12871 if ($this->current_xhtml_construct >= 0)
12873 $this->current_xhtml_construct--;
12874 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')))
12876 $this->data['data'] .= '</' . end($this->element) . '>';
12879 if ($this->current_xhtml_construct == -1)
12881 $this->data =& $this->datas[$this->feed];
12882 array_pop($this->datas);
12885 array_pop($this->element);
12886 array_pop($this->namespace);
12887 array_pop($this->xml_base);
12888 array_pop($this->xml_base_explicit);
12889 array_pop($this->xml_lang);
12893 function split_ns($string)
12895 static $cache = array();
12896 if (!isset($cache[$string]))
12898 if ($pos = strpos($string, $this->separator))
12900 static $separator_length;
12901 if (!$separator_length)
12903 $separator_length = strlen($this->separator);
12905 $namespace = substr($string, 0, $pos);
12906 $local_name = substr($string, $pos + $separator_length);
12907 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
12909 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
12911 $cache[$string] = array($namespace, $local_name);
12915 $cache[$string] = array('', $string);
12918 return $cache[$string];
12923 * @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 shortern a string while preserving HTML tags
12925 class SimplePie_Sanitize
12931 var $remove_div = true;
12932 var $image_handler = '';
12933 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
12934 var $encode_instead_of_strip = false;
12935 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
12936 var $strip_comments = false;
12937 var $output_encoding = 'UTF-8';
12938 var $enable_cache = true;
12939 var $cache_location = './cache';
12940 var $cache_name_function = 'md5';
12941 var $cache_class = 'SimplePie_Cache';
12942 var $file_class = 'SimplePie_File';
12944 var $useragent = '';
12945 var $force_fsockopen = false;
12947 var $replace_url_attributes = array(
12950 'blockquote' => 'cite',
12952 'form' => 'action',
12953 'img' => array('longdesc', 'src'),
12959 function remove_div($enable = true)
12961 $this->remove_div = (bool) $enable;
12964 function set_image_handler($page = false)
12968 $this->image_handler = (string) $page;
12972 $this->image_handler = false;
12976 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
12978 if (isset($enable_cache))
12980 $this->enable_cache = (bool) $enable_cache;
12983 if ($cache_location)
12985 $this->cache_location = (string) $cache_location;
12988 if ($cache_name_function)
12990 $this->cache_name_function = (string) $cache_name_function;
12995 $this->cache_class = (string) $cache_class;
12999 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13003 $this->file_class = (string) $file_class;
13008 $this->timeout = (string) $timeout;
13013 $this->useragent = (string) $useragent;
13016 if ($force_fsockopen)
13018 $this->force_fsockopen = (string) $force_fsockopen;
13022 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13026 if (is_array($tags))
13028 $this->strip_htmltags = $tags;
13032 $this->strip_htmltags = explode(',', $tags);
13037 $this->strip_htmltags = false;
13041 function encode_instead_of_strip($encode = false)
13043 $this->encode_instead_of_strip = (bool) $encode;
13046 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13050 if (is_array($attribs))
13052 $this->strip_attributes = $attribs;
13056 $this->strip_attributes = explode(',', $attribs);
13061 $this->strip_attributes = false;
13065 function strip_comments($strip = false)
13067 $this->strip_comments = (bool) $strip;
13070 function set_output_encoding($encoding = 'UTF-8')
13072 $this->output_encoding = (string) $encoding;
13076 * Set element/attribute key/value pairs of HTML attributes
13077 * containing URLs that need to be resolved relative to the feed
13081 * @param array $element_attribute Element/attribute key/value pairs
13083 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'))
13085 $this->replace_url_attributes = (array) $element_attribute;
13088 function sanitize($data, $type, $base = '')
13090 $data = trim($data);
13091 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13093 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13095 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))
13097 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13101 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13105 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13107 $data = base64_decode($data);
13110 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13112 if ($this->remove_div)
13114 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13115 $data = preg_replace('/<\/div>$/', '', $data);
13119 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13123 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13126 if ($this->strip_comments)
13128 $data = SimplePie_Misc::strip_comments($data);
13131 // Strip out HTML tags and attributes that might cause various security problems.
13132 // Based on recommendations by Mark Pilgrim at:
13133 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13134 if ($this->strip_htmltags)
13136 foreach ($this->strip_htmltags as $tag)
13138 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13139 while (preg_match($pcre, $data))
13141 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13146 if ($this->strip_attributes)
13148 foreach ($this->strip_attributes as $attrib)
13150 $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);
13154 // Replace relative URLs
13155 $this->base = $base;
13156 foreach ($this->replace_url_attributes as $element => $attributes)
13158 $data = $this->replace_urls($data, $element, $attributes);
13161 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13162 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13164 $images = SimplePie_Misc::get_element('img', $data);
13165 foreach ($images as $img)
13167 if (isset($img['attribs']['src']['data']))
13169 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13170 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13172 if ($cache->load())
13174 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13175 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13179 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13180 $headers = $file->headers;
13182 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13184 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13186 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13187 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13191 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13199 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13200 $data = trim($data);
13203 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13205 $data = SimplePie_Misc::absolutize_url($data, $base);
13208 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13210 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13213 if ($this->output_encoding != 'UTF-8')
13215 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13221 function replace_urls($data, $tag, $attributes)
13223 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13225 $elements = SimplePie_Misc::get_element($tag, $data);
13226 foreach ($elements as $element)
13228 if (is_array($attributes))
13230 foreach ($attributes as $attribute)
13232 if (isset($element['attribs'][$attribute]['data']))
13234 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13235 $new_element = SimplePie_Misc::element_implode($element);
13236 $data = str_replace($element['full'], $new_element, $data);
13237 $element['full'] = $new_element;
13241 elseif (isset($element['attribs'][$attributes]['data']))
13243 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13244 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13251 function do_strip_htmltags($match)
13253 if ($this->encode_instead_of_strip)
13255 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13257 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13258 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13259 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13263 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13266 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))