5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2008, Ryan Parman and Geoffrey Sneddon
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * @copyright 2004-2008 Ryan Parman, Geoffrey Sneddon
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 define('SIMPLEPIE_NAME', 'SimplePie');
54 define('SIMPLEPIE_VERSION', '1.1.1');
58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
60 define('SIMPLEPIE_BUILD', 20080315205903);
61 //define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::parse_date(substr('$Date: 2008-03-15 15:28:23 -0700 (Sat, 15 Mar 2008) $', 7, 25)) ? SimplePie_Misc::parse_date(substr('$Date: 2008-03-15 15:28:23 -0700 (Sat, 15 Mar 2008) $', 7, 25)) : filemtime(__FILE__)));
64 * SimplePie Website URL
66 define('SIMPLEPIE_URL', 'http://simplepie.org');
70 * @see SimplePie::set_useragent()
72 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
77 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
81 * @see SimplePie::set_autodiscovery_level()
83 define('SIMPLEPIE_LOCATOR_NONE', 0);
86 * Feed Link Element Autodiscovery
87 * @see SimplePie::set_autodiscovery_level()
89 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
92 * Local Feed Extension Autodiscovery
93 * @see SimplePie::set_autodiscovery_level()
95 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
98 * Local Feed Body Autodiscovery
99 * @see SimplePie::set_autodiscovery_level()
101 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
104 * Remote Feed Extension Autodiscovery
105 * @see SimplePie::set_autodiscovery_level()
107 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
110 * Remote Feed Body Autodiscovery
111 * @see SimplePie::set_autodiscovery_level()
113 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
116 * All Feed Autodiscovery
117 * @see SimplePie::set_autodiscovery_level()
119 define('SIMPLEPIE_LOCATOR_ALL', 31);
124 define('SIMPLEPIE_TYPE_NONE', 0);
129 define('SIMPLEPIE_TYPE_RSS_090', 1);
132 * RSS 0.91 (Netscape)
134 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
137 * RSS 0.91 (Userland)
139 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
142 * RSS 0.91 (both Netscape and Userland)
144 define('SIMPLEPIE_TYPE_RSS_091', 6);
149 define('SIMPLEPIE_TYPE_RSS_092', 8);
154 define('SIMPLEPIE_TYPE_RSS_093', 16);
159 define('SIMPLEPIE_TYPE_RSS_094', 32);
164 define('SIMPLEPIE_TYPE_RSS_10', 64);
169 define('SIMPLEPIE_TYPE_RSS_20', 128);
174 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
177 * Non-RDF-based RSS (truly intended as syndication format)
179 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
184 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
189 define('SIMPLEPIE_TYPE_ATOM_03', 256);
194 define('SIMPLEPIE_TYPE_ATOM_10', 512);
199 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
204 define('SIMPLEPIE_TYPE_ALL', 1023);
209 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
214 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
219 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
224 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
227 * base64-encoded construct
229 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
234 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
237 * A construct that might be HTML
239 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
244 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
247 * PCRE for HTML attributes
249 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]*');
252 * PCRE for XML attributes
254 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
259 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
264 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
269 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
274 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
279 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
284 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
287 * RSS 1.0 Content Module Namespace
289 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
294 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
299 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
302 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
304 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
309 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
312 * Media RSS Namespace
314 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
317 * Wrong Media RSS Namespace
319 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
322 * iTunes RSS Namespace
324 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
329 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
332 * IANA Link Relations Registry
334 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
337 * Whether we're running on PHP5
339 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
344 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
349 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
354 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
357 * fsockopen() file source
359 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
364 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
367 * file_get_contents() file source
369 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
375 * @version "Razzleberry"
376 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
377 * @author Ryan Parman
378 * @author Geoffrey Sneddon
379 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
384 * @var array Raw data
390 * @var mixed Error string
396 * @var object Instance of SimplePie_Sanitize (or other class)
397 * @see SimplePie::set_sanitize_class()
403 * @var string SimplePie Useragent
404 * @see SimplePie::set_useragent()
407 var $useragent = SIMPLEPIE_USERAGENT;
410 * @var string Feed URL
411 * @see SimplePie::set_feed_url()
417 * @var object Instance of SimplePie_File to use as a feed
418 * @see SimplePie::set_file()
424 * @var string Raw feed data
425 * @see SimplePie::set_raw_data()
431 * @var int Timeout for fetching remote files
432 * @see SimplePie::set_timeout()
438 * @var bool Forces fsockopen() to be used for remote files instead
439 * of cURL, even if a new enough version is installed
440 * @see SimplePie::force_fsockopen()
443 var $force_fsockopen = false;
446 * @var bool Force the given data/URL to be treated as a feed no matter what
448 * @see SimplePie::force_feed()
451 var $force_feed = false;
454 * @var bool Enable/Disable XML dump
455 * @see SimplePie::enable_xml_dump()
458 var $xml_dump = false;
461 * @var bool Enable/Disable Caching
462 * @see SimplePie::enable_cache()
468 * @var int Cache duration (in seconds)
469 * @see SimplePie::set_cache_duration()
472 var $cache_duration = 3600;
475 * @var int Auto-discovery cache duration (in seconds)
476 * @see SimplePie::set_autodiscovery_cache_duration()
479 var $autodiscovery_cache_duration = 604800; // 7 Days.
482 * @var string Cache location (relative to executing script)
483 * @see SimplePie::set_cache_location()
486 var $cache_location = './cache';
489 * @var string Function that creates the cache filename
490 * @see SimplePie::set_cache_name_function()
493 var $cache_name_function = 'md5';
496 * @var bool Reorder feed by date descending
497 * @see SimplePie::enable_order_by_date()
500 var $order_by_date = true;
503 * @var mixed Force input encoding to be set to the follow value
504 * (false, or anything type-cast to false, disables this feature)
505 * @see SimplePie::set_input_encoding()
508 var $input_encoding = false;
511 * @var int Feed Autodiscovery Level
512 * @see SimplePie::set_autodiscovery_level()
515 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
518 * @var string Class used for caching feeds
519 * @see SimplePie::set_cache_class()
522 var $cache_class = 'SimplePie_Cache';
525 * @var string Class used for locating feeds
526 * @see SimplePie::set_locator_class()
529 var $locator_class = 'SimplePie_Locator';
532 * @var string Class used for parsing feeds
533 * @see SimplePie::set_parser_class()
536 var $parser_class = 'SimplePie_Parser';
539 * @var string Class used for fetching feeds
540 * @see SimplePie::set_file_class()
543 var $file_class = 'SimplePie_File';
546 * @var string Class used for items
547 * @see SimplePie::set_item_class()
550 var $item_class = 'SimplePie_Item';
553 * @var string Class used for authors
554 * @see SimplePie::set_author_class()
557 var $author_class = 'SimplePie_Author';
560 * @var string Class used for categories
561 * @see SimplePie::set_category_class()
564 var $category_class = 'SimplePie_Category';
567 * @var string Class used for enclosures
568 * @see SimplePie::set_enclosures_class()
571 var $enclosure_class = 'SimplePie_Enclosure';
574 * @var string Class used for Media RSS <media:text> captions
575 * @see SimplePie::set_caption_class()
578 var $caption_class = 'SimplePie_Caption';
581 * @var string Class used for Media RSS <media:copyright>
582 * @see SimplePie::set_copyright_class()
585 var $copyright_class = 'SimplePie_Copyright';
588 * @var string Class used for Media RSS <media:credit>
589 * @see SimplePie::set_credit_class()
592 var $credit_class = 'SimplePie_Credit';
595 * @var string Class used for Media RSS <media:rating>
596 * @see SimplePie::set_rating_class()
599 var $rating_class = 'SimplePie_Rating';
602 * @var string Class used for Media RSS <media:restriction>
603 * @see SimplePie::set_restriction_class()
606 var $restriction_class = 'SimplePie_Restriction';
609 * @var string Class used for content-type sniffing
610 * @see SimplePie::set_content_type_sniffer_class()
613 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
616 * @var string Class used for item sources.
617 * @see SimplePie::set_source_class()
620 var $source_class = 'SimplePie_Source';
623 * @var mixed Set javascript query string parameter (false, or
624 * anything type-cast to false, disables this feature)
625 * @see SimplePie::set_javascript()
628 var $javascript = 'js';
631 * @var int Maximum number of feeds to check with autodiscovery
632 * @see SimplePie::set_max_checked_feeds()
635 var $max_checked_feeds = 10;
638 * @var string Web-accessible path to the handler_favicon.php file.
639 * @see SimplePie::set_favicon_handler()
642 var $favicon_handler = '';
645 * @var string Web-accessible path to the handler_image.php file.
646 * @see SimplePie::set_image_handler()
649 var $image_handler = '';
652 * @var array Stores the URLs when multiple feeds are being initialized.
653 * @see SimplePie::set_feed_url()
656 var $multifeed_url = array();
659 * @var array Stores SimplePie objects when multiple feeds initialized.
662 var $multifeed_objects = array();
665 * @var array Stores the get_object_vars() array for use with multifeeds.
666 * @see SimplePie::set_feed_url()
669 var $config_settings = null;
672 * @var integer Stores the number of items to return per-feed with multifeeds.
673 * @see SimplePie::set_item_limit()
679 * @var array Stores the default attributes to be stripped by strip_attributes().
680 * @see SimplePie::strip_attributes()
683 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
686 * @var array Stores the default tags to be stripped by strip_htmltags().
687 * @see SimplePie::strip_htmltags()
690 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
693 * The SimplePie class contains feed level data and options
695 * There are two ways that you can create a new SimplePie object. The first
696 * is by passing a feed URL as a parameter to the SimplePie constructor
697 * (as well as optionally setting the cache location and cache expiry). This
698 * will initialise the whole feed with all of the default settings, and you
699 * can begin accessing methods and properties immediately.
701 * The second way is to create the SimplePie object with no parameters
702 * at all. This will enable you to set configuration options. After setting
703 * them, you must initialise the feed using $feed->init(). At that point the
704 * object's methods and properties will be available to you. This format is
705 * what is used throughout this documentation.
708 * @since 1.0 Preview Release
709 * @param string $feed_url This is the URL you want to parse.
710 * @param string $cache_location This is where you want the cache to be stored.
711 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
713 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
715 // Other objects, instances created here so we can set options on them
716 $this->sanitize =& new SimplePie_Sanitize;
718 // Set options if they're passed to the constructor
719 if ($cache_location !== null)
721 $this->set_cache_location($cache_location);
724 if ($cache_duration !== null)
726 $this->set_cache_duration($cache_duration);
729 // Only init the script if we're passed a feed URL
730 if ($feed_url !== null)
732 $this->set_feed_url($feed_url);
738 * Used for converting object to a string
740 function __toString()
742 return md5(serialize($this->data));
746 * Remove items that link back to this before destroying this object
748 function __destruct()
750 if (!empty($this->data['items']))
752 foreach ($this->data['items'] as $item)
756 unset($this->data['items']);
758 if (!empty($this->data['ordered_items']))
760 foreach ($this->data['ordered_items'] as $item)
764 unset($this->data['ordered_items']);
769 * Force the given data/URL to be treated as a feed no matter what it
774 * @param bool $enable Force the given data/URL to be treated as a feed
776 function force_feed($enable = false)
778 $this->force_feed = (bool) $enable;
782 * This is the URL of the feed you want to parse.
784 * This allows you to enter the URL of the feed you want to parse, or the
785 * website you want to try to use auto-discovery on. This takes priority
786 * over any set raw data.
788 * You can set multiple feeds to mash together by passing an array instead
789 * of a string for the $url. Remember that with each additional feed comes
790 * additional processing and resources.
793 * @since 1.0 Preview Release
794 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
795 * @see SimplePie::set_raw_data()
797 function set_feed_url($url)
801 $this->multifeed_url = array();
802 foreach ($url as $value)
804 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
809 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
814 * Provides an instance of SimplePie_File to use as a feed
817 * @param object &$file Instance of SimplePie_File (or subclass)
818 * @return bool True on success, false on failure
820 function set_file(&$file)
822 if (is_a($file, 'SimplePie_File'))
824 $this->feed_url = $file->url;
825 $this->file =& $file;
832 * Allows you to use a string of RSS/Atom data instead of a remote feed.
834 * If you have a feed available as a string in PHP, you can tell SimplePie
835 * to parse that data string instead of a remote feed. Any set feed URL
840 * @param string $data RSS or Atom data as a string.
841 * @see SimplePie::set_feed_url()
843 function set_raw_data($data)
845 $this->raw_data = $data;
849 * Allows you to override the default timeout for fetching remote feeds.
851 * This allows you to change the maximum time the feed's server to respond
852 * and send the feed back.
856 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
858 function set_timeout($timeout = 10)
860 $this->timeout = (int) $timeout;
864 * Forces SimplePie to use fsockopen() instead of the preferred cURL
869 * @param bool $enable Force fsockopen() to be used
871 function force_fsockopen($enable = false)
873 $this->force_fsockopen = (bool) $enable;
877 * Outputs the raw XML content of the feed, after it has gone through
878 * SimplePie's filters.
880 * Used only for debugging, this function will output the XML content as
881 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
882 * before trying to parse it. Many parts of the feed are re-written in
883 * memory, and in the end, you have a parsable feed. XML dump shows you the
884 * actual XML that SimplePie tries to parse, which may or may not be very
885 * different from the original feed.
888 * @since 1.0 Preview Release
889 * @param bool $enable Enable XML dump
891 function enable_xml_dump($enable = false)
893 $this->xml_dump = (bool) $enable;
897 * Enables/disables caching in SimplePie.
899 * This option allows you to disable caching all-together in SimplePie.
900 * However, disabling the cache can lead to longer load times.
903 * @since 1.0 Preview Release
904 * @param bool $enable Enable caching
906 function enable_cache($enable = true)
908 $this->cache = (bool) $enable;
912 * Set the length of time (in seconds) that the contents of a feed
916 * @param int $seconds The feed content cache duration.
918 function set_cache_duration($seconds = 3600)
920 $this->cache_duration = (int) $seconds;
924 * Set the length of time (in seconds) that the autodiscovered feed
925 * URL will be cached.
928 * @param int $seconds The autodiscovered feed URL cache duration.
930 function set_autodiscovery_cache_duration($seconds = 604800)
932 $this->autodiscovery_cache_duration = (int) $seconds;
936 * Set the file system location where the cached files should be stored.
939 * @param string $location The file system location.
941 function set_cache_location($location = './cache')
943 $this->cache_location = (string) $location;
947 * Determines whether feed items should be sorted into reverse chronological order.
950 * @param bool $enable Sort as reverse chronological order.
952 function enable_order_by_date($enable = true)
954 $this->order_by_date = (bool) $enable;
958 * Allows you to override the character encoding reported by the feed.
961 * @param string $encoding Character encoding.
963 function set_input_encoding($encoding = false)
967 $this->input_encoding = (string) $encoding;
971 $this->input_encoding = false;
976 * Set how much feed autodiscovery to do
979 * @see SIMPLEPIE_LOCATOR_NONE
980 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
981 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
982 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
983 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
984 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
985 * @see SIMPLEPIE_LOCATOR_ALL
986 * @param int $level Feed Autodiscovery Level (level can be a
987 * combination of the above constants, see bitwise OR operator)
989 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
991 $this->autodiscovery = (int) $level;
995 * Allows you to change which class SimplePie uses for caching.
996 * Useful when you are overloading or extending SimplePie's default classes.
999 * @param string $class Name of custom class.
1000 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1001 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1003 function set_cache_class($class = 'SimplePie_Cache')
1005 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1007 $this->cache_class = $class;
1014 * Allows you to change which class SimplePie uses for auto-discovery.
1015 * Useful when you are overloading or extending SimplePie's default classes.
1018 * @param string $class Name of custom class.
1019 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1020 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1022 function set_locator_class($class = 'SimplePie_Locator')
1024 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1026 $this->locator_class = $class;
1033 * Allows you to change which class SimplePie uses for XML parsing.
1034 * Useful when you are overloading or extending SimplePie's default classes.
1037 * @param string $class Name of custom class.
1038 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1039 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1041 function set_parser_class($class = 'SimplePie_Parser')
1043 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1045 $this->parser_class = $class;
1052 * Allows you to change which class SimplePie uses for remote file fetching.
1053 * Useful when you are overloading or extending SimplePie's default classes.
1056 * @param string $class Name of custom class.
1057 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1058 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1060 function set_file_class($class = 'SimplePie_File')
1062 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1064 $this->file_class = $class;
1071 * Allows you to change which class SimplePie uses for data sanitization.
1072 * Useful when you are overloading or extending SimplePie's default classes.
1075 * @param string $class Name of custom class.
1076 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1077 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1079 function set_sanitize_class($class = 'SimplePie_Sanitize')
1081 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1083 $this->sanitize =& new $class;
1090 * Allows you to change which class SimplePie uses for handling feed items.
1091 * Useful when you are overloading or extending SimplePie's default classes.
1094 * @param string $class Name of custom class.
1095 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1096 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1098 function set_item_class($class = 'SimplePie_Item')
1100 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1102 $this->item_class = $class;
1109 * Allows you to change which class SimplePie uses for handling author data.
1110 * Useful when you are overloading or extending SimplePie's default classes.
1113 * @param string $class Name of custom class.
1114 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1115 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1117 function set_author_class($class = 'SimplePie_Author')
1119 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1121 $this->author_class = $class;
1128 * Allows you to change which class SimplePie uses for handling category data.
1129 * Useful when you are overloading or extending SimplePie's default classes.
1132 * @param string $class Name of custom class.
1133 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1134 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1136 function set_category_class($class = 'SimplePie_Category')
1138 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1140 $this->category_class = $class;
1147 * Allows you to change which class SimplePie uses for feed enclosures.
1148 * Useful when you are overloading or extending SimplePie's default classes.
1151 * @param string $class Name of custom class.
1152 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1153 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1155 function set_enclosure_class($class = 'SimplePie_Enclosure')
1157 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1159 $this->enclosure_class = $class;
1166 * Allows you to change which class SimplePie uses for <media:text> captions
1167 * Useful when you are overloading or extending SimplePie's default classes.
1170 * @param string $class Name of custom class.
1171 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1172 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1174 function set_caption_class($class = 'SimplePie_Caption')
1176 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1178 $this->caption_class = $class;
1185 * Allows you to change which class SimplePie uses for <media:copyright>
1186 * Useful when you are overloading or extending SimplePie's default classes.
1189 * @param string $class Name of custom class.
1190 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1191 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1193 function set_copyright_class($class = 'SimplePie_Copyright')
1195 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1197 $this->copyright_class = $class;
1204 * Allows you to change which class SimplePie uses for <media:credit>
1205 * Useful when you are overloading or extending SimplePie's default classes.
1208 * @param string $class Name of custom class.
1209 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1210 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1212 function set_credit_class($class = 'SimplePie_Credit')
1214 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1216 $this->credit_class = $class;
1223 * Allows you to change which class SimplePie uses for <media:rating>
1224 * Useful when you are overloading or extending SimplePie's default classes.
1227 * @param string $class Name of custom class.
1228 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1229 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1231 function set_rating_class($class = 'SimplePie_Rating')
1233 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1235 $this->rating_class = $class;
1242 * Allows you to change which class SimplePie uses for <media:restriction>
1243 * Useful when you are overloading or extending SimplePie's default classes.
1246 * @param string $class Name of custom class.
1247 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1248 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1250 function set_restriction_class($class = 'SimplePie_Restriction')
1252 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1254 $this->restriction_class = $class;
1261 * Allows you to change which class SimplePie uses for content-type sniffing.
1262 * Useful when you are overloading or extending SimplePie's default classes.
1265 * @param string $class Name of custom class.
1266 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1267 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1269 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1271 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1273 $this->content_type_sniffer_class = $class;
1280 * Allows you to change which class SimplePie uses item sources.
1281 * Useful when you are overloading or extending SimplePie's default classes.
1284 * @param string $class Name of custom class.
1285 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1286 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1288 function set_source_class($class = 'SimplePie_Source')
1290 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1292 $this->source_class = $class;
1299 * Allows you to override the default user agent string.
1302 * @param string $ua New user agent string.
1304 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1306 $this->useragent = (string) $ua;
1310 * Set callback function to create cache filename with
1313 * @param mixed $function Callback function
1315 function set_cache_name_function($function = 'md5')
1317 if (is_callable($function))
1319 $this->cache_name_function = $function;
1324 * Set javascript query string parameter
1327 * @param mixed $get Javascript query string parameter
1329 function set_javascript($get = 'js')
1333 $this->javascript = (string) $get;
1337 $this->javascript = false;
1342 * Set options to make SP as fast as possible. Forgoes a
1343 * substantial amount of data sanitization in favor of speed.
1346 * @param bool $set Whether to set them or not
1348 function set_stupidly_fast($set = false)
1352 $this->enable_order_by_date(false);
1353 $this->remove_div(false);
1354 $this->strip_comments(false);
1355 $this->strip_htmltags(false);
1356 $this->strip_attributes(false);
1357 $this->set_image_handler(false);
1362 * Set maximum number of feeds to check with autodiscovery
1365 * @param int $max Maximum number of feeds to check
1367 function set_max_checked_feeds($max = 10)
1369 $this->max_checked_feeds = (int) $max;
1372 function remove_div($enable = true)
1374 $this->sanitize->remove_div($enable);
1377 function strip_htmltags($tags = '', $encode = null)
1381 $tags = $this->strip_htmltags;
1383 $this->sanitize->strip_htmltags($tags);
1384 if ($encode !== null)
1386 $this->sanitize->encode_instead_of_strip($tags);
1390 function encode_instead_of_strip($enable = true)
1392 $this->sanitize->encode_instead_of_strip($enable);
1395 function strip_attributes($attribs = '')
1397 if ($attribs === '')
1399 $attribs = $this->strip_attributes;
1401 $this->sanitize->strip_attributes($attribs);
1404 function set_output_encoding($encoding = 'UTF-8')
1406 $this->sanitize->set_output_encoding($encoding);
1409 function strip_comments($strip = false)
1411 $this->sanitize->strip_comments($strip);
1415 * Set element/attribute key/value pairs of HTML attributes
1416 * containing URLs that need to be resolved relative to the feed
1420 * @param array $element_attribute Element/attribute key/value pairs
1422 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'))
1424 $this->sanitize->set_url_replacements($element_attribute);
1428 * Set the handler to enable the display of cached favicons.
1431 * @param str $page Web-accessible path to the handler_favicon.php file.
1432 * @param str $qs The query string that the value should be passed to.
1434 function set_favicon_handler($page = false, $qs = 'i')
1438 $this->favicon_handler = $page . '?' . $qs . '=';
1442 $this->favicon_handler = '';
1447 * Set the handler to enable the display of cached images.
1450 * @param str $page Web-accessible path to the handler_image.php file.
1451 * @param str $qs The query string that the value should be passed to.
1453 function set_image_handler($page = false, $qs = 'i')
1457 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1461 $this->image_handler = '';
1466 * Set the limit for items returned per-feed with multifeeds.
1469 * @param integer $limit The maximum number of items to return.
1471 function set_item_limit($limit = 0)
1473 $this->item_limit = (int) $limit;
1478 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1482 if (isset($_GET[$this->javascript]))
1484 if (function_exists('ob_gzhandler'))
1486 ob_start('ob_gzhandler');
1488 header('Content-type: text/javascript; charset: UTF-8');
1489 header('Cache-Control: must-revalidate');
1490 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1492 function embed_odeo(link) {
1493 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>');
1496 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1497 if (placeholder != '') {
1498 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>');
1501 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>');
1505 function embed_flash(bgcolor, width, height, link, loop, type) {
1506 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>');
1509 function embed_flv(width, height, link, placeholder, loop, player) {
1510 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>');
1513 function embed_wmedia(width, height, link) {
1514 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1520 // Pass whatever was set with config options over to the sanitizer.
1521 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1522 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1524 if ($this->feed_url !== null || $this->raw_data !== null)
1526 $this->data = array();
1527 $this->multifeed_objects = array();
1530 if ($this->feed_url !== null)
1532 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1533 // Decide whether to enable caching
1534 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1536 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1538 // If it's enabled and we don't want an XML dump, use the cache
1539 if ($cache && !$this->xml_dump)
1542 $this->data = $cache->load();
1543 if (!empty($this->data))
1545 // If the cache is for an outdated build of SimplePie
1546 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1549 $this->data = array();
1551 // If we've hit a collision just rerun it with caching disabled
1552 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1555 $this->data = array();
1557 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1558 elseif (isset($this->data['feed_url']))
1560 // If the autodiscovery cache is still valid use it.
1561 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1563 // Do not need to do feed autodiscovery yet.
1564 if ($this->data['feed_url'] == $this->data['url'])
1567 $this->data = array();
1571 $this->set_feed_url($this->data['feed_url']);
1572 return $this->init();
1576 // Check if the cache has been updated
1577 elseif ($cache->mtime() + $this->cache_duration < time())
1579 // If we have last-modified and/or etag set
1580 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1583 if (isset($this->data['headers']['last-modified']))
1585 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1587 if (isset($this->data['headers']['etag']))
1589 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1591 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1594 if ($file->status_code == 304)
1601 $headers = $file->headers;
1610 // If the cache is still valid, just return true
1616 // If the cache is empty, delete it
1620 $this->data = array();
1623 // 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.
1626 if (is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1628 $file =& $this->file;
1632 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1635 // If the file connection has an error, set SimplePie::error to that and quit
1636 if (!$file->success)
1638 $this->error = $file->error;
1639 if (!empty($this->data))
1649 if (!$this->force_feed)
1651 // Check if the supplied URL is a feed, if it isn't, look for it.
1652 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1653 if (!$locate->is_feed($file))
1655 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1657 if ($file = $locate->find($this->autodiscovery))
1661 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1662 if (!$cache->save($this))
1664 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1666 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1668 $this->feed_url = $file->url;
1672 $this->error = "A feed could not be found at $this->feed_url";
1673 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1680 $headers = $file->headers;
1681 $data = $file->body;
1682 $sniffer = new $this->content_type_sniffer_class($file);
1683 $sniffed = $sniffer->get_type();
1687 $data = $this->raw_data;
1690 // Set up array of possible encodings
1691 $encodings = array();
1693 // First check to see if input has been overridden.
1694 if ($this->input_encoding !== false)
1696 $encodings[] = $this->input_encoding;
1699 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1700 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1702 // RFC 3023 (only applies to sniffed content)
1703 if (isset($sniffed))
1705 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1707 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1709 $encodings[] = strtoupper($charset[1]);
1711 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1712 $encodings[] = 'UTF-8';
1714 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1716 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1718 $encodings[] = $charset[1];
1720 $encodings[] = 'US-ASCII';
1722 // Text MIME-type default
1723 elseif (substr($sniffed, 0, 5) === 'text/')
1725 $encodings[] = 'US-ASCII';
1729 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1730 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1731 $encodings[] = 'UTF-8';
1732 $encodings[] = 'ISO-8859-1';
1734 // There's no point in trying an encoding twice
1735 $encodings = array_unique($encodings);
1737 // If we want the XML, just output that with the most likely encoding and quit
1738 if ($this->xml_dump)
1740 header('Content-type: text/xml; charset=' . $encodings[0]);
1745 // Loop through each possible encoding, till we return something, or run out of possibilities
1746 foreach ($encodings as $encoding)
1748 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1749 $utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1751 // Create new parser
1752 $parser =& new $this->parser_class();
1754 // If it's parsed fine
1755 if ($parser->parse($utf8_data, 'UTF-8'))
1757 $this->data = $parser->get_data();
1758 if (isset($this->data['child']))
1760 if (isset($headers))
1762 $this->data['headers'] = $headers;
1764 $this->data['build'] = SIMPLEPIE_BUILD;
1766 // Cache the file if caching is enabled
1767 if ($cache && !$cache->save($this))
1769 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1775 $this->error = "A feed could not be found at $this->feed_url";
1776 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1781 // We have an error, just set SimplePie::error to it and quit
1782 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1783 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1786 elseif (!empty($this->multifeed_url))
1790 $this->multifeed_objects = array();
1791 foreach ($this->multifeed_url as $url)
1795 // This keyword needs to defy coding standards for PHP4 compatibility
1796 $this->multifeed_objects[$i] = clone($this);
1800 $this->multifeed_objects[$i] = $this;
1802 $this->multifeed_objects[$i]->set_feed_url($url);
1803 $success |= $this->multifeed_objects[$i]->init();
1806 return (bool) $success;
1815 * Return the error message for the occured error
1818 * @return string Error message
1822 return $this->error;
1825 function get_encoding()
1827 return $this->sanitize->output_encoding;
1830 function handle_content_type($mime = 'text/html')
1832 if (!headers_sent())
1834 $header = "Content-type: $mime;";
1835 if ($this->get_encoding())
1837 $header .= ' charset=' . $this->get_encoding();
1841 $header .= ' charset=UTF-8';
1849 if (!isset($this->data['type']))
1851 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1852 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1854 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1856 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1858 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1860 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1862 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1863 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1864 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1865 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1867 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1869 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1870 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1871 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1872 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1874 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1877 elseif (isset($this->data['child']['']['rss']))
1879 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1880 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1882 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1885 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1886 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1888 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1891 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1895 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1902 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1906 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1921 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1924 return $this->data['type'];
1928 * Returns the URL for the favicon of the feed's website.
1930 * @todo Cache atom:icon
1934 function get_favicon()
1936 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1938 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1940 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1942 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1944 if ($this->cache && $this->favicon_handler)
1946 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1947 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1951 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1955 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1957 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1959 $sniffer = new $this->content_type_sniffer_class($file);
1960 if (substr($sniffer->get_type(), 0, 6) === 'image/')
1962 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1964 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1968 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1969 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1977 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1984 * @todo If we have a perm redirect we should return the new URL
1985 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1986 * @todo Also, |atom:link|@rel=self
1988 function subscribe_url()
1990 if ($this->feed_url !== null)
1992 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2000 function subscribe_feed()
2002 if ($this->feed_url !== null)
2004 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2012 function subscribe_outlook()
2014 if ($this->feed_url !== null)
2016 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2024 function subscribe_podcast()
2026 if ($this->feed_url !== null)
2028 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2036 function subscribe_itunes()
2038 if ($this->feed_url !== null)
2040 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2049 * Creates the subscribe_* methods' return data
2052 * @param string $feed_url String to prefix to the feed URL
2053 * @param string $site_url String to prefix to the site URL (and
2054 * suffix to the feed URL)
2055 * @return mixed URL if feed exists, false otherwise
2057 function subscribe_service($feed_url, $site_url = null)
2059 if ($this->subscribe_url())
2061 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->feed_url);
2062 if ($site_url !== null && $this->get_link() !== null)
2064 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
2074 function subscribe_aol()
2076 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2079 function subscribe_bloglines()
2081 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
2084 function subscribe_eskobo()
2086 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2089 function subscribe_feedfeeds()
2091 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2094 function subscribe_feedster()
2096 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2099 function subscribe_google()
2101 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2104 function subscribe_gritwire()
2106 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2109 function subscribe_msn()
2111 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2114 function subscribe_netvibes()
2116 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2119 function subscribe_newsburst()
2121 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2124 function subscribe_newsgator()
2126 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2129 function subscribe_odeo()
2131 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2134 function subscribe_podnova()
2136 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2139 function subscribe_rojo()
2141 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2144 function subscribe_yahoo()
2146 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2149 function get_feed_tags($namespace, $tag)
2151 $type = $this->get_type();
2152 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2154 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2156 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2159 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2161 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2163 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2166 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2168 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2170 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2173 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2175 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2177 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2183 function get_channel_tags($namespace, $tag)
2185 $type = $this->get_type();
2186 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2188 if ($return = $this->get_feed_tags($namespace, $tag))
2193 if ($type & SIMPLEPIE_TYPE_RSS_10)
2195 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2197 if (isset($channel[0]['child'][$namespace][$tag]))
2199 return $channel[0]['child'][$namespace][$tag];
2203 if ($type & SIMPLEPIE_TYPE_RSS_090)
2205 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2207 if (isset($channel[0]['child'][$namespace][$tag]))
2209 return $channel[0]['child'][$namespace][$tag];
2213 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2215 if ($channel = $this->get_feed_tags('', 'channel'))
2217 if (isset($channel[0]['child'][$namespace][$tag]))
2219 return $channel[0]['child'][$namespace][$tag];
2226 function get_image_tags($namespace, $tag)
2228 $type = $this->get_type();
2229 if ($type & SIMPLEPIE_TYPE_RSS_10)
2231 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2233 if (isset($image[0]['child'][$namespace][$tag]))
2235 return $image[0]['child'][$namespace][$tag];
2239 if ($type & SIMPLEPIE_TYPE_RSS_090)
2241 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2243 if (isset($image[0]['child'][$namespace][$tag]))
2245 return $image[0]['child'][$namespace][$tag];
2249 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2251 if ($image = $this->get_channel_tags('', 'image'))
2253 if (isset($image[0]['child'][$namespace][$tag]))
2255 return $image[0]['child'][$namespace][$tag];
2262 function get_base($element = array())
2264 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2266 return $element['xml_base'];
2268 elseif ($this->get_link() !== null)
2270 return $this->get_link();
2274 return $this->subscribe_url();
2278 function sanitize($data, $type, $base = '')
2280 return $this->sanitize->sanitize($data, $type, $base);
2283 function get_title()
2285 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2287 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2289 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2291 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2293 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2295 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2297 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2299 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2301 elseif ($return = $this->get_channel_tags('', 'title'))
2303 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2305 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2307 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2309 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2311 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2319 function get_category($key = 0)
2321 $categories = $this->get_categories();
2322 if (isset($categories[$key]))
2324 return $categories[$key];
2332 function get_categories()
2334 $categories = array();
2336 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2341 if (isset($category['attribs']['']['term']))
2343 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2345 if (isset($category['attribs']['']['scheme']))
2347 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2349 if (isset($category['attribs']['']['label']))
2351 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2353 $categories[] =& new $this->category_class($term, $scheme, $label);
2355 foreach ((array) $this->get_channel_tags('', 'category') as $category)
2357 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2359 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2361 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2363 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2365 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2368 if (!empty($categories))
2370 return SimplePie_Misc::array_unique($categories);
2378 function get_author($key = 0)
2380 $authors = $this->get_authors();
2381 if (isset($authors[$key]))
2383 return $authors[$key];
2391 function get_authors()
2394 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2399 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2401 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2403 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2405 $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]));
2407 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2409 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2411 if ($name !== null || $email !== null || $uri !== null)
2413 $authors[] =& new $this->author_class($name, $uri, $email);
2416 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2421 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2423 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2425 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2427 $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]));
2429 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2431 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2433 if ($name !== null || $email !== null || $url !== null)
2435 $authors[] =& new $this->author_class($name, $url, $email);
2438 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2440 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2442 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2444 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2446 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2448 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2451 if (!empty($authors))
2453 return SimplePie_Misc::array_unique($authors);
2461 function get_contributor($key = 0)
2463 $contributors = $this->get_contributors();
2464 if (isset($contributors[$key]))
2466 return $contributors[$key];
2474 function get_contributors()
2476 $contributors = array();
2477 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2482 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2484 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2486 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2488 $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]));
2490 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2492 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2494 if ($name !== null || $email !== null || $uri !== null)
2496 $contributors[] =& new $this->author_class($name, $uri, $email);
2499 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2504 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2506 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2508 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2510 $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]));
2512 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2514 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2516 if ($name !== null || $email !== null || $url !== null)
2518 $contributors[] =& new $this->author_class($name, $url, $email);
2522 if (!empty($contributors))
2524 return SimplePie_Misc::array_unique($contributors);
2532 function get_link($key = 0, $rel = 'alternate')
2534 $links = $this->get_links($rel);
2535 if (isset($links[$key]))
2537 return $links[$key];
2546 * Added for parity between the parent-level and the item/entry-level.
2548 function get_permalink()
2550 return $this->get_link(0);
2553 function get_links($rel = 'alternate')
2555 if (!isset($this->data['links']))
2557 $this->data['links'] = array();
2558 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2560 foreach ($links as $link)
2562 if (isset($link['attribs']['']['href']))
2564 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2565 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2569 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2571 foreach ($links as $link)
2573 if (isset($link['attribs']['']['href']))
2575 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2576 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2581 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2583 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2585 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2587 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2589 if ($links = $this->get_channel_tags('', 'link'))
2591 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2594 $keys = array_keys($this->data['links']);
2595 foreach ($keys as $key)
2597 if (SimplePie_Misc::is_isegment_nz_nc($key))
2599 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2601 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2602 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2606 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2609 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2611 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2613 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2617 if (isset($this->data['links'][$rel]))
2619 return $this->data['links'][$rel];
2627 function get_description()
2629 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2631 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2633 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2635 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2637 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2639 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2641 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2643 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2645 elseif ($return = $this->get_channel_tags('', 'description'))
2647 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2649 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2651 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2653 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2655 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2657 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2659 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2661 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2663 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2671 function get_copyright()
2673 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2675 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2677 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2679 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2681 elseif ($return = $this->get_channel_tags('', 'copyright'))
2683 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2685 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2687 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2689 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2691 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2699 function get_language()
2701 if ($return = $this->get_channel_tags('', 'language'))
2703 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2705 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2707 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2709 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2711 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2715 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2717 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2719 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2721 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2723 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2725 elseif (isset($this->data['headers']['content-language']))
2727 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2735 function get_latitude()
2737 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2739 return (float) $return[0]['data'];
2741 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2743 return (float) $match[1];
2751 function get_longitude()
2753 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2755 return (float) $return[0]['data'];
2757 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2759 return (float) $return[0]['data'];
2761 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2763 return (float) $match[2];
2771 function get_image_title()
2773 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2775 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2777 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2779 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2781 elseif ($return = $this->get_image_tags('', 'title'))
2783 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2785 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2787 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2789 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2799 function get_image_url()
2801 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2803 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2805 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2807 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2809 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2811 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2813 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2815 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2817 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2819 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2821 elseif ($return = $this->get_image_tags('', 'url'))
2823 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2831 function get_image_link()
2833 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2835 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2837 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2839 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2841 elseif ($return = $this->get_image_tags('', 'link'))
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2851 function get_image_width()
2853 if ($return = $this->get_image_tags('', 'width'))
2855 return round($return[0]['data']);
2857 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2867 function get_image_height()
2869 if ($return = $this->get_image_tags('', 'height'))
2871 return round($return[0]['data']);
2873 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2883 function get_item_quantity($max = 0)
2885 $qty = count($this->get_items());
2892 return ($qty > $max) ? $max : $qty;
2896 function get_item($key = 0)
2898 $items = $this->get_items();
2899 if (isset($items[$key]))
2901 return $items[$key];
2909 function get_items($start = 0, $end = 0)
2911 if (!empty($this->multifeed_objects))
2913 return SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2915 elseif (!isset($this->data['items']))
2917 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2919 $keys = array_keys($items);
2920 foreach ($keys as $key)
2922 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2925 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2927 $keys = array_keys($items);
2928 foreach ($keys as $key)
2930 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2933 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2935 $keys = array_keys($items);
2936 foreach ($keys as $key)
2938 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2941 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2943 $keys = array_keys($items);
2944 foreach ($keys as $key)
2946 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2949 if ($items = $this->get_channel_tags('', 'item'))
2951 $keys = array_keys($items);
2952 foreach ($keys as $key)
2954 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2959 if (!empty($this->data['items']))
2961 // If we want to order it by date, check if all items have a date, and then sort it
2962 if ($this->order_by_date)
2964 if (!isset($this->data['ordered_items']))
2967 foreach ($this->data['items'] as $item)
2969 if (!$item->get_date('U'))
2976 $this->data['ordered_items'] = $this->data['items'];
2979 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2982 $items = $this->data['ordered_items'];
2986 $items = $this->data['items'];
2989 // Slice the data as desired
2992 return array_slice($items, $start);
2996 return array_slice($items, $start, $end);
3005 function sort_items($a, $b)
3007 return $a->get_date('U') <= $b->get_date('U');
3010 function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3012 if (is_array($urls) && sizeof($urls) > 0)
3015 foreach ($urls as $arg)
3017 if (is_a($arg, 'SimplePie'))
3019 $items = array_merge($items, $arg->get_items(0, $limit));
3023 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3028 foreach ($items as $item)
3030 if (!$item->get_date('U'))
3039 usort($items, array('SimplePie', 'sort_items'));
3044 return array_slice($items, $start);
3048 return array_slice($items, $start, $end);
3053 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3059 class SimplePie_Item
3062 var $data = array();
3064 function SimplePie_Item($feed, $data)
3066 $this->feed = $feed;
3067 $this->data = $data;
3070 function __toString()
3072 return md5(serialize($this->data));
3076 * Remove items that link back to this before destroying this object
3078 function __destruct()
3083 function get_item_tags($namespace, $tag)
3085 if (isset($this->data['child'][$namespace][$tag]))
3087 return $this->data['child'][$namespace][$tag];
3095 function get_base($element = array())
3097 return $this->feed->get_base($element);
3100 function sanitize($data, $type, $base = '')
3102 return $this->feed->sanitize($data, $type, $base);
3110 function get_id($hash = false)
3114 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3116 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3118 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3120 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3122 elseif ($return = $this->get_item_tags('', 'guid'))
3124 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3126 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3128 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3130 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3132 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3134 elseif (($return = $this->get_permalink()) !== null)
3138 elseif (($return = $this->get_title()) !== null)
3143 if ($this->get_permalink() !== null || $this->get_title() !== null)
3145 return md5($this->get_permalink() . $this->get_title());
3149 return md5(serialize($this->data));
3153 function get_title()
3155 if (!isset($this->data['title']))
3157 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3159 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3161 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3163 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3165 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3167 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3169 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3171 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3173 elseif ($return = $this->get_item_tags('', 'title'))
3175 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3177 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3179 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3181 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3183 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3187 $this->data['title'] = null;
3190 return $this->data['title'];
3193 function get_description($description_only = false)
3195 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3197 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3199 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3201 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3203 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3205 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3207 elseif ($return = $this->get_item_tags('', 'description'))
3209 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3211 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3213 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3215 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3217 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3219 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3221 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3223 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3225 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3227 elseif (!$description_only)
3229 return $this->get_content(true);
3237 function get_content($content_only = false)
3239 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3241 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3243 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3245 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3247 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3249 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3251 elseif (!$content_only)
3253 return $this->get_description(true);
3261 function get_category($key = 0)
3263 $categories = $this->get_categories();
3264 if (isset($categories[$key]))
3266 return $categories[$key];
3274 function get_categories()
3276 $categories = array();
3278 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3283 if (isset($category['attribs']['']['term']))
3285 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3287 if (isset($category['attribs']['']['scheme']))
3289 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3291 if (isset($category['attribs']['']['label']))
3293 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3295 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
3297 foreach ((array) $this->get_item_tags('', 'category') as $category)
3299 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3301 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3303 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3305 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3307 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3310 if (!empty($categories))
3312 return SimplePie_Misc::array_unique($categories);
3320 function get_author($key = 0)
3322 $authors = $this->get_authors();
3323 if (isset($authors[$key]))
3325 return $authors[$key];
3333 function get_contributor($key = 0)
3335 $contributors = $this->get_contributors();
3336 if (isset($contributors[$key]))
3338 return $contributors[$key];
3346 function get_contributors()
3348 $contributors = array();
3349 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3354 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3356 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3358 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3360 $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]));
3362 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3364 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3366 if ($name !== null || $email !== null || $uri !== null)
3368 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
3371 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3376 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3378 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3380 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3382 $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]));
3384 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3386 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3388 if ($name !== null || $email !== null || $url !== null)
3390 $contributors[] =& new $this->feed->author_class($name, $url, $email);
3394 if (!empty($contributors))
3396 return SimplePie_Misc::array_unique($contributors);
3405 * @todo Atom inheritance (item author, source author, feed author)
3407 function get_authors()
3410 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3415 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3417 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3419 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3421 $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]));
3423 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3425 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3427 if ($name !== null || $email !== null || $uri !== null)
3429 $authors[] =& new $this->feed->author_class($name, $uri, $email);
3432 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3437 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3439 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3441 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3443 $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]));
3445 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3447 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3449 if ($name !== null || $email !== null || $url !== null)
3451 $authors[] =& new $this->feed->author_class($name, $url, $email);
3454 if ($author = $this->get_item_tags('', 'author'))
3456 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3458 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3460 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3462 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3464 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3466 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3468 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3471 if (!empty($authors))
3473 return SimplePie_Misc::array_unique($authors);
3475 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3479 elseif ($authors = $this->feed->get_authors())
3489 function get_copyright()
3491 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3493 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3495 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3497 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3499 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3501 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3509 function get_date($date_format = 'j F Y, g:i a')
3511 if (!isset($this->data['date']))
3513 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3515 $this->data['date']['raw'] = $return[0]['data'];
3517 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3519 $this->data['date']['raw'] = $return[0]['data'];
3521 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3523 $this->data['date']['raw'] = $return[0]['data'];
3525 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3527 $this->data['date']['raw'] = $return[0]['data'];
3529 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3531 $this->data['date']['raw'] = $return[0]['data'];
3533 elseif ($return = $this->get_item_tags('', 'pubDate'))
3535 $this->data['date']['raw'] = $return[0]['data'];
3537 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3539 $this->data['date']['raw'] = $return[0]['data'];
3541 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3543 $this->data['date']['raw'] = $return[0]['data'];
3546 if (!empty($this->data['date']['raw']))
3548 $parser = SimplePie_Parse_Date::get();
3549 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3553 $this->data['date'] = null;
3556 if ($this->data['date'])
3558 $date_format = (string) $date_format;
3559 switch ($date_format)
3562 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3565 return $this->data['date']['parsed'];
3568 return date($date_format, $this->data['date']['parsed']);
3577 function get_local_date($date_format = '%c')
3581 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3583 elseif (($date = $this->get_date('U')) !== null)
3585 return strftime($date_format, $date);
3593 function get_permalink()
3595 $link = $this->get_link();
3596 $enclosure = $this->get_enclosure(0);
3601 elseif ($enclosure !== null)
3603 return $enclosure->get_link();
3611 function get_link($key = 0, $rel = 'alternate')
3613 $links = $this->get_links($rel);
3614 if ($links[$key] !== null)
3616 return $links[$key];
3624 function get_links($rel = 'alternate')
3626 if (!isset($this->data['links']))
3628 $this->data['links'] = array();
3629 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3631 if (isset($link['attribs']['']['href']))
3633 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3634 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3638 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3640 if (isset($link['attribs']['']['href']))
3642 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3643 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3646 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3648 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3650 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3652 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3654 if ($links = $this->get_item_tags('', 'link'))
3656 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3658 if ($links = $this->get_item_tags('', 'guid'))
3660 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3662 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3666 $keys = array_keys($this->data['links']);
3667 foreach ($keys as $key)
3669 if (SimplePie_Misc::is_isegment_nz_nc($key))
3671 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3673 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3674 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3678 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3681 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3683 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3685 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3688 if (isset($this->data['links'][$rel]))
3690 return $this->data['links'][$rel];
3699 * @todo Add ability to prefer one type of content over another (in a media group).
3701 function get_enclosure($key = 0, $prefer = null)
3703 $enclosures = $this->get_enclosures();
3704 if (isset($enclosures[$key]))
3706 return $enclosures[$key];
3715 * Grabs all available enclosures (podcasts, etc.)
3717 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3719 * 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.
3721 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3722 * @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).
3724 function get_enclosures()
3726 if (!isset($this->data['enclosures']))
3728 $this->data['enclosures'] = array();
3731 $captions_parent = null;
3732 $categories_parent = null;
3733 $copyrights_parent = null;
3734 $credits_parent = null;
3735 $description_parent = null;
3736 $duration_parent = null;
3737 $hashes_parent = null;
3738 $keywords_parent = null;
3739 $player_parent = null;
3740 $ratings_parent = null;
3741 $restrictions_parent = null;
3742 $thumbnails_parent = null;
3743 $title_parent = null;
3745 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3746 $parent = $this->get_feed();
3749 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3751 foreach ($captions as $caption)
3753 $caption_type = null;
3754 $caption_lang = null;
3755 $caption_startTime = null;
3756 $caption_endTime = null;
3757 $caption_text = null;
3758 if (isset($caption['attribs']['']['type']))
3760 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3762 if (isset($caption['attribs']['']['lang']))
3764 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3766 if (isset($caption['attribs']['']['start']))
3768 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3770 if (isset($caption['attribs']['']['end']))
3772 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3774 if (isset($caption['data']))
3776 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3778 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3781 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3783 foreach ($captions as $caption)
3785 $caption_type = null;
3786 $caption_lang = null;
3787 $caption_startTime = null;
3788 $caption_endTime = null;
3789 $caption_text = null;
3790 if (isset($caption['attribs']['']['type']))
3792 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3794 if (isset($caption['attribs']['']['lang']))
3796 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3798 if (isset($caption['attribs']['']['start']))
3800 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3802 if (isset($caption['attribs']['']['end']))
3804 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3806 if (isset($caption['data']))
3808 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3810 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3813 if (is_array($captions_parent))
3815 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3819 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3824 if (isset($category['data']))
3826 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3828 if (isset($category['attribs']['']['scheme']))
3830 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3834 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3836 if (isset($category['attribs']['']['label']))
3838 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3840 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3842 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3847 if (isset($category['data']))
3849 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3851 if (isset($category['attribs']['']['scheme']))
3853 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3857 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3859 if (isset($category['attribs']['']['label']))
3861 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3863 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3865 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3868 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3870 if (isset($category['attribs']['']['text']))
3872 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3874 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3876 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3878 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3880 if (isset($subcategory['attribs']['']['text']))
3882 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3884 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3888 if (is_array($categories_parent))
3890 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3894 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3896 $copyright_url = null;
3897 $copyright_label = null;
3898 if (isset($copyright[0]['attribs']['']['url']))
3900 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3902 if (isset($copyright[0]['data']))
3904 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3906 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3908 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3910 $copyright_url = null;
3911 $copyright_label = null;
3912 if (isset($copyright[0]['attribs']['']['url']))
3914 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3916 if (isset($copyright[0]['data']))
3918 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3920 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3924 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3926 foreach ($credits as $credit)
3928 $credit_role = null;
3929 $credit_scheme = null;
3930 $credit_name = null;
3931 if (isset($credit['attribs']['']['role']))
3933 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3935 if (isset($credit['attribs']['']['scheme']))
3937 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3941 $credit_scheme = 'urn:ebu';
3943 if (isset($credit['data']))
3945 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3947 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3950 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3952 foreach ($credits as $credit)
3954 $credit_role = null;
3955 $credit_scheme = null;
3956 $credit_name = null;
3957 if (isset($credit['attribs']['']['role']))
3959 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3961 if (isset($credit['attribs']['']['scheme']))
3963 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3967 $credit_scheme = 'urn:ebu';
3969 if (isset($credit['data']))
3971 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3973 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3976 if (is_array($credits_parent))
3978 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3982 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3984 if (isset($description_parent[0]['data']))
3986 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3989 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3991 if (isset($description_parent[0]['data']))
3993 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3998 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4003 if (isset($duration_parent[0]['data']))
4005 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4006 if (sizeof($temp) > 0)
4008 (int) $seconds = array_pop($temp);
4010 if (sizeof($temp) > 0)
4012 (int) $minutes = array_pop($temp);
4013 $seconds += $minutes * 60;
4015 if (sizeof($temp) > 0)
4017 (int) $hours = array_pop($temp);
4018 $seconds += $hours * 3600;
4021 $duration_parent = $seconds;
4026 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4028 foreach ($hashes_iterator as $hash)
4032 if (isset($hash['data']))
4034 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4036 if (isset($hash['attribs']['']['algo']))
4038 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4044 $hashes_parent[] = $algo.':'.$value;
4047 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4049 foreach ($hashes_iterator as $hash)
4053 if (isset($hash['data']))
4055 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4057 if (isset($hash['attribs']['']['algo']))
4059 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4065 $hashes_parent[] = $algo.':'.$value;
4068 if (is_array($hashes_parent))
4070 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4074 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4076 if (isset($keywords[0]['data']))
4078 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4079 foreach ($temp as $word)
4081 $keywords_parent[] = trim($word);
4086 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4088 if (isset($keywords[0]['data']))
4090 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4091 foreach ($temp as $word)
4093 $keywords_parent[] = trim($word);
4098 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4100 if (isset($keywords[0]['data']))
4102 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4103 foreach ($temp as $word)
4105 $keywords_parent[] = trim($word);
4110 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4112 if (isset($keywords[0]['data']))
4114 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4115 foreach ($temp as $word)
4117 $keywords_parent[] = trim($word);
4122 if (is_array($keywords_parent))
4124 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4128 if ($player_parent = $this->get_item_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);
4135 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4137 if (isset($player_parent[0]['attribs']['']['url']))
4139 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4144 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4146 foreach ($ratings as $rating)
4148 $rating_scheme = null;
4149 $rating_value = null;
4150 if (isset($rating['attribs']['']['scheme']))
4152 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4156 $rating_scheme = 'urn:simple';
4158 if (isset($rating['data']))
4160 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4162 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4165 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4167 foreach ($ratings as $rating)
4169 $rating_scheme = 'urn:itunes';
4170 $rating_value = null;
4171 if (isset($rating['data']))
4173 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4175 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4178 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4180 foreach ($ratings as $rating)
4182 $rating_scheme = null;
4183 $rating_value = null;
4184 if (isset($rating['attribs']['']['scheme']))
4186 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4190 $rating_scheme = 'urn:simple';
4192 if (isset($rating['data']))
4194 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4196 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4199 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4201 foreach ($ratings as $rating)
4203 $rating_scheme = 'urn:itunes';
4204 $rating_value = null;
4205 if (isset($rating['data']))
4207 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4209 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4212 if (is_array($ratings_parent))
4214 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4218 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4220 foreach ($restrictions as $restriction)
4222 $restriction_relationship = null;
4223 $restriction_type = null;
4224 $restriction_value = null;
4225 if (isset($restriction['attribs']['']['relationship']))
4227 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4229 if (isset($restriction['attribs']['']['type']))
4231 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4233 if (isset($restriction['data']))
4235 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4237 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4240 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4242 foreach ($restrictions as $restriction)
4244 $restriction_relationship = 'allow';
4245 $restriction_type = null;
4246 $restriction_value = 'itunes';
4247 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4249 $restriction_relationship = 'deny';
4251 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4254 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4256 foreach ($restrictions as $restriction)
4258 $restriction_relationship = null;
4259 $restriction_type = null;
4260 $restriction_value = null;
4261 if (isset($restriction['attribs']['']['relationship']))
4263 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4265 if (isset($restriction['attribs']['']['type']))
4267 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4269 if (isset($restriction['data']))
4271 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4273 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4276 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4278 foreach ($restrictions as $restriction)
4280 $restriction_relationship = 'allow';
4281 $restriction_type = null;
4282 $restriction_value = 'itunes';
4283 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
4285 $restriction_relationship = 'deny';
4287 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4290 if (is_array($restrictions_parent))
4292 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4296 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4298 foreach ($thumbnails as $thumbnail)
4300 if (isset($thumbnail['attribs']['']['url']))
4302 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4306 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4308 foreach ($thumbnails as $thumbnail)
4310 if (isset($thumbnail['attribs']['']['url']))
4312 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4318 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4320 if (isset($title_parent[0]['data']))
4322 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4325 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4327 if (isset($title_parent[0]['data']))
4329 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4347 $samplingrate = null;
4357 $description = null;
4362 $restrictions = null;
4366 // If we have media:group tags, loop through them.
4367 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4369 // If we have media:content tags, loop through them.
4370 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4372 if (isset($content['attribs']['']['url']))
4385 $samplingrate = null;
4395 $description = null;
4400 $restrictions = null;
4404 // Start checking the attributes of media:content
4405 if (isset($content['attribs']['']['bitrate']))
4407 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4409 if (isset($content['attribs']['']['channels']))
4411 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4413 if (isset($content['attribs']['']['duration']))
4415 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4419 $duration = $duration_parent;
4421 if (isset($content['attribs']['']['expression']))
4423 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4425 if (isset($content['attribs']['']['framerate']))
4427 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4429 if (isset($content['attribs']['']['height']))
4431 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4433 if (isset($content['attribs']['']['lang']))
4435 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4437 if (isset($content['attribs']['']['fileSize']))
4439 $length = ceil($content['attribs']['']['fileSize']);
4441 if (isset($content['attribs']['']['medium']))
4443 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4445 if (isset($content['attribs']['']['samplingrate']))
4447 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4449 if (isset($content['attribs']['']['type']))
4451 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4453 if (isset($content['attribs']['']['width']))
4455 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4457 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4459 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4462 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4464 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4466 $caption_type = null;
4467 $caption_lang = null;
4468 $caption_startTime = null;
4469 $caption_endTime = null;
4470 $caption_text = null;
4471 if (isset($caption['attribs']['']['type']))
4473 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4475 if (isset($caption['attribs']['']['lang']))
4477 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4479 if (isset($caption['attribs']['']['start']))
4481 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4483 if (isset($caption['attribs']['']['end']))
4485 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4487 if (isset($caption['data']))
4489 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4491 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4493 if (is_array($captions))
4495 $captions = array_values(SimplePie_Misc::array_unique($captions));
4498 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4500 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4502 $caption_type = null;
4503 $caption_lang = null;
4504 $caption_startTime = null;
4505 $caption_endTime = null;
4506 $caption_text = null;
4507 if (isset($caption['attribs']['']['type']))
4509 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4511 if (isset($caption['attribs']['']['lang']))
4513 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4515 if (isset($caption['attribs']['']['start']))
4517 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4519 if (isset($caption['attribs']['']['end']))
4521 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4523 if (isset($caption['data']))
4525 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4527 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4529 if (is_array($captions))
4531 $captions = array_values(SimplePie_Misc::array_unique($captions));
4536 $captions = $captions_parent;
4540 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4542 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4547 if (isset($category['data']))
4549 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4551 if (isset($category['attribs']['']['scheme']))
4553 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4557 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4559 if (isset($category['attribs']['']['label']))
4561 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4563 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4566 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4568 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4573 if (isset($category['data']))
4575 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4577 if (isset($category['attribs']['']['scheme']))
4579 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4583 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4585 if (isset($category['attribs']['']['label']))
4587 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4589 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4592 if (is_array($categories) && is_array($categories_parent))
4594 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4596 elseif (is_array($categories))
4598 $categories = array_values(SimplePie_Misc::array_unique($categories));
4600 elseif (is_array($categories_parent))
4602 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4606 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4608 $copyright_url = null;
4609 $copyright_label = null;
4610 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4612 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4614 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4616 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4618 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4620 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4622 $copyright_url = null;
4623 $copyright_label = null;
4624 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4626 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4628 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4630 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4632 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4636 $copyrights = $copyrights_parent;
4640 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4642 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4644 $credit_role = null;
4645 $credit_scheme = null;
4646 $credit_name = null;
4647 if (isset($credit['attribs']['']['role']))
4649 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4651 if (isset($credit['attribs']['']['scheme']))
4653 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4657 $credit_scheme = 'urn:ebu';
4659 if (isset($credit['data']))
4661 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4663 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4665 if (is_array($credits))
4667 $credits = array_values(SimplePie_Misc::array_unique($credits));
4670 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4672 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4674 $credit_role = null;
4675 $credit_scheme = null;
4676 $credit_name = null;
4677 if (isset($credit['attribs']['']['role']))
4679 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4681 if (isset($credit['attribs']['']['scheme']))
4683 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4687 $credit_scheme = 'urn:ebu';
4689 if (isset($credit['data']))
4691 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4693 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4695 if (is_array($credits))
4697 $credits = array_values(SimplePie_Misc::array_unique($credits));
4702 $credits = $credits_parent;
4706 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4708 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4710 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4712 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4716 $description = $description_parent;
4720 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4722 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4726 if (isset($hash['data']))
4728 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4730 if (isset($hash['attribs']['']['algo']))
4732 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4738 $hashes[] = $algo.':'.$value;
4740 if (is_array($hashes))
4742 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4745 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4747 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4751 if (isset($hash['data']))
4753 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4755 if (isset($hash['attribs']['']['algo']))
4757 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4763 $hashes[] = $algo.':'.$value;
4765 if (is_array($hashes))
4767 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4772 $hashes = $hashes_parent;
4776 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4778 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4780 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4781 foreach ($temp as $word)
4783 $keywords[] = trim($word);
4787 if (is_array($keywords))
4789 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4792 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4794 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4796 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4797 foreach ($temp as $word)
4799 $keywords[] = trim($word);
4803 if (is_array($keywords))
4805 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4810 $keywords = $keywords_parent;
4814 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4816 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4818 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4820 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4824 $player = $player_parent;
4828 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4830 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4832 $rating_scheme = null;
4833 $rating_value = null;
4834 if (isset($rating['attribs']['']['scheme']))
4836 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4840 $rating_scheme = 'urn:simple';
4842 if (isset($rating['data']))
4844 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4846 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4848 if (is_array($ratings))
4850 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4853 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4855 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4857 $rating_scheme = null;
4858 $rating_value = null;
4859 if (isset($rating['attribs']['']['scheme']))
4861 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4865 $rating_scheme = 'urn:simple';
4867 if (isset($rating['data']))
4869 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4871 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4873 if (is_array($ratings))
4875 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4880 $ratings = $ratings_parent;
4884 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4886 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4888 $restriction_relationship = null;
4889 $restriction_type = null;
4890 $restriction_value = null;
4891 if (isset($restriction['attribs']['']['relationship']))
4893 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4895 if (isset($restriction['attribs']['']['type']))
4897 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4899 if (isset($restriction['data']))
4901 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4903 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4905 if (is_array($restrictions))
4907 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4910 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4912 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4914 $restriction_relationship = null;
4915 $restriction_type = null;
4916 $restriction_value = null;
4917 if (isset($restriction['attribs']['']['relationship']))
4919 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4921 if (isset($restriction['attribs']['']['type']))
4923 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4925 if (isset($restriction['data']))
4927 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4929 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4931 if (is_array($restrictions))
4933 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4938 $restrictions = $restrictions_parent;
4942 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4944 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4946 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4948 if (is_array($thumbnails))
4950 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4953 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4955 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4957 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4959 if (is_array($thumbnails))
4961 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4966 $thumbnails = $thumbnails_parent;
4970 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4972 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4974 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4976 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4980 $title = $title_parent;
4983 $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);
4988 // If we have standalone media:content tags, loop through them.
4989 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4991 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4993 if (isset($content['attribs']['']['url']))
5006 $samplingrate = null;
5016 $description = null;
5021 $restrictions = null;
5025 // Start checking the attributes of media:content
5026 if (isset($content['attribs']['']['bitrate']))
5028 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5030 if (isset($content['attribs']['']['channels']))
5032 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5034 if (isset($content['attribs']['']['duration']))
5036 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5040 $duration = $duration_parent;
5042 if (isset($content['attribs']['']['expression']))
5044 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5046 if (isset($content['attribs']['']['framerate']))
5048 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5050 if (isset($content['attribs']['']['height']))
5052 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5054 if (isset($content['attribs']['']['lang']))
5056 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5058 if (isset($content['attribs']['']['fileSize']))
5060 $length = ceil($content['attribs']['']['fileSize']);
5062 if (isset($content['attribs']['']['medium']))
5064 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5066 if (isset($content['attribs']['']['samplingrate']))
5068 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5070 if (isset($content['attribs']['']['type']))
5072 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5074 if (isset($content['attribs']['']['width']))
5076 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5078 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5080 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5083 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5085 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5087 $caption_type = null;
5088 $caption_lang = null;
5089 $caption_startTime = null;
5090 $caption_endTime = null;
5091 $caption_text = null;
5092 if (isset($caption['attribs']['']['type']))
5094 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5096 if (isset($caption['attribs']['']['lang']))
5098 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5100 if (isset($caption['attribs']['']['start']))
5102 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5104 if (isset($caption['attribs']['']['end']))
5106 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5108 if (isset($caption['data']))
5110 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5112 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5114 if (is_array($captions))
5116 $captions = array_values(SimplePie_Misc::array_unique($captions));
5121 $captions = $captions_parent;
5125 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5127 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5132 if (isset($category['data']))
5134 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5136 if (isset($category['attribs']['']['scheme']))
5138 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5142 $scheme = 'http://search.yahoo.com/mrss/category_schema';
5144 if (isset($category['attribs']['']['label']))
5146 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5148 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
5151 if (is_array($categories) && is_array($categories_parent))
5153 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5155 elseif (is_array($categories))
5157 $categories = array_values(SimplePie_Misc::array_unique($categories));
5159 elseif (is_array($categories_parent))
5161 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5169 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5171 $copyright_url = null;
5172 $copyright_label = null;
5173 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5175 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5177 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5179 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5181 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
5185 $copyrights = $copyrights_parent;
5189 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5191 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5193 $credit_role = null;
5194 $credit_scheme = null;
5195 $credit_name = null;
5196 if (isset($credit['attribs']['']['role']))
5198 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5200 if (isset($credit['attribs']['']['scheme']))
5202 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5206 $credit_scheme = 'urn:ebu';
5208 if (isset($credit['data']))
5210 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5212 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5214 if (is_array($credits))
5216 $credits = array_values(SimplePie_Misc::array_unique($credits));
5221 $credits = $credits_parent;
5225 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5227 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5231 $description = $description_parent;
5235 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5237 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5241 if (isset($hash['data']))
5243 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5245 if (isset($hash['attribs']['']['algo']))
5247 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5253 $hashes[] = $algo.':'.$value;
5255 if (is_array($hashes))
5257 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5262 $hashes = $hashes_parent;
5266 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5268 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5270 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5271 foreach ($temp as $word)
5273 $keywords[] = trim($word);
5277 if (is_array($keywords))
5279 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5284 $keywords = $keywords_parent;
5288 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5290 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5294 $player = $player_parent;
5298 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5300 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5302 $rating_scheme = null;
5303 $rating_value = null;
5304 if (isset($rating['attribs']['']['scheme']))
5306 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5310 $rating_scheme = 'urn:simple';
5312 if (isset($rating['data']))
5314 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5316 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
5318 if (is_array($ratings))
5320 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5325 $ratings = $ratings_parent;
5329 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5331 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5333 $restriction_relationship = null;
5334 $restriction_type = null;
5335 $restriction_value = null;
5336 if (isset($restriction['attribs']['']['relationship']))
5338 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5340 if (isset($restriction['attribs']['']['type']))
5342 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5344 if (isset($restriction['data']))
5346 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5348 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5350 if (is_array($restrictions))
5352 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5357 $restrictions = $restrictions_parent;
5361 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5363 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5365 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5367 if (is_array($thumbnails))
5369 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5374 $thumbnails = $thumbnails_parent;
5378 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5380 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5384 $title = $title_parent;
5387 $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);
5392 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5394 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5407 $samplingrate = null;
5412 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5413 if (isset($link['attribs']['']['type']))
5415 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5417 if (isset($link['attribs']['']['length']))
5419 $length = ceil($link['attribs']['']['length']);
5422 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5423 $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);
5427 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5429 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
5442 $samplingrate = null;
5447 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5448 if (isset($link['attribs']['']['type']))
5450 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5452 if (isset($link['attribs']['']['length']))
5454 $length = ceil($link['attribs']['']['length']);
5457 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5458 $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);
5462 if ($enclosure = $this->get_item_tags('', 'enclosure'))
5464 if (isset($enclosure[0]['attribs']['']['url']))
5477 $samplingrate = null;
5482 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5483 if (isset($enclosure[0]['attribs']['']['type']))
5485 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5487 if (isset($enclosure[0]['attribs']['']['length']))
5489 $length = ceil($enclosure[0]['attribs']['']['length']);
5492 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5493 $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);
5497 if (sizeof($this->data['enclosures']) == 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
5499 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5500 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5503 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5505 if (!empty($this->data['enclosures']))
5507 return $this->data['enclosures'];
5515 function get_latitude()
5517 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5519 return (float) $return[0]['data'];
5521 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5523 return (float) $match[1];
5531 function get_longitude()
5533 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5535 return (float) $return[0]['data'];
5537 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5539 return (float) $return[0]['data'];
5541 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5543 return (float) $match[2];
5551 function get_source()
5553 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5555 return new $this->feed->source_class($this, $return[0]);
5564 * Creates the add_to_* methods' return data
5567 * @param string $item_url String to prefix to the item permalink
5568 * @param string $title_url String to prefix to the item title
5569 * (and suffix to the item permalink)
5570 * @return mixed URL if feed exists, false otherwise
5572 function add_to_service($item_url, $title_url = null, $summary_url = null)
5574 if ($this->get_permalink() !== null)
5576 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5577 if ($title_url !== null && $this->get_title() !== null)
5579 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5581 if ($summary_url !== null && $this->get_description() !== null)
5583 $return .= $this->sanitize($summary_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_description());
5593 function add_to_blinklist()
5595 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5598 function add_to_blogmarks()
5600 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5603 function add_to_delicious()
5605 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5608 function add_to_digg()
5610 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5613 function add_to_furl()
5615 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5618 function add_to_magnolia()
5620 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5623 function add_to_myweb20()
5625 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5628 function add_to_newsvine()
5630 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5633 function add_to_reddit()
5635 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5638 function add_to_segnalo()
5640 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5643 function add_to_simpy()
5645 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5648 function add_to_spurl()
5650 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5653 function add_to_wists()
5655 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5658 function search_technorati()
5660 return $this->add_to_service('http://www.technorati.com/search/');
5664 class SimplePie_Source
5667 var $data = array();
5669 function SimplePie_Source($item, $data)
5671 $this->item = $item;
5672 $this->data = $data;
5675 function __toString()
5677 return md5(serialize($this->data));
5681 * Remove items that link back to this before destroying this object
5683 function __destruct()
5688 function get_source_tags($namespace, $tag)
5690 if (isset($this->data['child'][$namespace][$tag]))
5692 return $this->data['child'][$namespace][$tag];
5700 function get_base($element = array())
5702 return $this->item->get_base($element);
5705 function sanitize($data, $type, $base = '')
5707 return $this->item->sanitize($data, $type, $base);
5715 function get_title()
5717 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5719 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5721 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5723 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5725 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5727 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5729 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5731 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5733 elseif ($return = $this->get_source_tags('', 'title'))
5735 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5737 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5739 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5741 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5743 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5751 function get_category($key = 0)
5753 $categories = $this->get_categories();
5754 if (isset($categories[$key]))
5756 return $categories[$key];
5764 function get_categories()
5766 $categories = array();
5768 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5773 if (isset($category['attribs']['']['term']))
5775 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5777 if (isset($category['attribs']['']['scheme']))
5779 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5781 if (isset($category['attribs']['']['label']))
5783 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5785 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
5787 foreach ((array) $this->get_source_tags('', 'category') as $category)
5789 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5791 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5793 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5795 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5797 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5800 if (!empty($categories))
5802 return SimplePie_Misc::array_unique($categories);
5810 function get_author($key = 0)
5812 $authors = $this->get_authors();
5813 if (isset($authors[$key]))
5815 return $authors[$key];
5823 function get_authors()
5826 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5831 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5833 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5835 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5837 $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]));
5839 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5841 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5843 if ($name !== null || $email !== null || $uri !== null)
5845 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
5848 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5853 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5855 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5857 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5859 $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]));
5861 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5863 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5865 if ($name !== null || $email !== null || $url !== null)
5867 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
5870 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5872 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5874 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5876 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5878 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5880 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5883 if (!empty($authors))
5885 return SimplePie_Misc::array_unique($authors);
5893 function get_contributor($key = 0)
5895 $contributors = $this->get_contributors();
5896 if (isset($contributors[$key]))
5898 return $contributors[$key];
5906 function get_contributors()
5908 $contributors = array();
5909 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
5914 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5916 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5918 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5920 $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]));
5922 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5924 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5926 if ($name !== null || $email !== null || $uri !== null)
5928 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
5931 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
5936 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5938 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5940 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5942 $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]));
5944 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5946 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5948 if ($name !== null || $email !== null || $url !== null)
5950 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
5954 if (!empty($contributors))
5956 return SimplePie_Misc::array_unique($contributors);
5964 function get_link($key = 0, $rel = 'alternate')
5966 $links = $this->get_links($rel);
5967 if (isset($links[$key]))
5969 return $links[$key];
5978 * Added for parity between the parent-level and the item/entry-level.
5980 function get_permalink()
5982 return $this->get_link(0);
5985 function get_links($rel = 'alternate')
5987 if (!isset($this->data['links']))
5989 $this->data['links'] = array();
5990 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
5992 foreach ($links as $link)
5994 if (isset($link['attribs']['']['href']))
5996 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
5997 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6001 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6003 foreach ($links as $link)
6005 if (isset($link['attribs']['']['href']))
6007 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6008 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6013 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6015 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6017 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6019 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6021 if ($links = $this->get_source_tags('', 'link'))
6023 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6026 $keys = array_keys($this->data['links']);
6027 foreach ($keys as $key)
6029 if (SimplePie_Misc::is_isegment_nz_nc($key))
6031 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6033 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6034 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6038 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6041 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6043 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6045 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6049 if (isset($this->data['links'][$rel]))
6051 return $this->data['links'][$rel];
6059 function get_description()
6061 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6063 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6065 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6067 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6069 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6071 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6073 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6075 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6077 elseif ($return = $this->get_source_tags('', 'description'))
6079 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6081 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6083 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6085 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6087 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6089 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6091 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6093 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6095 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6103 function get_copyright()
6105 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6107 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6109 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6111 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6113 elseif ($return = $this->get_source_tags('', 'copyright'))
6115 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6117 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6119 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6121 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6123 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6131 function get_language()
6133 if ($return = $this->get_source_tags('', 'language'))
6135 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6137 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6139 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6141 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6143 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6145 elseif (isset($this->data['xml_lang']))
6147 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6155 function get_latitude()
6157 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6159 return (float) $return[0]['data'];
6161 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6163 return (float) $match[1];
6171 function get_longitude()
6173 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6175 return (float) $return[0]['data'];
6177 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6179 return (float) $return[0]['data'];
6181 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
6183 return (float) $match[2];
6191 function get_image_url()
6193 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6195 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6197 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6199 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6201 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6203 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6212 class SimplePie_Author
6218 // Constructor, used to input the data
6219 function SimplePie_Author($name = null, $link = null, $email = null)
6221 $this->name = $name;
6222 $this->link = $link;
6223 $this->email = $email;
6226 function __toString()
6228 // There is no $this->data here
6229 return md5(serialize($this));
6234 if ($this->name !== null)
6246 if ($this->link !== null)
6256 function get_email()
6258 if ($this->email !== null)
6260 return $this->email;
6269 class SimplePie_Category
6275 // Constructor, used to input the data
6276 function SimplePie_Category($term = null, $scheme = null, $label = null)
6278 $this->term = $term;
6279 $this->scheme = $scheme;
6280 $this->label = $label;
6283 function __toString()
6285 // There is no $this->data here
6286 return md5(serialize($this));
6291 if ($this->term !== null)
6301 function get_scheme()
6303 if ($this->scheme !== null)
6305 return $this->scheme;
6313 function get_label()
6315 if ($this->label !== null)
6317 return $this->label;
6321 return $this->get_term();
6326 class SimplePie_Enclosure
6356 // Constructor, used to input the data
6357 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)
6359 $this->bitrate = $bitrate;
6360 $this->captions = $captions;
6361 $this->categories = $categories;
6362 $this->channels = $channels;
6363 $this->copyright = $copyright;
6364 $this->credits = $credits;
6365 $this->description = $description;
6366 $this->duration = $duration;
6367 $this->expression = $expression;
6368 $this->framerate = $framerate;
6369 $this->hashes = $hashes;
6370 $this->height = $height;
6371 $this->javascript = $javascript;
6372 $this->keywords = $keywords;
6373 $this->lang = $lang;
6374 $this->length = $length;
6375 $this->link = $link;
6376 $this->medium = $medium;
6377 $this->player = $player;
6378 $this->ratings = $ratings;
6379 $this->restrictions = $restrictions;
6380 $this->samplingrate = $samplingrate;
6381 $this->thumbnails = $thumbnails;
6382 $this->title = $title;
6383 $this->type = $type;
6384 $this->width = $width;
6385 if (class_exists('idna_convert'))
6387 $idn =& new idna_convert;
6388 $parsed = SimplePie_Misc::parse_url($link);
6389 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6391 $this->handler = $this->get_handler(); // Needs to load last
6394 function __toString()
6396 // There is no $this->data here
6397 return md5(serialize($this));
6400 function get_bitrate()
6402 if ($this->bitrate !== null)
6404 return $this->bitrate;
6412 function get_caption($key = 0)
6414 $captions = $this->get_captions();
6415 if (isset($captions[$key]))
6417 return $captions[$key];
6425 function get_captions()
6427 if ($this->captions !== null)
6429 return $this->captions;
6437 function get_category($key = 0)
6439 $categories = $this->get_categories();
6440 if (isset($categories[$key]))
6442 return $categories[$key];
6450 function get_categories()
6452 if ($this->categories !== null)
6454 return $this->categories;
6462 function get_channels()
6464 if ($this->channels !== null)
6466 return $this->channels;
6474 function get_copyright()
6476 if ($this->copyright !== null)
6478 return $this->copyright;
6486 function get_credit($key = 0)
6488 $credits = $this->get_credits();
6489 if (isset($credits[$key]))
6491 return $credits[$key];
6499 function get_credits()
6501 if ($this->credits !== null)
6503 return $this->credits;
6511 function get_description()
6513 if ($this->description !== null)
6515 return $this->description;
6523 function get_duration($convert = false)
6525 if ($this->duration !== null)
6529 $time = SimplePie_Misc::time_hms($this->duration);
6534 return $this->duration;
6543 function get_expression()
6545 if ($this->expression !== null)
6547 return $this->expression;
6555 function get_extension()
6557 if ($this->link !== null)
6559 $url = SimplePie_Misc::parse_url($this->link);
6560 if ($url['path'] !== '')
6562 return pathinfo($url['path'], PATHINFO_EXTENSION);
6568 function get_framerate()
6570 if ($this->framerate !== null)
6572 return $this->framerate;
6580 function get_handler()
6582 return $this->get_real_type(true);
6585 function get_hash($key = 0)
6587 $hashes = $this->get_hashes();
6588 if (isset($hashes[$key]))
6590 return $hashes[$key];
6598 function get_hashes()
6600 if ($this->hashes !== null)
6602 return $this->hashes;
6610 function get_height()
6612 if ($this->height !== null)
6614 return $this->height;
6622 function get_language()
6624 if ($this->lang !== null)
6634 function get_keyword($key = 0)
6636 $keywords = $this->get_keywords();
6637 if (isset($keywords[$key]))
6639 return $keywords[$key];
6647 function get_keywords()
6649 if ($this->keywords !== null)
6651 return $this->keywords;
6659 function get_length()
6661 if ($this->length !== null)
6663 return $this->length;
6673 if ($this->link !== null)
6675 return urldecode($this->link);
6683 function get_medium()
6685 if ($this->medium !== null)
6687 return $this->medium;
6695 function get_player()
6697 if ($this->player !== null)
6699 return $this->player;
6707 function get_rating($key = 0)
6709 $ratings = $this->get_ratings();
6710 if (isset($ratings[$key]))
6712 return $ratings[$key];
6720 function get_ratings()
6722 if ($this->ratings !== null)
6724 return $this->ratings;
6732 function get_restriction($key = 0)
6734 $restrictions = $this->get_restrictions();
6735 if (isset($restrictions[$key]))
6737 return $restrictions[$key];
6745 function get_restrictions()
6747 if ($this->restrictions !== null)
6749 return $this->restrictions;
6757 function get_sampling_rate()
6759 if ($this->samplingrate !== null)
6761 return $this->samplingrate;
6771 $length = $this->get_length();
6772 if ($length !== null)
6774 return round($length/1048576, 2);
6782 function get_thumbnail($key = 0)
6784 $thumbnails = $this->get_thumbnails();
6785 if (isset($thumbnails[$key]))
6787 return $thumbnails[$key];
6795 function get_thumbnails()
6797 if ($this->thumbnails !== null)
6799 return $this->thumbnails;
6807 function get_title()
6809 if ($this->title !== null)
6811 return $this->title;
6821 if ($this->type !== null)
6831 function get_width()
6833 if ($this->width !== null)
6835 return $this->width;
6843 function native_embed($options='')
6845 return $this->embed($options, true);
6849 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6851 function embed($options = '', $native = false)
6861 $bgcolor = '#ffffff';
6863 $widescreen = false;
6864 $handler = $this->get_handler();
6865 $type = $this->get_real_type();
6867 // Process options and reassign values as necessary
6868 if (is_array($options))
6874 $options = explode(',', $options);
6875 foreach($options as $option)
6877 $opt = explode(':', $option, 2);
6878 if (isset($opt[0], $opt[1]))
6880 $opt[0] = trim($opt[0]);
6881 $opt[1] = trim($opt[1]);
6897 $altclass = $opt[1];
6917 $mediaplayer = $opt[1];
6921 $widescreen = $opt[1];
6928 $mime = explode('/', $type, 2);
6931 // Process values for 'auto'
6932 if ($width == 'auto')
6934 if ($mime == 'video')
6936 if ($height == 'auto')
6940 elseif ($widescreen)
6942 $width = round((intval($height)/9)*16);
6946 $width = round((intval($height)/3)*4);
6955 if ($height == 'auto')
6957 if ($mime == 'audio')
6961 elseif ($mime == 'video')
6963 if ($width == 'auto')
6974 elseif ($widescreen)
6976 $height = round((intval($width)/16)*9);
6980 $height = round((intval($width)/4)*3);
6988 elseif ($mime == 'audio')
6993 // Set proper placeholder value
6994 if ($mime == 'audio')
6996 $placeholder = $audio;
6998 elseif ($mime == 'video')
7000 $placeholder = $video;
7005 // Make sure the JS library is included
7008 static $javascript_outputted = null;
7009 if (!$javascript_outputted && $this->javascript)
7011 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7012 $javascript_outputted = true;
7017 if ($handler == 'odeo')
7021 $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>';
7025 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7030 elseif ($handler == 'flash')
7034 $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>";
7038 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7042 // Flash Media Player file types.
7043 // Preferred handler for MP3 file types.
7044 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
7049 $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>";
7053 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7057 // QuickTime 7 file types. Need to test with QuickTime 6.
7058 // Only handle MP3's if the Flash Media Player is not present.
7059 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
7064 if ($placeholder != ""){
7065 $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>";
7068 $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>";
7073 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7078 elseif ($handler == 'wmedia')
7083 $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>";
7087 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7092 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7097 function get_real_type($find_handler = false)
7099 // If it's Odeo, let's get it out of the way.
7100 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
7105 // Mime-types by handler.
7106 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7107 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
7108 $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
7109 $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
7110 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7112 if ($this->get_type() !== null)
7114 $type = strtolower($this->type);
7121 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7122 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7124 switch (strtolower($this->get_extension()))
7129 $type = 'audio/acc';
7136 $type = 'audio/aiff';
7140 $type = 'audio/wav';
7147 $type = 'audio/midi';
7151 $type = 'audio/x-m4a';
7156 $type = 'audio/mp3';
7160 $type = 'audio/wav';
7164 $type = 'audio/x-ms-wax';
7168 $type = 'audio/x-ms-wma';
7174 $type = 'video/3gpp';
7179 $type = 'video/3gpp2';
7183 $type = 'video/x-ms-asf';
7187 $type = 'video/x-flv';
7201 $type = 'video/mpeg';
7205 $type = 'video/x-m4v';
7210 $type = 'video/quicktime';
7215 $type = 'video/mp4';
7219 $type = 'video/sd-video';
7223 $type = 'video/x-ms-wm';
7227 $type = 'video/x-ms-wmv';
7231 $type = 'video/x-ms-wvx';
7236 $type = 'application/futuresplash';
7240 $type = 'application/x-shockwave-flash';
7247 if (in_array($type, $types_flash))
7251 elseif (in_array($type, $types_fmedia))
7255 elseif (in_array($type, $types_quicktime))
7259 elseif (in_array($type, $types_wmedia))
7263 elseif (in_array($type, $types_mp3))
7279 class SimplePie_Caption
7287 // Constructor, used to input the data
7288 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7290 $this->type = $type;
7291 $this->lang = $lang;
7292 $this->startTime = $startTime;
7293 $this->endTime = $endTime;
7294 $this->text = $text;
7297 function __toString()
7299 // There is no $this->data here
7300 return md5(serialize($this));
7303 function get_endtime()
7305 if ($this->endTime !== null)
7307 return $this->endTime;
7315 function get_language()
7317 if ($this->lang !== null)
7327 function get_starttime()
7329 if ($this->startTime !== null)
7331 return $this->startTime;
7341 if ($this->text !== null)
7353 if ($this->type !== null)
7364 class SimplePie_Credit
7370 // Constructor, used to input the data
7371 function SimplePie_Credit($role = null, $scheme = null, $name = null)
7373 $this->role = $role;
7374 $this->scheme = $scheme;
7375 $this->name = $name;
7378 function __toString()
7380 // There is no $this->data here
7381 return md5(serialize($this));
7386 if ($this->role !== null)
7396 function get_scheme()
7398 if ($this->scheme !== null)
7400 return $this->scheme;
7410 if ($this->name !== null)
7421 class SimplePie_Copyright
7426 // Constructor, used to input the data
7427 function SimplePie_Copyright($url = null, $label = null)
7430 $this->label = $label;
7433 function __toString()
7435 // There is no $this->data here
7436 return md5(serialize($this));
7441 if ($this->url !== null)
7451 function get_attribution()
7453 if ($this->label !== null)
7455 return $this->label;
7464 class SimplePie_Rating
7469 // Constructor, used to input the data
7470 function SimplePie_Rating($scheme = null, $value = null)
7472 $this->scheme = $scheme;
7473 $this->value = $value;
7476 function __toString()
7478 // There is no $this->data here
7479 return md5(serialize($this));
7482 function get_scheme()
7484 if ($this->scheme !== null)
7486 return $this->scheme;
7494 function get_value()
7496 if ($this->value !== null)
7498 return $this->value;
7507 class SimplePie_Restriction
7513 // Constructor, used to input the data
7514 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7516 $this->relationship = $relationship;
7517 $this->type = $type;
7518 $this->value = $value;
7521 function __toString()
7523 // There is no $this->data here
7524 return md5(serialize($this));
7527 function get_relationship()
7529 if ($this->relationship !== null)
7531 return $this->relationship;
7541 if ($this->type !== null)
7551 function get_value()
7553 if ($this->value !== null)
7555 return $this->value;
7565 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7567 class SimplePie_File
7571 var $success = true;
7572 var $headers = array();
7577 var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7579 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7581 if (class_exists('idna_convert'))
7583 $idn =& new idna_convert;
7584 $parsed = SimplePie_Misc::parse_url($url);
7585 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7588 $this->useragent = $useragent;
7589 if (preg_match('/^http(s)?:\/\//i', $url))
7591 if ($useragent === null)
7593 $useragent = ini_get('user_agent');
7594 $this->useragent = $useragent;
7596 if (!is_array($headers))
7600 if (!$force_fsockopen && function_exists('curl_exec'))
7602 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7604 $headers2 = array();
7605 foreach ($headers as $key => $value)
7607 $headers2[] = "$key: $value";
7609 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7611 curl_setopt($fp, CURLOPT_ENCODING, '');
7613 curl_setopt($fp, CURLOPT_URL, $url);
7614 curl_setopt($fp, CURLOPT_HEADER, 1);
7615 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7616 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7617 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7618 curl_setopt($fp, CURLOPT_REFERER, $url);
7619 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7620 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7621 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7623 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7624 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7627 /* Enable Digest authentication and SSL -fox */
7628 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
7629 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
7631 $this->headers = curl_exec($fp);
7632 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
7634 curl_setopt($fp, CURLOPT_ENCODING, 'none');
7635 $this->headers = curl_exec($fp);
7637 if (curl_errno($fp))
7639 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7640 $this->success = false;
7644 $info = curl_getinfo($fp);
7646 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7647 $this->headers = array_pop($this->headers);
7648 $parser =& new SimplePie_HTTP_Parser($this->headers);
7649 if ($parser->parse())
7651 $this->headers = $parser->headers;
7652 $this->body = $parser->body;
7653 $this->status_code = $parser->status_code;
7654 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)
7657 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7658 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7665 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7666 $url_parts = parse_url($url);
7667 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
7669 $url_parts['host'] = "ssl://$url_parts[host]";
7670 $url_parts['port'] = 443;
7672 if (!isset($url_parts['port']))
7674 $url_parts['port'] = 80;
7676 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7679 $this->error = 'fsockopen error: ' . $errstr;
7680 $this->success = false;
7684 stream_set_timeout($fp, $timeout);
7685 if (isset($url_parts['path']))
7687 if (isset($url_parts['query']))
7689 $get = "$url_parts[path]?$url_parts[query]";
7693 $get = $url_parts['path'];
7700 $out = "GET $get HTTP/1.0\r\n";
7701 $out .= "Host: $url_parts[host]\r\n";
7702 $out .= "User-Agent: $useragent\r\n";
7703 if (function_exists('gzinflate'))
7705 $out .= "Accept-Encoding: gzip,deflate\r\n";
7708 if (isset($url_parts['user']) && isset($url_parts['pass']))
7710 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7712 foreach ($headers as $key => $value)
7714 $out .= "$key: $value\r\n";
7716 $out .= "Connection: Close\r\n\r\n";
7719 $info = stream_get_meta_data($fp);
7721 $this->headers = '';
7722 while (!$info['eof'] && !$info['timed_out'])
7724 $this->headers .= fread($fp, 1160);
7725 $info = stream_get_meta_data($fp);
7727 if (!$info['timed_out'])
7729 $parser =& new SimplePie_HTTP_Parser($this->headers);
7730 if ($parser->parse())
7732 $this->headers = $parser->headers;
7733 $this->body = $parser->body;
7734 $this->status_code = $parser->status_code;
7735 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)
7738 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7739 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7741 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
7743 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
7745 $this->body = substr($this->body, 10);
7747 $this->body = gzinflate($this->body);
7753 $this->error = 'fsocket timed out';
7754 $this->success = false;
7762 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7763 if (!$this->body = file_get_contents($url))
7765 $this->error = 'file_get_contents could not read the file';
7766 $this->success = false;
7773 * HTTP Response Parser
7775 * @package SimplePie
7777 class SimplePie_HTTP_Parser
7785 var $http_version = 0.0;
7793 var $status_code = 0;
7804 * Key/value pairs of the headers
7809 var $headers = array();
7812 * Body of the response
7820 * Current state of the state machine
7825 var $state = 'http_version';
7836 * Input data length (to avoid calling strlen() everytime this is needed)
7841 var $data_length = 0;
7844 * Current position of the pointer
7852 * Name of the hedaer currently being parsed
7860 * Value of the hedaer currently being parsed
7868 * Create an instance of the class with the input data
7871 * @param string $data Input data
7873 function SimplePie_HTTP_Parser($data)
7875 $this->data = $data;
7876 $this->data_length = strlen($this->data);
7880 * Parse the input data
7883 * @return bool true on success, false on failure
7887 while ($this->state && $this->state !== 'emit' && $this->has_data())
7889 $state = $this->state;
7893 if ($this->state === 'emit' || $this->state === 'body')
7899 $this->http_version = '';
7900 $this->status_code = '';
7902 $this->headers = array();
7909 * Check whether there is data beyond the pointer
7912 * @return bool true if there is further data, false if not
7916 return (bool) ($this->position < $this->data_length);
7920 * See if the next character is LWS
7923 * @return bool true if the next character is LWS, false if not
7925 function is_linear_whitespace()
7927 return (bool) ($this->data[$this->position] === "\x09"
7928 || $this->data[$this->position] === "\x20"
7929 || ($this->data[$this->position] === "\x0A"
7930 && isset($this->data[$this->position + 1])
7931 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
7935 * Parse the HTTP version
7939 function http_version()
7941 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
7943 $len = strspn($this->data, '0123456789.', 5);
7944 $this->http_version = substr($this->data, 5, $len);
7945 $this->position += 5 + $len;
7946 if (substr_count($this->http_version, '.') <= 1)
7948 $this->http_version = (float) $this->http_version;
7949 $this->position += strspn($this->data, "\x09\x20", $this->position);
7950 $this->state = 'status';
7954 $this->state = false;
7959 $this->state = false;
7964 * Parse the status code
7970 if ($len = strspn($this->data, '0123456789', $this->position))
7972 $this->status_code = (int) substr($this->data, $this->position, $len);
7973 $this->position += $len;
7974 $this->state = 'reason';
7978 $this->state = false;
7983 * Parse the reason phrase
7989 $len = strcspn($this->data, "\x0A", $this->position);
7990 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
7991 $this->position += $len + 1;
7992 $this->state = 'new_line';
7996 * Deal with a new line, shifting data around as needed
8002 $this->value = trim($this->value, "\x0D\x20");
8003 if ($this->name !== '' && $this->value !== '')
8005 $this->name = strtolower($this->name);
8006 if (isset($this->headers[$this->name]))
8008 $this->headers[$this->name] .= ', ' . $this->value;
8012 $this->headers[$this->name] = $this->value;
8017 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8019 $this->position += 2;
8020 $this->state = 'body';
8022 elseif ($this->data[$this->position] === "\x0A")
8025 $this->state = 'body';
8029 $this->state = 'name';
8034 * Parse a header name
8040 $len = strcspn($this->data, "\x0A:", $this->position);
8041 if (isset($this->data[$this->position + $len]))
8043 if ($this->data[$this->position + $len] === "\x0A")
8045 $this->position += $len;
8046 $this->state = 'new_line';
8050 $this->name = substr($this->data, $this->position, $len);
8051 $this->position += $len + 1;
8052 $this->state = 'value';
8057 $this->state = false;
8062 * Parse LWS, replacing consecutive LWS characters with a single space
8066 function linear_whitespace()
8070 if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8072 $this->position += 2;
8074 elseif ($this->data[$this->position] === "\x0A")
8078 $this->position += strspn($this->data, "\x09\x20", $this->position);
8079 } while ($this->has_data() && $this->is_linear_whitespace());
8080 $this->value .= "\x20";
8084 * See what state to move to while within non-quoted header values
8090 if ($this->is_linear_whitespace())
8092 $this->linear_whitespace();
8096 switch ($this->data[$this->position])
8100 $this->state = 'quote';
8105 $this->state = 'new_line';
8109 $this->state = 'value_char';
8116 * Parse a header value while outside quotes
8120 function value_char()
8122 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8123 $this->value .= substr($this->data, $this->position, $len);
8124 $this->position += $len;
8125 $this->state = 'value';
8129 * See what state to move to while within quoted header values
8135 if ($this->is_linear_whitespace())
8137 $this->linear_whitespace();
8141 switch ($this->data[$this->position])
8145 $this->state = 'value';
8150 $this->state = 'new_line';
8155 $this->state = 'quote_escaped';
8159 $this->state = 'quote_char';
8166 * Parse a header value while within quotes
8170 function quote_char()
8172 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8173 $this->value .= substr($this->data, $this->position, $len);
8174 $this->position += $len;
8175 $this->state = 'value';
8179 * Parse an escaped character within quotes
8183 function quote_escaped()
8185 $this->value .= $this->data[$this->position];
8187 $this->state = 'quote';
8197 $this->body = substr($this->data, $this->position);
8198 $this->state = 'emit';
8202 class SimplePie_Cache
8205 * Don't call the constructor. Please.
8209 function SimplePie_Cache()
8211 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8215 * Create a new SimplePie_Cache object
8220 function create($location, $filename, $extension)
8222 return new SimplePie_Cache_File($location, $filename, $extension);
8226 class SimplePie_Cache_File
8233 function SimplePie_Cache_File($location, $filename, $extension)
8235 $this->location = $location;
8236 $this->filename = rawurlencode($filename);
8237 $this->extension = rawurlencode($extension);
8238 $this->name = "$location/$this->filename.$this->extension";
8241 function save($data)
8243 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8245 if (is_a($data, 'SimplePie'))
8247 $data = $data->data;
8250 $data = serialize($data);
8252 if (function_exists('file_put_contents'))
8254 return (bool) file_put_contents($this->name, $data);
8258 $fp = fopen($this->name, 'wb');
8272 if (file_exists($this->name) && is_readable($this->name))
8274 return unserialize(file_get_contents($this->name));
8281 if (file_exists($this->name))
8283 return filemtime($this->name);
8290 if (file_exists($this->name))
8292 return touch($this->name);
8299 if (file_exists($this->name))
8301 return unlink($this->name);
8307 class SimplePie_Misc
8309 function time_hms($seconds)
8313 $hours = floor($seconds / 3600);
8314 $remainder = $seconds % 3600;
8317 $time .= $hours.':';
8320 $minutes = floor($remainder / 60);
8321 $seconds = $remainder % 60;
8322 if ($minutes < 10 && $hours > 0)
8324 $minutes = '0' . $minutes;
8328 $seconds = '0' . $seconds;
8331 $time .= $minutes.':';
8337 function absolutize_url($relative, $base)
8339 if ($relative !== '')
8341 $relative = SimplePie_Misc::parse_url($relative);
8342 if ($relative['scheme'] !== '')
8344 $target = $relative;
8346 elseif ($base !== '')
8348 $base = SimplePie_Misc::parse_url($base);
8349 $target = SimplePie_Misc::parse_url('');
8350 if ($relative['authority'] !== '')
8352 $target = $relative;
8353 $target['scheme'] = $base['scheme'];
8357 $target['scheme'] = $base['scheme'];
8358 $target['authority'] = $base['authority'];
8359 if ($relative['path'] !== '')
8361 if (strpos($relative['path'], '/') === 0)
8363 $target['path'] = $relative['path'];
8365 elseif ($base['authority'] !== '' && $base['path'] === '')
8367 $target['path'] = '/' . $relative['path'];
8369 elseif (($last_segment = strrpos($base['path'], '/')) !== false)
8371 $target['path'] = substr($base['path'], 0, $last_segment + 1) . $relative['path'];
8375 $target['path'] = $relative['path'];
8377 $target['query'] = $relative['query'];
8381 $target['path'] = $base['path'];
8382 if ($relative['query'] !== '')
8384 $target['query'] = $relative['query'];
8386 elseif ($base['query'] !== '')
8388 $target['query'] = $base['query'];
8392 $target['fragment'] = $relative['fragment'];
8396 // No base URL, just return the relative URL
8397 $target = $relative;
8399 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
8405 $return = SimplePie_Misc::normalize_url($return);
8409 function remove_dot_segments($input)
8412 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
8414 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8415 if (strpos($input, '../') === 0)
8417 $input = substr($input, 3);
8419 elseif (strpos($input, './') === 0)
8421 $input = substr($input, 2);
8423 // 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,
8424 elseif (strpos($input, '/./') === 0)
8426 $input = substr_replace($input, '/', 0, 3);
8428 elseif ($input == '/.')
8432 // 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,
8433 elseif (strpos($input, '/../') === 0)
8435 $input = substr_replace($input, '/', 0, 4);
8436 $output = substr_replace($output, '', strrpos($output, '/'));
8438 elseif ($input == '/..')
8441 $output = substr_replace($output, '', strrpos($output, '/'));
8443 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8444 elseif ($input == '.' || $input == '..')
8448 // 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
8449 elseif (($pos = strpos($input, '/', 1)) !== false)
8451 $output .= substr($input, 0, $pos);
8452 $input = substr_replace($input, '', 0, $pos);
8460 return $output . $input;
8463 function get_element($realname, $string)
8466 $name = preg_quote($realname, '/');
8467 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
8469 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
8471 $return[$i]['tag'] = $realname;
8472 $return[$i]['full'] = $matches[$i][0][0];
8473 $return[$i]['offset'] = $matches[$i][0][1];
8474 if (strlen($matches[$i][3][0]) <= 2)
8476 $return[$i]['self_closing'] = true;
8480 $return[$i]['self_closing'] = false;
8481 $return[$i]['content'] = $matches[$i][4][0];
8483 $return[$i]['attribs'] = array();
8484 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))
8486 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
8488 if (count($attribs[$j]) == 2)
8490 $attribs[$j][2] = $attribs[$j][1];
8492 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
8500 function element_implode($element)
8502 $full = "<$element[tag]";
8503 foreach ($element['attribs'] as $key => $value)
8505 $key = strtolower($key);
8506 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8508 if ($element['self_closing'])
8514 $full .= ">$element[content]</$element[tag]>";
8519 function error($message, $level, $file, $line)
8524 $note = 'PHP Error';
8526 case E_USER_WARNING:
8527 $note = 'PHP Warning';
8530 $note = 'PHP Notice';
8533 $note = 'Unknown Error';
8536 error_log("$note: $message in $file on line $line", 0);
8541 * If a file has been cached, retrieve and display it.
8543 * This is most useful for caching images (get_favicon(), etc.),
8544 * however it works for all cached files. This WILL NOT display ANY
8545 * file/image/page/whatever, but rather only display what has already
8546 * been cached by SimplePie.
8549 * @see SimplePie::get_favicon()
8550 * @param str $identifier_url URL that is used to identify the content.
8551 * This may or may not be the actual URL of the live content.
8552 * @param str $cache_location Location of SimplePie's cache. Defaults
8554 * @param str $cache_extension The file extension that the file was
8555 * cached with. Defaults to 'spc'.
8556 * @param str $cache_class Name of the cache-handling class being used
8557 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
8558 * as-is unless you've overloaded the class.
8559 * @param str $cache_name_function Obsolete. Exists for backwards
8560 * compatibility reasons only.
8562 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
8564 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
8566 if ($file = $cache->load())
8568 if (isset($file['headers']['content-type']))
8570 header('Content-type:' . $file['headers']['content-type']);
8574 header('Content-type: application/octet-stream');
8576 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
8581 die('Cached file for ' . $identifier_url . ' cannot be found.');
8584 function fix_protocol($url, $http = 1)
8586 $url = SimplePie_Misc::normalize_url($url);
8587 $parsed = SimplePie_Misc::parse_url($url);
8588 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
8590 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8593 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8595 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8598 if ($http == 2 && $parsed['scheme'] !== '')
8602 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
8604 return substr_replace($url, 'podcast', 0, 4);
8606 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
8608 return substr_replace($url, 'itpc', 0, 4);
8616 function parse_url($url)
8618 static $cache = array();
8619 if (isset($cache[$url]))
8621 return $cache[$url];
8623 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
8625 for ($i = count($match); $i <= 9; $i++)
8629 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
8633 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
8637 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8642 $return .= "$scheme:";
8644 if ($authority !== '')
8646 $return .= "//$authority";
8654 $return .= "?$query";
8656 if ($fragment !== '')
8658 $return .= "#$fragment";
8663 function normalize_url($url)
8665 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
8666 $url = SimplePie_Misc::parse_url($url);
8667 $url['scheme'] = strtolower($url['scheme']);
8668 if ($url['authority'] !== '')
8670 $url['authority'] = strtolower($url['authority']);
8671 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
8673 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
8676 function percent_encoding_normalization($match)
8678 $integer = hexdec($match[1]);
8679 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
8681 return chr($integer);
8685 return strtoupper($match[0]);
8690 * Remove bad UTF-8 bytes
8692 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
8693 * FAQ: Multilingual Forms (modified to include full ASCII range)
8695 * @author Geoffrey Sneddon
8696 * @see http://www.w3.org/International/questions/qa-forms-utf-8
8697 * @param string $str String to remove bad UTF-8 bytes from
8698 * @return string UTF-8 string
8700 function utf8_bad_replace($str)
8702 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
8706 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
8710 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))
8712 return implode("\xEF\xBF\xBD", $matches[0]);
8714 elseif ($str !== '')
8716 return "\xEF\xBF\xBD";
8725 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8729 * @param string $string Windows-1252 encoded string
8730 * @return string UTF-8 encoded string
8732 function windows_1252_to_utf8($string)
8734 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");
8736 return strtr($string, $convert_table);
8739 function change_encoding($data, $input, $output)
8741 $input = SimplePie_Misc::encoding($input);
8742 $output = SimplePie_Misc::encoding($output);
8744 // We fail to fail on non US-ASCII bytes
8745 if ($input === 'US-ASCII')
8747 static $non_ascii_octects = '';
8748 if (!$non_ascii_octects)
8750 for ($i = 0x80; $i <= 0xFF; $i++)
8752 $non_ascii_octects .= chr($i);
8755 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8758 if (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
8762 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
8766 elseif ($input == 'windows-1252' && $output == 'UTF-8')
8768 return SimplePie_Misc::windows_1252_to_utf8($data);
8770 elseif ($input == 'UTF-8' && $output == 'windows-1252')
8772 return utf8_decode($data);
8777 function encoding($encoding)
8779 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
8780 switch (strtoupper($encoding))
8782 case 'ANSI_X3.110-1983':
8783 case 'CSA_T500-1983':
8784 case 'CSISO99NAPLPS':
8787 return 'ANSI_X3.110-1983';
8791 case 'CSISO89ASMO449':
8796 case 'ADOBE-STANDARD-ENCODING':
8797 case 'CSADOBESTANDARDENCODING':
8798 return 'Adobe-Standard-Encoding';
8800 case 'ADOBE-SYMBOL-ENCODING':
8802 return 'Adobe-Symbol-Encoding';
8808 return 'Amiga-1251';
8819 case 'CSISO4UNITEDKINGDOM':
8827 case 'CSISO47BSVIEWDATA':
8829 return 'BS_viewdata';
8836 return 'Big5-HKSCS';
8844 case 'CSA_Z243.4-1985-1':
8845 case 'CSISO121CANADIAN1':
8848 return 'CSA_Z243.4-1985-1';
8851 case 'CSA_Z243.4-1985-2':
8852 case 'CSISO122CANADIAN2':
8855 return 'CSA_Z243.4-1985-2';
8857 case 'CSA_Z243.4-1985-GR':
8858 case 'CSISO123CSAZ24341985GR':
8860 return 'CSA_Z243.4-1985-gr';
8862 case 'CSISO139CSN369103':
8865 return 'CSN_369103';
8872 case 'CSISO21GERMAN':
8879 case 'CSISO646DANISH':
8886 case 'CSIBMEBCDICATDE':
8887 case 'EBCDIC-AT-DE':
8888 return 'EBCDIC-AT-DE';
8890 case 'CSEBCDICATDEA':
8891 case 'EBCDIC-AT-DE-A':
8892 return 'EBCDIC-AT-DE-A';
8894 case 'CSEBCDICCAFR':
8895 case 'EBCDIC-CA-FR':
8896 return 'EBCDIC-CA-FR';
8898 case 'CSEBCDICDKNO':
8899 case 'EBCDIC-DK-NO':
8900 return 'EBCDIC-DK-NO';
8902 case 'CSEBCDICDKNOA':
8903 case 'EBCDIC-DK-NO-A':
8904 return 'EBCDIC-DK-NO-A';
8912 return 'EBCDIC-ES-A';
8916 return 'EBCDIC-ES-S';
8918 case 'CSEBCDICFISE':
8919 case 'EBCDIC-FI-SE':
8920 return 'EBCDIC-FI-SE';
8922 case 'CSEBCDICFISEA':
8923 case 'EBCDIC-FI-SE-A':
8924 return 'EBCDIC-FI-SE-A';
8946 case 'CSISO111ECMACYRILLIC':
8947 case 'ECMA-CYRILLIC':
8950 return 'ECMA-cyrillic';
8952 case 'CSISO17SPANISH':
8958 case 'CSISO85SPANISH2':
8964 case 'CSEUCPKDFMTJAPANESE':
8966 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
8973 case 'CSEUCFIXWIDJAPANESE':
8974 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
8975 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
8991 case 'CSISO57GB1988':
8995 return 'GB_1988-80';
8998 case 'CSISO58GB231280':
9001 return 'GB_2312-80';
9003 case 'CSISO153GOST1976874':
9004 case 'GOST_19768-74':
9006 case 'ST_SEV_358-88':
9007 return 'GOST_19768-74';
9011 return 'HP-DeskTop';
9023 return 'HP-Pi-font';
9026 return 'HZ-GB-2312';
9028 case 'CSIBMSYMBOLS':
9030 return 'IBM-Symbols';
9039 case 'PC-MULTILINGUAL-850+EURO':
9044 case 'EBCDIC-LATIN9--EURO':
9050 case 'EBCDIC-US-37+EURO':
9056 case 'EBCDIC-DE-273+EURO':
9062 case 'EBCDIC-DK-277+EURO':
9063 case 'EBCDIC-NO-277+EURO':
9069 case 'EBCDIC-FI-278+EURO':
9070 case 'EBCDIC-SE-278+EURO':
9076 case 'EBCDIC-IT-280+EURO':
9082 case 'EBCDIC-ES-284+EURO':
9088 case 'EBCDIC-GB-285+EURO':
9094 case 'EBCDIC-FR-297+EURO':
9100 case 'EBCDIC-INTERNATIONAL-500+EURO':
9106 case 'EBCDIC-IS-871+EURO':
9112 case 'EBCDIC-CP-CA':
9113 case 'EBCDIC-CP-NL':
9114 case 'EBCDIC-CP-US':
9115 case 'EBCDIC-CP-WT':
9152 case 'EBCDIC-CP-DK':
9153 case 'EBCDIC-CP-NO':
9159 case 'EBCDIC-CP-FI':
9160 case 'EBCDIC-CP-SE':
9166 case 'EBCDIC-CP-IT':
9178 case 'EBCDIC-CP-ES':
9184 case 'EBCDIC-CP-GB':
9190 case 'EBCDIC-JP-KANA':
9196 case 'EBCDIC-CP-FR':
9202 case 'EBCDIC-CP-AR1':
9208 case 'EBCDIC-CP-GR':
9214 case 'EBCDIC-CP-HE':
9220 case 'CSPC8CODEPAGE437':
9226 case 'EBCDIC-CP-BE':
9227 case 'EBCDIC-CP-CH':
9232 case 'CSPC775BALTIC':
9238 case 'CSPC850MULTILINGUAL':
9281 case 'CSPC862LATINHEBREW':
9323 case 'EBCDIC-CP-ROECE':
9324 case 'EBCDIC-CP-YU':
9330 case 'EBCDIC-CP-IS':
9336 case 'EBCDIC-CYRILLIC':
9358 case 'EBCDIC-CP-TR':
9364 case 'EBCDIC-CP-AR2':
9368 case 'CSISO143IECP271':
9378 case 'CSISO50INIS8':
9383 case 'CSISO51INISCYRILLIC':
9384 case 'INIS-CYRILLIC':
9386 return 'INIS-cyrillic';
9392 case 'ISO-10646-J-1':
9393 return 'ISO-10646-J-1';
9396 case 'ISO-10646-UCS-2':
9397 return 'ISO-10646-UCS-2';
9400 case 'ISO-10646-UCS-4':
9401 return 'ISO-10646-UCS-4';
9403 case 'CSUNICODEASCII':
9404 case 'ISO-10646-UCS-BASIC':
9405 return 'ISO-10646-UCS-Basic';
9407 case 'CSISO10646UTF1':
9408 case 'ISO-10646-UTF-1':
9409 return 'ISO-10646-UTF-1';
9411 case 'CSUNICODELATIN1':
9413 case 'ISO-10646-UNICODE-LATIN1':
9414 return 'ISO-10646-Unicode-Latin1';
9419 case 'ISO_TR_11548-1':
9420 return 'ISO-11548-1';
9423 return 'ISO-2022-CN';
9425 case 'ISO-2022-CN-EXT':
9426 return 'ISO-2022-CN-EXT';
9430 return 'ISO-2022-JP';
9432 case 'CSISO2022JP2':
9433 case 'ISO-2022-JP-2':
9434 return 'ISO-2022-JP-2';
9438 return 'ISO-2022-KR';
9440 case 'CSWINDOWS30LATIN1':
9441 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
9442 return 'ISO-8859-1-Windows-3.0-Latin-1';
9444 case 'CSWINDOWS31LATIN1':
9445 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
9446 return 'ISO-8859-1-Windows-3.1-Latin-1';
9451 case 'ISO_8859-10:1992':
9454 return 'ISO-8859-10';
9457 return 'ISO-8859-13';
9463 case 'ISO_8859-14:1998':
9466 return 'ISO-8859-14';
9471 return 'ISO-8859-15';
9476 case 'ISO_8859-16:2001':
9479 return 'ISO-8859-16';
9485 case 'ISO_8859-2:1987':
9488 return 'ISO-8859-2';
9490 case 'CSWINDOWS31LATIN2':
9491 case 'ISO-8859-2-WINDOWS-LATIN-2':
9492 return 'ISO-8859-2-Windows-Latin-2';
9498 case 'ISO_8859-3:1988':
9501 return 'ISO-8859-3';
9507 case 'ISO_8859-4:1988':
9510 return 'ISO-8859-4';
9512 case 'CSISOLATINCYRILLIC':
9517 case 'ISO_8859-5:1988':
9518 return 'ISO-8859-5';
9522 case 'CSISOLATINARABIC':
9527 case 'ISO_8859-6:1987':
9528 return 'ISO-8859-6';
9531 case 'ISO-8859-6-E':
9532 case 'ISO_8859-6-E':
9533 return 'ISO-8859-6-E';
9536 case 'ISO-8859-6-I':
9537 case 'ISO_8859-6-I':
9538 return 'ISO-8859-6-I';
9540 case 'CSISOLATINGREEK':
9548 case 'ISO_8859-7:1987':
9549 return 'ISO-8859-7';
9551 case 'CSISOLATINHEBREW':
9556 case 'ISO_8859-8:1988':
9557 return 'ISO-8859-8';
9560 case 'ISO-8859-8-E':
9561 case 'ISO_8859-8-E':
9562 return 'ISO-8859-8-E';
9565 case 'ISO-8859-8-I':
9566 case 'ISO_8859-8-I':
9567 return 'ISO-8859-8-I';
9573 case 'ISO_8859-9:1989':
9576 return 'ISO-8859-9';
9578 case 'CSWINDOWS31LATIN5':
9579 case 'ISO-8859-9-WINDOWS-LATIN-5':
9580 return 'ISO-8859-9-Windows-Latin-5';
9582 case 'CSUNICODEIBM1261':
9583 case 'ISO-UNICODE-IBM-1261':
9584 return 'ISO-Unicode-IBM-1261';
9586 case 'CSUNICODEIBM1264':
9587 case 'ISO-UNICODE-IBM-1264':
9588 return 'ISO-Unicode-IBM-1264';
9590 case 'CSUNICODEIBM1265':
9591 case 'ISO-UNICODE-IBM-1265':
9592 return 'ISO-Unicode-IBM-1265';
9594 case 'CSUNICODEIBM1268':
9595 case 'ISO-UNICODE-IBM-1268':
9596 return 'ISO-Unicode-IBM-1268';
9598 case 'CSUNICODEIBM1276':
9599 case 'ISO-UNICODE-IBM-1276':
9600 return 'ISO-Unicode-IBM-1276';
9602 case 'CSISO10367BOX':
9604 case 'ISO_10367-BOX':
9605 return 'ISO_10367-box';
9610 case 'ISO_2033-1983':
9611 return 'ISO_2033-1983';
9613 case 'CSISO5427CYRILLIC':
9619 case 'ISO5427CYRILLIC1981':
9620 case 'ISO_5427:1981':
9621 return 'ISO_5427:1981';
9623 case 'CSISO5428GREEK':
9625 case 'ISO_5428:1980':
9626 return 'ISO_5428:1980';
9628 case 'CSISO646BASIC1983':
9629 case 'ISO_646.BASIC:1983':
9631 return 'ISO_646.basic:1983';
9633 case 'CSISO2INTLREFVERSION':
9636 case 'ISO_646.IRV:1983':
9637 return 'ISO_646.irv:1983';
9639 case 'CSISO6937ADD':
9641 case 'ISO_6937-2-25':
9642 return 'ISO_6937-2-25';
9644 case 'CSISOTEXTCOMM':
9646 case 'ISO_6937-2-ADD':
9647 return 'ISO_6937-2-add';
9649 case 'CSISO8859SUPP':
9651 case 'ISO_8859-SUPP':
9653 return 'ISO_8859-supp';
9655 case 'CSISO15ITALIAN':
9661 case 'CSISO13JISC6220JP':
9663 case 'JIS_C6220-1969':
9664 case 'JIS_C6220-1969-JP':
9667 return 'JIS_C6220-1969-jp';
9669 case 'CSISO14JISC6220RO':
9672 case 'JIS_C6220-1969-RO':
9674 return 'JIS_C6220-1969-ro';
9676 case 'CSISO42JISC62261978':
9678 case 'JIS_C6226-1978':
9679 return 'JIS_C6226-1978';
9681 case 'CSISO87JISX0208':
9683 case 'JIS_C6226-1983':
9684 case 'JIS_X0208-1983':
9686 return 'JIS_C6226-1983';
9688 case 'CSISO91JISC62291984A':
9690 case 'JIS_C6229-1984-A':
9692 return 'JIS_C6229-1984-a';
9694 case 'CSISO92JISC62991984B':
9696 case 'ISO646-JP-OCR-B':
9697 case 'JIS_C6229-1984-B':
9699 return 'JIS_C6229-1984-b';
9701 case 'CSISO93JIS62291984BADD':
9703 case 'JIS_C6229-1984-B-ADD':
9704 case 'JP-OCR-B-ADD':
9705 return 'JIS_C6229-1984-b-add';
9707 case 'CSISO94JIS62291984HAND':
9709 case 'JIS_C6229-1984-HAND':
9711 return 'JIS_C6229-1984-hand';
9713 case 'CSISO95JIS62291984HANDADD':
9715 case 'JIS_C6229-1984-HAND-ADD':
9716 case 'JP-OCR-HAND-ADD':
9717 return 'JIS_C6229-1984-hand-add';
9719 case 'CSISO96JISC62291984KANA':
9721 case 'JIS_C6229-1984-KANA':
9722 return 'JIS_C6229-1984-kana';
9724 case 'CSJISENCODING':
9725 case 'JIS_ENCODING':
9726 return 'JIS_Encoding';
9728 case 'CSHALFWIDTHKATAKANA':
9733 case 'CSISO159JISX02121990':
9735 case 'JIS_X0212-1990':
9737 return 'JIS_X0212-1990';
9739 case 'CSISO141JUSIB1002':
9743 case 'JUS_I.B1.002':
9745 return 'JUS_I.B1.002';
9747 case 'CSISO147MACEDONIAN':
9749 case 'JUS_I.B1.003-MAC':
9751 return 'JUS_I.B1.003-mac';
9753 case 'CSISO146SERBIAN':
9755 case 'JUS_I.B1.003-SERB':
9757 return 'JUS_I.B1.003-serb';
9759 case 'KOI7-SWITCHED':
9760 return 'KOI7-switched';
9774 case 'CSKSC56011987':
9778 case 'KS_C_5601-1987':
9779 case 'KS_C_5601-1989':
9780 return 'KS_C_5601-1987';
9785 case 'STRK1048-2002':
9788 case 'CSISO27LATINGREEK1':
9790 case 'LATIN-GREEK-1':
9791 return 'Latin-greek-1';
9801 case 'CSISO86HUNGARIAN':
9806 return 'MSZ_7795.3';
9808 case 'CSMICROSOFTPUBLISHING':
9809 case 'MICROSOFT-PUBLISHING':
9810 return 'Microsoft-Publishing';
9817 case 'CSNATSDANOADD':
9819 case 'NATS-DANO-ADD':
9820 return 'NATS-DANO-ADD';
9827 case 'CSNATSSEFIADD':
9829 case 'NATS-SEFI-ADD':
9830 return 'NATS-SEFI-ADD';
9832 case 'CSISO151CUBA':
9836 case 'NC_NC00-10:81':
9837 return 'NC_NC00-10:81';
9839 case 'CSISO69FRENCH':
9844 return 'NF_Z_62-010';
9846 case 'CSISO25FRENCH':
9849 case 'NF_Z_62-010_(1973)':
9850 return 'NF_Z_62-010_(1973)';
9852 case 'CSISO60DANISHNORWEGIAN':
9853 case 'CSISO60NORWEGIAN1':
9860 case 'CSISO61NORWEGIAN2':
9867 case 'OSD_EBCDIC_DF03_IRV':
9868 return 'OSD_EBCDIC_DF03_IRV';
9870 case 'OSD_EBCDIC_DF04_1':
9871 return 'OSD_EBCDIC_DF04_1';
9873 case 'OSD_EBCDIC_DF04_15':
9874 return 'OSD_EBCDIC_DF04_15';
9876 case 'CSPC8DANISHNORWEGIAN':
9877 case 'PC8-DANISH-NORWEGIAN':
9878 return 'PC8-Danish-Norwegian';
9880 case 'CSPC8TURKISH':
9882 return 'PC8-Turkish';
9884 case 'CSISO16PORTUGUESE':
9890 case 'CSISO84PORTUGUESE2':
9898 case 'CYRILLIC-ASIAN':
9906 case 'CSISO10SWEDISH':
9912 case 'SEN_850200_B':
9913 return 'SEN_850200_B';
9915 case 'CSISO11SWEDISHFORNAMES':
9919 case 'SEN_850200_C':
9920 return 'SEN_850200_C';
9927 case 'CSISO128T101G2':
9932 case 'CSISO102T617BIT':
9937 case 'CSISO103T618BIT':
9949 return 'UNICODE-1-1';
9951 case 'CSUNICODE11UTF7':
9952 case 'UNICODE-1-1-UTF-7':
9953 return 'UNICODE-1-1-UTF-7';
9955 case 'CSUNKNOWN8BIT':
9956 case 'UNKNOWN-8BIT':
9957 return 'UNKNOWN-8BIT';
9960 case 'ANSI_X3.4-1968':
9961 case 'ANSI_X3.4-1986':
9968 case 'ISO_646.IRV:1991':
10005 case 'CSVENTURAINTERNATIONAL':
10006 case 'VENTURA-INTERNATIONAL':
10007 return 'Ventura-International';
10009 case 'CSVENTURAMATH':
10010 case 'VENTURA-MATH':
10011 return 'Ventura-Math';
10013 case 'CSVENTURAUS':
10015 return 'Ventura-US';
10017 case 'CSWINDOWS31J':
10018 case 'WINDOWS-31J':
10019 return 'Windows-31J';
10026 case 'CSISO150GREEKCCITT':
10027 case 'GREEK-CCITT':
10029 return 'greek-ccitt';
10031 case 'CSISO88GREEK7':
10036 case 'CSISO18GREEK7OLD':
10039 return 'greek7-old';
10045 return 'hp-roman8';
10049 return 'iso-ir-90';
10051 case 'CSISO19LATINGREEK':
10053 case 'LATIN-GREEK':
10054 return 'latin-greek';
10056 case 'CSISO158LAP':
10060 return 'latin-lap';
10062 case 'CSMACINTOSH':
10065 return 'macintosh';
10071 case 'CSISO70VIDEOTEXSUPP1':
10073 case 'VIDEOTEX-SUPPL':
10074 return 'videotex-suppl';
10076 case 'WINDOWS-1250':
10077 return 'windows-1250';
10079 case 'WINDOWS-1251':
10080 return 'windows-1251';
10083 case 'CSISOLATIN1':
10088 case 'ISO_8859-1:1987':
10091 case 'WINDOWS-1252':
10092 return 'windows-1252';
10094 case 'WINDOWS-1253':
10095 return 'windows-1253';
10097 case 'WINDOWS-1254':
10098 return 'windows-1254';
10100 case 'WINDOWS-1255':
10101 return 'windows-1255';
10103 case 'WINDOWS-1256':
10104 return 'windows-1256';
10106 case 'WINDOWS-1257':
10107 return 'windows-1257';
10109 case 'WINDOWS-1258':
10110 return 'windows-1258';
10117 function get_curl_version()
10119 if (is_array($curl = curl_version()))
10121 $curl = $curl['version'];
10123 elseif (substr($curl, 0, 5) == 'curl/')
10125 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10127 elseif (substr($curl, 0, 8) == 'libcurl/')
10129 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10138 function is_subclass_of($class1, $class2)
10140 if (func_num_args() != 2)
10142 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10144 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10146 return is_subclass_of($class1, $class2);
10148 elseif (is_string($class1) && is_string($class2))
10150 if (class_exists($class1))
10152 if (class_exists($class2))
10154 $class2 = strtolower($class2);
10155 while ($class1 = strtolower(get_parent_class($class1)))
10157 if ($class1 == $class2)
10166 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10173 * Strip HTML comments
10176 * @param string $data Data to strip comments from
10177 * @return string Comment stripped string
10179 function strip_comments($data)
10182 while (($start = strpos($data, '<!--')) !== false)
10184 $output .= substr($data, 0, $start);
10185 if (($end = strpos($data, '-->', $start)) !== false)
10187 $data = substr_replace($data, '', 0, $end + 3);
10194 return $output . $data;
10197 function parse_date($dt)
10199 $parser = SimplePie_Parse_Date::get();
10200 return $parser->parse($dt);
10204 * Decode HTML entities
10208 * @param string $data Input data
10209 * @return string Output data
10211 function entities_decode($data)
10213 $decoder = new SimplePie_Decode_HTML_Entities($data);
10214 return $decoder->parse();
10218 * Remove RFC822 comments
10221 * @param string $data Data to strip comments from
10222 * @return string Comment stripped string
10224 function uncomment_rfc822($string)
10226 $string = (string) $string;
10228 $length = strlen($string);
10233 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10235 $output .= substr($string, $position, $pos - $position);
10236 $position = $pos + 1;
10237 if ($string[$pos - 1] !== '\\')
10240 while ($depth && $position < $length)
10242 $position += strcspn($string, '()', $position);
10243 if ($string[$position - 1] === '\\')
10248 elseif (isset($string[$position]))
10250 switch ($string[$position])
10273 $output .= substr($string, $position);
10278 function parse_mime($mime)
10280 if (($pos = strpos($mime, ';')) === false)
10282 return trim($mime);
10286 return trim(substr($mime, 0, $pos));
10290 function htmlspecialchars_decode($string, $quote_style)
10292 if (function_exists('htmlspecialchars_decode'))
10294 return htmlspecialchars_decode($string, $quote_style);
10298 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
10302 function atom_03_construct_type($attribs)
10304 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
10306 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
10310 $mode = SIMPLEPIE_CONSTRUCT_NONE;
10312 if (isset($attribs['']['type']))
10314 switch (strtolower(trim($attribs['']['type'])))
10318 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10322 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
10325 case 'application/xhtml+xml':
10326 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
10329 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
10334 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
10338 function atom_10_construct_type($attribs)
10340 if (isset($attribs['']['type']))
10342 switch (strtolower(trim($attribs['']['type'])))
10345 return SIMPLEPIE_CONSTRUCT_TEXT;
10348 return SIMPLEPIE_CONSTRUCT_HTML;
10351 return SIMPLEPIE_CONSTRUCT_XHTML;
10354 return SIMPLEPIE_CONSTRUCT_NONE;
10357 return SIMPLEPIE_CONSTRUCT_TEXT;
10360 function atom_10_content_construct_type($attribs)
10362 if (isset($attribs['']['type']))
10364 $type = strtolower(trim($attribs['']['type']));
10368 return SIMPLEPIE_CONSTRUCT_TEXT;
10371 return SIMPLEPIE_CONSTRUCT_HTML;
10374 return SIMPLEPIE_CONSTRUCT_XHTML;
10376 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
10378 return SIMPLEPIE_CONSTRUCT_NONE;
10382 return SIMPLEPIE_CONSTRUCT_BASE64;
10387 return SIMPLEPIE_CONSTRUCT_TEXT;
10391 function is_isegment_nz_nc($string)
10393 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);
10396 function space_seperated_tokens($string)
10398 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10399 $string_length = strlen($string);
10401 $position = strspn($string, $space_characters);
10404 while ($position < $string_length)
10406 $len = strcspn($string, $space_characters, $position);
10407 $tokens[] = substr($string, $position, $len);
10409 $position += strspn($string, $space_characters, $position);
10415 function array_unique($array)
10417 if (version_compare(PHP_VERSION, '5.2', '>='))
10419 return array_unique($array);
10423 $array = (array) $array;
10424 $new_array = array();
10425 $new_array_strings = array();
10426 foreach ($array as $key => $value)
10428 if (is_object($value))
10430 if (method_exists($value, '__toString'))
10432 $cmp = $value->__toString();
10436 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
10439 elseif (is_array($value))
10441 $cmp = (string) reset($value);
10445 $cmp = (string) $value;
10447 if (!in_array($cmp, $new_array_strings))
10449 $new_array[$key] = $value;
10450 $new_array_strings[] = $cmp;
10458 * Converts a unicode codepoint to a UTF-8 character
10462 * @param int $codepoint Unicode codepoint
10463 * @return string UTF-8 character
10465 function codepoint_to_utf8($codepoint)
10467 static $cache = array();
10468 $codepoint = (int) $codepoint;
10469 if (isset($cache[$codepoint]))
10471 return $cache[$codepoint];
10473 elseif ($codepoint < 0)
10475 return $cache[$codepoint] = false;
10477 else if ($codepoint <= 0x7f)
10479 return $cache[$codepoint] = chr($codepoint);
10481 else if ($codepoint <= 0x7ff)
10483 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
10485 else if ($codepoint <= 0xffff)
10487 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10489 else if ($codepoint <= 0x10ffff)
10491 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
10495 // U+FFFD REPLACEMENT CHARACTER
10496 return $cache[$codepoint] = "\xEF\xBF\xBD";
10501 * Re-implementation of PHP 5's stripos()
10503 * Returns the numeric position of the first occurrence of needle in the
10508 * @param object $haystack
10509 * @param string $needle Note that the needle may be a string of one or more
10510 * characters. If needle is not a string, it is converted to an integer
10511 * and applied as the ordinal value of a character.
10512 * @param int $offset The optional offset parameter allows you to specify which
10513 * character in haystack to start searching. The position returned is still
10514 * relative to the beginning of haystack.
10515 * @return bool If needle is not found, stripos() will return boolean false.
10517 function stripos($haystack, $needle, $offset = 0)
10519 if (function_exists('stripos'))
10521 return stripos($haystack, $needle, $offset);
10525 if (is_string($needle))
10527 $needle = strtolower($needle);
10529 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
10531 $needle = strtolower(chr($needle));
10535 trigger_error('needle is not a string or an integer', E_USER_WARNING);
10539 return strpos(strtolower($haystack), $needle, $offset);
10544 * Similar to parse_str()
10546 * Returns an associative array of name/value pairs, where the value is an
10547 * array of values that have used the same name
10551 * @param string $str The input string.
10554 function parse_str($str)
10557 $str = explode('&', $str);
10559 foreach ($str as $section)
10561 if (strpos($section, '=') !== false)
10563 list($name, $value) = explode('=', $section, 2);
10564 $return[urldecode($name)][] = urldecode($value);
10568 $return[urldecode($section)][] = null;
10576 * Detect XML encoding, as per XML 1.0 Appendix F.1
10578 * @todo Add support for EBCDIC
10579 * @param string $data XML data
10580 * @return array Possible encodings
10582 function xml_encoding($data)
10584 // UTF-32 Big Endian BOM
10585 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10587 $encoding[] = 'UTF-32BE';
10589 // UTF-32 Little Endian BOM
10590 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10592 $encoding[] = 'UTF-32LE';
10594 // UTF-16 Big Endian BOM
10595 elseif (substr($data, 0, 2) === "\xFE\xFF")
10597 $encoding[] = 'UTF-16BE';
10599 // UTF-16 Little Endian BOM
10600 elseif (substr($data, 0, 2) === "\xFF\xFE")
10602 $encoding[] = 'UTF-16LE';
10605 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10607 $encoding[] = 'UTF-8';
10609 // UTF-32 Big Endian Without BOM
10610 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")
10612 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10614 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10615 if ($parser->parse())
10617 $encoding[] = $parser->encoding;
10620 $encoding[] = 'UTF-32BE';
10622 // UTF-32 Little Endian Without BOM
10623 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")
10625 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10627 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10628 if ($parser->parse())
10630 $encoding[] = $parser->encoding;
10633 $encoding[] = 'UTF-32LE';
10635 // UTF-16 Big Endian Without BOM
10636 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10638 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10640 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10641 if ($parser->parse())
10643 $encoding[] = $parser->encoding;
10646 $encoding[] = 'UTF-16BE';
10648 // UTF-16 Little Endian Without BOM
10649 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10651 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10653 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10654 if ($parser->parse())
10656 $encoding[] = $parser->encoding;
10659 $encoding[] = 'UTF-16LE';
10661 // US-ASCII (or superset)
10662 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10664 if ($pos = strpos($data, "\x3F\x3E"))
10666 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10667 if ($parser->parse())
10669 $encoding[] = $parser->encoding;
10672 $encoding[] = 'UTF-8';
10674 // Fallback to UTF-8
10677 $encoding[] = 'UTF-8';
10684 * Decode HTML Entities
10686 * This implements HTML5 as of revision 967 (2007-06-28)
10688 * @package SimplePie
10690 class SimplePie_Decode_HTML_Entities
10693 * Data to be parsed
10701 * Currently consumed bytes
10706 var $consumed = '';
10709 * Position of the current byte being parsed
10717 * Create an instance of the class with the input data
10720 * @param string $data Input data
10722 function SimplePie_Decode_HTML_Entities($data)
10724 $this->data = $data;
10728 * Parse the input data
10731 * @return string Output data
10735 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
10739 $this->consumed = '';
10741 return $this->data;
10745 * Consume the next byte
10748 * @return mixed The next byte, or false, if there is no more data
10752 if (isset($this->data[$this->position]))
10754 $this->consumed .= $this->data[$this->position];
10755 return $this->data[$this->position++];
10759 $this->consumed = false;
10765 * Consume a range of characters
10768 * @param string $chars Characters to consume
10769 * @return mixed A series of characters that match the range, or false
10771 function consume_range($chars)
10773 if ($len = strspn($this->data, $chars, $this->position))
10775 $data = substr($this->data, $this->position, $len);
10776 $this->consumed .= $data;
10777 $this->position += $len;
10782 $this->consumed = false;
10788 * Unconsume one byte
10792 function unconsume()
10794 $this->consumed = substr($this->consumed, 0, -1);
10805 switch ($this->consume())
10819 switch ($this->consume())
10823 $range = '0123456789ABCDEFabcdef';
10828 $range = '0123456789';
10830 $this->unconsume();
10834 if ($codepoint = $this->consume_range($range))
10836 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");
10840 $codepoint = hexdec($codepoint);
10844 $codepoint = intval($codepoint);
10847 if (isset($windows_1252_specials[$codepoint]))
10849 $replacement = $windows_1252_specials[$codepoint];
10853 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
10856 if ($this->consume() != ';')
10858 $this->unconsume();
10861 $consumed_length = strlen($this->consumed);
10862 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
10863 $this->position += strlen($replacement) - $consumed_length;
10868 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");
10870 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
10872 $consumed = substr($this->consumed, 1);
10873 if (isset($entities[$consumed]))
10875 $match = $consumed;
10879 if ($match !== null)
10881 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
10882 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
10892 * @package SimplePie
10894 class SimplePie_Parse_Date
10899 * @access protected
10905 * List of days, calendar day name => ordinal day number in the week
10907 * @access protected
10970 'keskiviikko' => 3,
10994 * List of months, calendar month name => calendar month number
10996 * @access protected
10999 var $month = array(
11010 // No long form of May
11139 * List of timezones, abbreviation => offset from UTC
11141 * @access protected
11144 var $timezone = array(
11347 * Cached PCRE for SimplePie_Parse_Date::$day
11349 * @access protected
11355 * Cached PCRE for SimplePie_Parse_Date::$month
11357 * @access protected
11363 * Array of user-added callback methods
11368 var $built_in = array();
11371 * Array of user-added callback methods
11376 var $user = array();
11379 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
11380 * self::month_pcre, and self::built_in
11384 function SimplePie_Parse_Date()
11386 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
11387 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
11390 if (!isset($cache[get_class($this)]))
11392 if (extension_loaded('Reflection'))
11394 $class = new ReflectionClass(get_class($this));
11395 $methods = $class->getMethods();
11396 $all_methods = array();
11397 foreach ($methods as $method)
11399 $all_methods[] = $method->getName();
11404 $all_methods = get_class_methods($this);
11407 foreach ($all_methods as $method)
11409 if (strtolower(substr($method, 0, 5)) === 'date_')
11411 $cache[get_class($this)][] = $method;
11416 foreach ($cache[get_class($this)] as $method)
11418 $this->built_in[] = $method;
11432 $object = new SimplePie_Parse_Date;
11442 * @param string $date Date to parse
11443 * @return int Timestamp corresponding to date string, or false on failure
11445 function parse($date)
11447 foreach ($this->user as $method)
11449 if (($returned = call_user_func($method, $date)) !== false)
11455 foreach ($this->built_in as $method)
11457 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
11467 * Add a callback method to parse a date
11471 * @param callback $callback
11473 function add_callback($callback)
11475 if (is_callable($callback))
11477 $this->user[] = $callback;
11481 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
11486 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
11487 * well as allowing any of upper or lower case "T", horizontal tabs, or
11488 * spaces to be used as the time seperator (including more than one))
11490 * @access protected
11491 * @return int Timestamp
11493 function date_w3cdtf($date)
11498 $year = '([0-9]{4})';
11499 $month = $day = $hour = $minute = $second = '([0-9]{2})';
11500 $decimal = '([0-9]*)';
11501 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
11502 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
11504 if (preg_match($pcre, $date, $match))
11507 Capturing subpatterns:
11514 7: Decimal fraction of a second
11518 11: Timezone minutes
11521 // Fill in empty matches
11522 for ($i = count($match); $i <= 3; $i++)
11527 for ($i = count($match); $i <= 7; $i++)
11532 // Numeric timezone
11533 if (isset($match[9]) && $match[9] !== '')
11535 $timezone = $match[10] * 3600;
11536 $timezone += $match[11] * 60;
11537 if ($match[9] === '-')
11539 $timezone = 0 - $timezone;
11547 // Convert the number of seconds to an integer, taking decimals into account
11548 $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
11550 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
11559 * Remove RFC822 comments
11561 * @access protected
11562 * @param string $data Data to strip comments from
11563 * @return string Comment stripped string
11565 function remove_rfc2822_comments($string)
11567 $string = (string) $string;
11569 $length = strlen($string);
11574 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
11576 $output .= substr($string, $position, $pos - $position);
11577 $position = $pos + 1;
11578 if ($string[$pos - 1] !== '\\')
11581 while ($depth && $position < $length)
11583 $position += strcspn($string, '()', $position);
11584 if ($string[$position - 1] === '\\')
11589 elseif (isset($string[$position]))
11591 switch ($string[$position])
11614 $output .= substr($string, $position);
11620 * Parse RFC2822's date format
11622 * @access protected
11623 * @return int Timestamp
11625 function date_rfc2822($date)
11630 $wsp = '[\x09\x20]';
11631 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
11632 $optional_fws = $fws . '?';
11633 $day_name = $this->day_pcre;
11634 $month = $this->month_pcre;
11635 $day = '([0-9]{1,2})';
11636 $hour = $minute = $second = '([0-9]{2})';
11637 $year = '([0-9]{2,4})';
11638 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
11639 $character_zone = '([A-Z]{1,5})';
11640 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
11641 $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';
11643 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
11646 Capturing subpatterns:
11656 10: Timezone minutes
11657 11: Alphabetic timezone
11660 // Find the month number
11661 $month = $this->month[strtolower($match[3])];
11663 // Numeric timezone
11664 if ($match[8] !== '')
11666 $timezone = $match[9] * 3600;
11667 $timezone += $match[10] * 60;
11668 if ($match[8] === '-')
11670 $timezone = 0 - $timezone;
11673 // Character timezone
11674 elseif (isset($this->timezone[strtoupper($match[11])]))
11676 $timezone = $this->timezone[strtoupper($match[11])];
11678 // Assume everything else to be -0000
11684 // Deal with 2/3 digit years
11685 if ($match[4] < 50)
11689 elseif ($match[4] < 1000)
11694 // Second is optional, if it is empty set it to zero
11695 if ($match[7] !== '')
11697 $second = $match[7];
11704 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
11713 * Parse RFC850's date format
11715 * @access protected
11716 * @return int Timestamp
11718 function date_rfc850($date)
11723 $space = '[\x09\x20]+';
11724 $day_name = $this->day_pcre;
11725 $month = $this->month_pcre;
11726 $day = '([0-9]{1,2})';
11727 $year = $hour = $minute = $second = '([0-9]{2})';
11728 $zone = '([A-Z]{1,5})';
11729 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
11731 if (preg_match($pcre, $date, $match))
11734 Capturing subpatterns:
11746 $month = $this->month[strtolower($match[3])];
11748 // Character timezone
11749 if (isset($this->timezone[strtoupper($match[8])]))
11751 $timezone = $this->timezone[strtoupper($match[8])];
11753 // Assume everything else to be -0000
11759 // Deal with 2 digit year
11760 if ($match[4] < 50)
11769 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
11778 * Parse C99's asctime()'s date format
11780 * @access protected
11781 * @return int Timestamp
11783 function date_asctime($date)
11788 $space = '[\x09\x20]+';
11789 $wday_name = $this->day_pcre;
11790 $mon_name = $this->month_pcre;
11791 $day = '([0-9]{1,2})';
11792 $hour = $sec = $min = '([0-9]{2})';
11793 $year = '([0-9]{4})';
11794 $terminator = '\x0A?\x00?';
11795 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
11797 if (preg_match($pcre, $date, $match))
11800 Capturing subpatterns:
11810 $month = $this->month[strtolower($match[2])];
11811 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
11820 * Parse dates using strtotime()
11822 * @access protected
11823 * @return int Timestamp
11825 function date_strtotime($date)
11827 $strtotime = strtotime($date);
11828 if ($strtotime === -1 || $strtotime === false)
11840 * Content-type sniffing
11842 * @package SimplePie
11844 class SimplePie_Content_Type_Sniffer
11849 * @var SimplePie_File
11855 * Create an instance of the class with the input file
11858 * @param SimplePie_Content_Type_Sniffer $file Input file
11860 function SimplePie_Content_Type_Sniffer($file)
11862 $this->file = $file;
11866 * Get the Content-Type of the specified file
11869 * @return string Actual Content-Type
11871 function get_type()
11873 if (isset($this->file->headers['content-type']))
11875 if (!isset($this->file->headers['content-encoding'])
11876 && ($this->file->headers['content-type'] === 'text/plain'
11877 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
11878 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
11880 return $this->text_or_binary();
11883 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
11885 $official = substr($this->file->headers['content-type'], 0, $pos);
11889 $official = $this->file->headers['content-type'];
11891 $official = strtolower($official);
11893 if ($official === 'unknown/unknown'
11894 || $official === 'application/unknown')
11896 return $this->unknown();
11898 elseif (substr($official, -4) === '+xml'
11899 || $official === 'text/xml'
11900 || $official === 'application/xml')
11904 elseif (substr($official, 0, 6) === 'image/')
11906 if ($return = $this->image())
11915 elseif ($official === 'text/html')
11917 return $this->feed_or_html();
11926 return $this->unknown();
11931 * Sniff text or binary
11934 * @return string Actual Content-Type
11936 function text_or_binary()
11938 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
11939 || substr($this->file->body, 0, 2) === "\xFF\xFE"
11940 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
11941 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
11943 return 'text/plain';
11945 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
11947 return 'application/octect-stream';
11951 return 'text/plain';
11959 * @return string Actual Content-Type
11963 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
11964 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
11965 || strtolower(substr($this->file->body, $ws, 5)) === '<html'
11966 || strtolower(substr($this->file->body, $ws, 7)) === '<script')
11968 return 'text/html';
11970 elseif (substr($this->file->body, 0, 5) === '%PDF-')
11972 return 'application/pdf';
11974 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
11976 return 'application/postscript';
11978 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
11979 || substr($this->file->body, 0, 6) === 'GIF89a')
11981 return 'image/gif';
11983 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
11985 return 'image/png';
11987 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
11989 return 'image/jpeg';
11991 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
11993 return 'image/bmp';
11997 return $this->text_or_binary();
12005 * @return string Actual Content-Type
12009 if (substr($this->file->body, 0, 6) === 'GIF87a'
12010 || substr($this->file->body, 0, 6) === 'GIF89a')
12012 return 'image/gif';
12014 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
12016 return 'image/png';
12018 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
12020 return 'image/jpeg';
12022 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
12024 return 'image/bmp';
12036 * @return string Actual Content-Type
12038 function feed_or_html()
12040 $len = strlen($this->file->body);
12041 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
12043 while ($pos < $len)
12045 switch ($this->file->body[$pos])
12051 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
12059 return 'text/html';
12062 if (substr($this->file->body, $pos, 3) === '!--')
12065 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
12071 return 'text/html';
12074 elseif (substr($this->file->body, $pos, 1) === '!')
12076 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
12082 return 'text/html';
12085 elseif (substr($this->file->body, $pos, 1) === '?')
12087 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
12093 return 'text/html';
12096 elseif (substr($this->file->body, $pos, 3) === 'rss'
12097 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
12099 return 'application/rss+xml';
12101 elseif (substr($this->file->body, $pos, 4) === 'feed')
12103 return 'application/atom+xml';
12107 return 'text/html';
12111 return 'text/html';
12116 * Parses the XML Declaration
12118 * @package SimplePie
12120 class SimplePie_XML_Declaration_Parser
12128 var $version = '1.0';
12136 var $encoding = 'UTF-8';
12144 var $standalone = false;
12147 * Current state of the state machine
12152 var $state = 'before_version_name';
12163 * Input data length (to avoid calling strlen() everytime this is needed)
12168 var $data_length = 0;
12171 * Current position of the pointer
12179 * Create an instance of the class with the input data
12182 * @param string $data Input data
12184 function SimplePie_XML_Declaration_Parser($data)
12186 $this->data = $data;
12187 $this->data_length = strlen($this->data);
12191 * Parse the input data
12194 * @return bool true on success, false on failure
12198 while ($this->state && $this->state !== 'emit' && $this->has_data())
12200 $state = $this->state;
12204 if ($this->state === 'emit')
12210 $this->version = '';
12211 $this->encoding = '';
12212 $this->standalone = '';
12218 * Check whether there is data beyond the pointer
12221 * @return bool true if there is further data, false if not
12223 function has_data()
12225 return (bool) ($this->position < $this->data_length);
12229 * Advance past any whitespace
12231 * @return int Number of whitespace characters passed
12233 function skip_whitespace()
12235 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
12236 $this->position += $whitespace;
12237 return $whitespace;
12243 function get_value()
12245 $quote = substr($this->data, $this->position, 1);
12246 if ($quote === '"' || $quote === "'")
12249 $len = strcspn($this->data, $quote, $this->position);
12250 if ($this->has_data())
12252 $value = substr($this->data, $this->position, $len);
12253 $this->position += $len + 1;
12260 function before_version_name()
12262 if ($this->skip_whitespace())
12264 $this->state = 'version_name';
12268 $this->state = false;
12272 function version_name()
12274 if (substr($this->data, $this->position, 7) === 'version')
12276 $this->position += 7;
12277 $this->skip_whitespace();
12278 $this->state = 'version_equals';
12282 $this->state = false;
12286 function version_equals()
12288 if (substr($this->data, $this->position, 1) === '=')
12291 $this->skip_whitespace();
12292 $this->state = 'version_value';
12296 $this->state = false;
12300 function version_value()
12302 if ($this->version = $this->get_value())
12304 $this->skip_whitespace();
12305 if ($this->has_data())
12307 $this->state = 'encoding_name';
12311 $this->state = 'emit';
12316 $this->state = 'standalone_name';
12320 function encoding_name()
12322 if (substr($this->data, $this->position, 8) === 'encoding')
12324 $this->position += 8;
12325 $this->skip_whitespace();
12326 $this->state = 'encoding_equals';
12330 $this->state = false;
12334 function encoding_equals()
12336 if (substr($this->data, $this->position, 1) === '=')
12339 $this->skip_whitespace();
12340 $this->state = 'encoding_value';
12344 $this->state = false;
12348 function encoding_value()
12350 if ($this->encoding = $this->get_value())
12352 $this->skip_whitespace();
12353 if ($this->has_data())
12355 $this->state = 'standalone_name';
12359 $this->state = 'emit';
12364 $this->state = false;
12368 function standalone_name()
12370 if (substr($this->data, $this->position, 10) === 'standalone')
12372 $this->position += 10;
12373 $this->skip_whitespace();
12374 $this->state = 'standalone_equals';
12378 $this->state = false;
12382 function standalone_equals()
12384 if (substr($this->data, $this->position, 1) === '=')
12387 $this->skip_whitespace();
12388 $this->state = 'standalone_value';
12392 $this->state = false;
12396 function standalone_value()
12398 if ($standalone = $this->get_value())
12400 switch ($standalone)
12403 $this->standalone = true;
12407 $this->standalone = false;
12411 $this->state = false;
12415 $this->skip_whitespace();
12416 if ($this->has_data())
12418 $this->state = false;
12422 $this->state = 'emit';
12427 $this->state = false;
12432 class SimplePie_Locator
12437 var $local = array();
12438 var $elsewhere = array();
12439 var $file_class = 'SimplePie_File';
12440 var $cached_entities = array();
12443 var $base_location = 0;
12444 var $checked_feeds = 0;
12445 var $max_checked_feeds = 10;
12446 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
12448 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
12450 $this->file =& $file;
12451 $this->file_class = $file_class;
12452 $this->useragent = $useragent;
12453 $this->timeout = $timeout;
12454 $this->max_checked_feeds = $max_checked_feeds;
12455 $this->content_type_sniffer_class = $content_type_sniffer_class;
12458 function find($type = SIMPLEPIE_LOCATOR_ALL)
12460 if ($this->is_feed($this->file))
12462 return $this->file;
12465 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12467 $sniffer = new $this->content_type_sniffer_class($this->file);
12468 if ($sniffer->get_type() !== 'text/html')
12474 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
12479 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
12484 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
12486 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
12491 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
12496 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
12501 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
12509 function is_feed(&$file)
12511 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
12513 $sniffer = new $this->content_type_sniffer_class($file);
12514 $sniffed = $sniffer->get_type();
12515 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'application/atom+xml', 'text/xml', 'application/xml', 'text/plain')))
12524 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
12534 function get_base()
12536 $this->http_base = $this->file->url;
12537 $this->base = $this->http_base;
12538 $elements = SimplePie_Misc::get_element('base', $this->file->body);
12539 foreach ($elements as $element)
12541 if ($element['attribs']['href']['data'] !== '')
12543 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
12544 $this->base_location = $element['offset'];
12550 function autodiscovery()
12552 $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));
12554 foreach ($links as $link)
12556 if ($this->checked_feeds == $this->max_checked_feeds)
12560 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
12562 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
12564 if ($this->base_location < $link['offset'])
12566 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12570 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12573 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'))))
12575 $this->checked_feeds++;
12576 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
12577 if ($this->is_feed($feed))
12588 function get_links()
12590 $links = SimplePie_Misc::get_element('a', $this->file->body);
12591 foreach ($links as $link)
12593 if (isset($link['attribs']['href']['data']))
12595 $href = trim($link['attribs']['href']['data']);
12596 $parsed = SimplePie_Misc::parse_url($href);
12597 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
12599 if ($this->base_location < $link['offset'])
12601 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
12605 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
12608 $current = SimplePie_Misc::parse_url($this->file->url);
12610 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
12612 $this->local[] = $href;
12616 $this->elsewhere[] = $href;
12621 $this->local = array_unique($this->local);
12622 $this->elsewhere = array_unique($this->elsewhere);
12623 if (!empty($this->local) || !empty($this->elsewhere))
12630 function extension(&$array)
12632 foreach ($array as $key => $value)
12634 if ($this->checked_feeds == $this->max_checked_feeds)
12638 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
12640 $this->checked_feeds++;
12641 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12642 if ($this->is_feed($feed))
12648 unset($array[$key]);
12655 function body(&$array)
12657 foreach ($array as $key => $value)
12659 if ($this->checked_feeds == $this->max_checked_feeds)
12663 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
12665 $this->checked_feeds++;
12666 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
12667 if ($this->is_feed($feed))
12673 unset($array[$key]);
12681 class SimplePie_Parser
12686 var $current_column;
12688 var $separator = ' ';
12690 var $namespace = array('');
12691 var $element = array('');
12692 var $xml_base = array('');
12693 var $xml_base_explicit = array(false);
12694 var $xml_lang = array('');
12695 var $data = array();
12696 var $datas = array(array());
12697 var $current_xhtml_construct = -1;
12700 function parse(&$data, $encoding)
12702 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
12703 if (strtoupper($encoding) == 'US-ASCII')
12705 $this->encoding = 'UTF-8';
12709 $this->encoding = $encoding;
12713 // UTF-32 Big Endian BOM
12714 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
12716 $data = substr($data, 4);
12718 // UTF-32 Little Endian BOM
12719 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
12721 $data = substr($data, 4);
12723 // UTF-16 Big Endian BOM
12724 elseif (substr($data, 0, 2) === "\xFE\xFF")
12726 $data = substr($data, 2);
12728 // UTF-16 Little Endian BOM
12729 elseif (substr($data, 0, 2) === "\xFF\xFE")
12731 $data = substr($data, 2);
12734 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
12736 $data = substr($data, 3);
12739 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
12741 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
12742 if ($declaration->parse())
12744 $data = substr($data, $pos + 2);
12745 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
12749 $this->error_string = 'SimplePie bug! Please report this!';
12756 // Create the parser
12757 $xml = xml_parser_create_ns($this->encoding, $this->separator);
12758 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
12759 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
12760 xml_set_object($xml, $this);
12761 xml_set_character_data_handler($xml, 'cdata');
12762 xml_set_element_handler($xml, 'tag_open', 'tag_close');
12765 if (!xml_parse($xml, $data, true))
12767 $this->error_code = xml_get_error_code($xml);
12768 $this->error_string = xml_error_string($this->error_code);
12771 $this->current_line = xml_get_current_line_number($xml);
12772 $this->current_column = xml_get_current_column_number($xml);
12773 $this->current_byte = xml_get_current_byte_index($xml);
12774 xml_parser_free($xml);
12778 function get_error_code()
12780 return $this->error_code;
12783 function get_error_string()
12785 return $this->error_string;
12788 function get_current_line()
12790 return $this->current_line;
12793 function get_current_column()
12795 return $this->current_column;
12798 function get_current_byte()
12800 return $this->current_byte;
12803 function get_data()
12805 return $this->data;
12808 function tag_open($parser, $tag, $attributes)
12810 if ($this->feed === 0)
12814 elseif ($this->feed == false)
12816 if (in_array($tag, array(
12817 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
12818 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
12820 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
12831 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
12833 $attribs = array();
12834 foreach ($attributes as $name => $value)
12836 list($attrib_namespace, $attribute) = $this->split_ns($name);
12837 $attribs[$attrib_namespace][$attribute] = $value;
12840 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
12842 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
12843 $this->xml_base_explicit[] = true;
12847 $this->xml_base[] = end($this->xml_base);
12848 $this->xml_base_explicit[] = end($this->xml_base_explicit);
12851 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
12853 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
12857 $this->xml_lang[] = end($this->xml_lang);
12860 if ($this->current_xhtml_construct >= 0)
12862 $this->current_xhtml_construct++;
12863 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
12865 $this->data['data'] .= '<' . end($this->element);
12866 if (isset($attribs['']))
12868 foreach ($attribs[''] as $name => $value)
12870 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
12873 $this->data['data'] .= '>';
12878 $this->datas[] =& $this->data;
12879 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
12880 $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));
12881 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')
12882 || (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'))
12884 $this->current_xhtml_construct = 0;
12889 function cdata($parser, $cdata)
12891 if ($this->current_xhtml_construct >= 0)
12893 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
12895 elseif ($this->feed > 1)
12897 $this->data['data'] .= $cdata;
12901 function tag_close($parser, $tag)
12908 if ($this->current_xhtml_construct >= 0)
12910 $this->current_xhtml_construct--;
12911 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')))
12913 $this->data['data'] .= '</' . end($this->element) . '>';
12916 if ($this->current_xhtml_construct == -1)
12918 $this->data =& $this->datas[$this->feed];
12919 array_pop($this->datas);
12922 array_pop($this->element);
12923 array_pop($this->namespace);
12924 array_pop($this->xml_base);
12925 array_pop($this->xml_base_explicit);
12926 array_pop($this->xml_lang);
12930 function split_ns($string)
12932 static $cache = array();
12933 if (!isset($cache[$string]))
12935 if ($pos = strpos($string, $this->separator))
12937 static $separator_length;
12938 if (!$separator_length)
12940 $separator_length = strlen($this->separator);
12942 $namespace = substr($string, 0, $pos);
12943 $local_name = substr($string, $pos + $separator_length);
12944 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
12946 $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
12949 // Normalize the Media RSS namespaces
12950 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
12952 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
12954 $cache[$string] = array($namespace, $local_name);
12958 $cache[$string] = array('', $string);
12961 return $cache[$string];
12966 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
12968 class SimplePie_Sanitize
12974 var $remove_div = true;
12975 var $image_handler = '';
12976 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
12977 var $encode_instead_of_strip = false;
12978 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
12979 var $strip_comments = false;
12980 var $output_encoding = 'UTF-8';
12981 var $enable_cache = true;
12982 var $cache_location = './cache';
12983 var $cache_name_function = 'md5';
12984 var $cache_class = 'SimplePie_Cache';
12985 var $file_class = 'SimplePie_File';
12987 var $useragent = '';
12988 var $force_fsockopen = false;
12990 var $replace_url_attributes = array(
12993 'blockquote' => 'cite',
12995 'form' => 'action',
12996 'img' => array('longdesc', 'src'),
13002 function remove_div($enable = true)
13004 $this->remove_div = (bool) $enable;
13007 function set_image_handler($page = false)
13011 $this->image_handler = (string) $page;
13015 $this->image_handler = false;
13019 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
13021 if (isset($enable_cache))
13023 $this->enable_cache = (bool) $enable_cache;
13026 if ($cache_location)
13028 $this->cache_location = (string) $cache_location;
13031 if ($cache_name_function)
13033 $this->cache_name_function = (string) $cache_name_function;
13038 $this->cache_class = (string) $cache_class;
13042 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
13046 $this->file_class = (string) $file_class;
13051 $this->timeout = (string) $timeout;
13056 $this->useragent = (string) $useragent;
13059 if ($force_fsockopen)
13061 $this->force_fsockopen = (string) $force_fsockopen;
13065 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
13069 if (is_array($tags))
13071 $this->strip_htmltags = $tags;
13075 $this->strip_htmltags = explode(',', $tags);
13080 $this->strip_htmltags = false;
13084 function encode_instead_of_strip($encode = false)
13086 $this->encode_instead_of_strip = (bool) $encode;
13089 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
13093 if (is_array($attribs))
13095 $this->strip_attributes = $attribs;
13099 $this->strip_attributes = explode(',', $attribs);
13104 $this->strip_attributes = false;
13108 function strip_comments($strip = false)
13110 $this->strip_comments = (bool) $strip;
13113 function set_output_encoding($encoding = 'UTF-8')
13115 $this->output_encoding = (string) $encoding;
13119 * Set element/attribute key/value pairs of HTML attributes
13120 * containing URLs that need to be resolved relative to the feed
13124 * @param array $element_attribute Element/attribute key/value pairs
13126 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'))
13128 $this->replace_url_attributes = (array) $element_attribute;
13131 function sanitize($data, $type, $base = '')
13133 $data = trim($data);
13134 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
13136 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
13138 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))
13140 $type |= SIMPLEPIE_CONSTRUCT_HTML;
13144 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
13148 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
13150 $data = base64_decode($data);
13153 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
13155 if ($this->remove_div)
13157 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
13158 $data = preg_replace('/<\/div>$/', '', $data);
13162 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
13166 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
13169 if ($this->strip_comments)
13171 $data = SimplePie_Misc::strip_comments($data);
13174 // Strip out HTML tags and attributes that might cause various security problems.
13175 // Based on recommendations by Mark Pilgrim at:
13176 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
13177 if ($this->strip_htmltags)
13179 foreach ($this->strip_htmltags as $tag)
13181 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
13182 while (preg_match($pcre, $data))
13184 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
13189 if ($this->strip_attributes)
13191 foreach ($this->strip_attributes as $attrib)
13193 $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);
13197 // Replace relative URLs
13198 $this->base = $base;
13199 foreach ($this->replace_url_attributes as $element => $attributes)
13201 $data = $this->replace_urls($data, $element, $attributes);
13204 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
13205 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
13207 $images = SimplePie_Misc::get_element('img', $data);
13208 foreach ($images as $img)
13210 if (isset($img['attribs']['src']['data']))
13212 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
13213 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
13215 if ($cache->load())
13217 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13218 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13222 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
13223 $headers = $file->headers;
13225 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
13227 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
13229 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
13230 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
13234 trigger_error("$cache->name is not writeable", E_USER_WARNING);
13242 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
13243 $data = trim($data);
13246 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
13248 $data = SimplePie_Misc::absolutize_url($data, $base);
13251 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
13253 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
13256 if ($this->output_encoding != 'UTF-8')
13258 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
13264 function replace_urls($data, $tag, $attributes)
13266 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
13268 $elements = SimplePie_Misc::get_element($tag, $data);
13269 foreach ($elements as $element)
13271 if (is_array($attributes))
13273 foreach ($attributes as $attribute)
13275 if (isset($element['attribs'][$attribute]['data']))
13277 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
13278 $new_element = SimplePie_Misc::element_implode($element);
13279 $data = str_replace($element['full'], $new_element, $data);
13280 $element['full'] = $new_element;
13284 elseif (isset($element['attribs'][$attributes]['data']))
13286 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
13287 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
13294 function do_strip_htmltags($match)
13296 if ($this->encode_instead_of_strip)
13298 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
13300 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
13301 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
13302 return "<$match[1]$match[2]>$match[3]</$match[1]>";
13306 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
13309 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))