5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
36 * @version "Razzleberry"
37 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
39 * @author Geoffrey Sneddon
40 * @link http://simplepie.org/ SimplePie
41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @todo phpDoc comments
49 define('SIMPLEPIE_NAME', 'SimplePie');
54 define('SIMPLEPIE_VERSION', '1.0.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', 20070719221955);
63 * SimplePie Website URL
65 define('SIMPLEPIE_URL', 'http://simplepie.org/');
69 * @see SimplePie::set_useragent()
71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
80 * @see SimplePie::set_autodiscovery_level()
82 define('SIMPLEPIE_LOCATOR_NONE', 0);
85 * Feed Link Element Autodiscovery
86 * @see SimplePie::set_autodiscovery_level()
88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
91 * Local Feed Extension Autodiscovery
92 * @see SimplePie::set_autodiscovery_level()
94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
97 * Local Feed Body Autodiscovery
98 * @see SimplePie::set_autodiscovery_level()
100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
103 * Remote Feed Extension Autodiscovery
104 * @see SimplePie::set_autodiscovery_level()
106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
109 * Remote Feed Body Autodiscovery
110 * @see SimplePie::set_autodiscovery_level()
112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
115 * All Feed Autodiscovery
116 * @see SimplePie::set_autodiscovery_level()
118 define('SIMPLEPIE_LOCATOR_ALL', 31);
123 define('SIMPLEPIE_TYPE_NONE', 0);
128 define('SIMPLEPIE_TYPE_RSS_090', 1);
131 * RSS 0.91 (Netscape)
133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
136 * RSS 0.91 (Userland)
138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
141 * RSS 0.91 (both Netscape and Userland)
143 define('SIMPLEPIE_TYPE_RSS_091', 6);
148 define('SIMPLEPIE_TYPE_RSS_092', 8);
153 define('SIMPLEPIE_TYPE_RSS_093', 16);
158 define('SIMPLEPIE_TYPE_RSS_094', 32);
163 define('SIMPLEPIE_TYPE_RSS_10', 64);
168 define('SIMPLEPIE_TYPE_RSS_20', 128);
173 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
176 * Non-RDF-based RSS (truly intended as syndication format)
178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
183 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
188 define('SIMPLEPIE_TYPE_ATOM_03', 256);
193 define('SIMPLEPIE_TYPE_ATOM_10', 512);
198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
203 define('SIMPLEPIE_TYPE_ALL', 1023);
208 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
218 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
226 * base64-encoded construct
228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
233 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
236 * A construct that might be HTML
238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
243 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
246 * PCRE for HTML attributes
248 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[a-z0-9\-._:]*)))?)*)\s*');
251 * PCRE for XML attributes
253 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
258 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
263 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
268 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
273 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
278 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
283 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
286 * RSS 1.0 Content Module Namespace
288 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
293 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
298 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
301 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
303 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
308 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
311 * Media RSS Namespace
313 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
316 * iTunes RSS Namespace
318 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
323 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
326 * IANA Link Relations Registry
328 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
331 * Whether we're running on PHP5
333 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
339 * @version "Razzleberry"
340 * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
341 * @author Ryan Parman
342 * @author Geoffrey Sneddon
343 * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
348 * @var array Raw data
354 * @var mixed Error string
360 * @var object Instance of SimplePie_Sanitize (or other class)
361 * @see SimplePie::set_sanitize_class()
367 * @var string SimplePie Useragent
368 * @see SimplePie::set_useragent()
371 var $useragent = SIMPLEPIE_USERAGENT;
374 * @var string Feed URL
375 * @see SimplePie::set_feed_url()
381 * @var object Instance of SimplePie_File to use as a feed
382 * @see SimplePie::set_file()
388 * @var string Raw feed data
389 * @see SimplePie::set_raw_data()
395 * @var int Timeout for fetching remote files
396 * @see SimplePie::set_timeout()
402 * @var bool Forces fsockopen() to be used for remote files instead
403 * of cURL, even if a new enough version is installed
404 * @see SimplePie::force_fsockopen()
407 var $force_fsockopen = false;
410 * @var bool Enable/Disable XML dump
411 * @see SimplePie::enable_xml_dump()
414 var $xml_dump = false;
417 * @var bool Enable/Disable Caching
418 * @see SimplePie::enable_cache()
424 * @var int Cache duration (in seconds)
425 * @see SimplePie::set_cache_duration()
428 var $cache_duration = 3600;
431 * @var int Auto-discovery cache duration (in seconds)
432 * @see SimplePie::set_autodiscovery_cache_duration()
435 var $autodiscovery_cache_duration = 604800; // 7 Days.
438 * @var string Cache location (relative to executing script)
439 * @see SimplePie::set_cache_location()
442 var $cache_location = './cache';
445 * @var string Function that creates the cache filename
446 * @see SimplePie::set_cache_name_function()
449 var $cache_name_function = 'md5';
452 * @var bool Reorder feed by date descending
453 * @see SimplePie::enable_order_by_date()
456 var $order_by_date = true;
459 * @var mixed Force input encoding to be set to the follow value
460 * (false, or anything type-cast to false, disables this feature)
461 * @see SimplePie::set_input_encoding()
464 var $input_encoding = false;
467 * @var int Feed Autodiscovery Level
468 * @see SimplePie::set_autodiscovery_level()
471 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
474 * @var string Class used for caching feeds
475 * @see SimplePie::set_cache_class()
478 var $cache_class = 'SimplePie_Cache';
481 * @var string Class used for locating feeds
482 * @see SimplePie::set_locator_class()
485 var $locator_class = 'SimplePie_Locator';
488 * @var string Class used for parsing feeds
489 * @see SimplePie::set_parser_class()
492 var $parser_class = 'SimplePie_Parser';
495 * @var string Class used for fetching feeds
496 * @see SimplePie::set_file_class()
499 var $file_class = 'SimplePie_File';
502 * @var string Class used for items
503 * @see SimplePie::set_item_class()
506 var $item_class = 'SimplePie_Item';
509 * @var string Class used for authors
510 * @see SimplePie::set_author_class()
513 var $author_class = 'SimplePie_Author';
516 * @var string Class used for categories
517 * @see SimplePie::set_category_class()
520 var $category_class = 'SimplePie_Category';
523 * @var string Class used for enclosures
524 * @see SimplePie::set_enclosures_class()
527 var $enclosure_class = 'SimplePie_Enclosure';
530 * @var string Class used for Media RSS <media:text> captions
531 * @see SimplePie::set_caption_class()
534 var $caption_class = 'SimplePie_Caption';
537 * @var string Class used for Media RSS <media:copyright>
538 * @see SimplePie::set_copyright_class()
541 var $copyright_class = 'SimplePie_Copyright';
544 * @var string Class used for Media RSS <media:credit>
545 * @see SimplePie::set_credit_class()
548 var $credit_class = 'SimplePie_Credit';
551 * @var string Class used for Media RSS <media:rating>
552 * @see SimplePie::set_rating_class()
555 var $rating_class = 'SimplePie_Rating';
558 * @var string Class used for Media RSS <media:restriction>
559 * @see SimplePie::set_restriction_class()
562 var $restriction_class = 'SimplePie_Restriction';
565 * @var mixed Set javascript query string parameter (false, or
566 * anything type-cast to false, disables this feature)
567 * @see SimplePie::set_javascript()
570 var $javascript = 'js';
573 * @var int Maximum number of feeds to check with autodiscovery
574 * @see SimplePie::set_max_checked_feeds()
577 var $max_checked_feeds = 10;
580 * @var string Web-accessible path to the handler_favicon.php file.
581 * @see SimplePie::set_favicon_handler()
584 var $favicon_handler = '';
587 * @var string Web-accessible path to the handler_image.php file.
588 * @see SimplePie::set_image_handler()
591 var $image_handler = '';
594 * @var array Stores the URLs when multiple feeds are being initialized.
595 * @see SimplePie::set_feed_url()
598 var $multifeed_url = array();
601 * @var array Stores SimplePie objects when multiple feeds initialized.
604 var $multifeed_objects = array();
607 * @var array Stores the get_object_vars() array for use with multifeeds.
608 * @see SimplePie::set_feed_url()
611 var $config_settings = null;
614 * @var array Stores the default attributes to be stripped by strip_attributes().
615 * @see SimplePie::strip_attributes()
618 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
621 * @var array Stores the default tags to be stripped by strip_htmltags().
622 * @see SimplePie::strip_htmltags()
625 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
628 * The SimplePie class contains feed level data and options
630 * There are two ways that you can create a new SimplePie object. The first
631 * is by passing a feed URL as a parameter to the SimplePie constructor
632 * (as well as optionally setting the cache location and cache expiry). This
633 * will initialise the whole feed with all of the default settings, and you
634 * can begin accessing methods and properties immediately.
636 * The second way is to create the SimplePie object with no parameters
637 * at all. This will enable you to set configuration options. After setting
638 * them, you must initialise the feed using $feed->init(). At that point the
639 * object's methods and properties will be available to you. This format is
640 * what is used throughout this documentation.
643 * @since 1.0 Preview Release
644 * @param string $feed_url This is the URL you want to parse.
645 * @param string $cache_location This is where you want the cache to be stored.
646 * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
648 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
650 // Other objects, instances created here so we can set options on them
651 $this->sanitize =& new SimplePie_Sanitize;
653 // Set options if they're passed to the constructor
654 if ($cache_location !== null)
656 $this->set_cache_location($cache_location);
659 if ($cache_duration !== null)
661 $this->set_cache_duration($cache_duration);
664 // Only init the script if we're passed a feed URL
665 if ($feed_url !== null)
667 $this->set_feed_url($feed_url);
673 * Used for converting object to a string
675 function __toString()
677 return md5(serialize($this->data));
681 * This is the URL of the feed you want to parse.
683 * This allows you to enter the URL of the feed you want to parse, or the
684 * website you want to try to use auto-discovery on. This takes priority
685 * over any set raw data.
687 * You can set multiple feeds to mash together by passing an array instead
688 * of a string for the $url. Remember that with each additional feed comes
689 * additional processing and resources.
692 * @since 1.0 Preview Release
693 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
694 * @see SimplePie::set_raw_data()
696 function set_feed_url($url)
700 $this->multifeed_url = array();
701 foreach ($url as $value)
703 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
708 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
713 * Provides an instance of SimplePie_File to use as a feed
716 * @param object &$file Instance of SimplePie_File (or subclass)
717 * @return bool True on success, false on failure
719 function set_file(&$file)
721 if (SimplePie_Misc::is_a($file, 'SimplePie_File'))
723 $this->feed_url = $file->url;
724 $this->file =& $file;
731 * Allows you to use a string of RSS/Atom data instead of a remote feed.
733 * If you have a feed available as a string in PHP, you can tell SimplePie
734 * to parse that data string instead of a remote feed. Any set feed URL
739 * @param string $data RSS or Atom data as a string.
740 * @see SimplePie::set_feed_url()
742 function set_raw_data($data)
744 $this->raw_data = trim($data);
748 * Allows you to override the default timeout for fetching remote feeds.
750 * This allows you to change the maximum time the feed's server to respond
751 * and send the feed back.
755 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
757 function set_timeout($timeout = 10)
759 $this->timeout = (int) $timeout;
763 * Forces SimplePie to use fsockopen() instead of the preferred cURL
768 * @param bool $enable Force fsockopen() to be used
770 function force_fsockopen($enable = false)
772 $this->force_fsockopen = (bool) $enable;
776 * Outputs the raw XML content of the feed, after it has gone through
777 * SimplePie's filters.
779 * Used only for debugging, this function will output the XML content as
780 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
781 * before trying to parse it. Many parts of the feed are re-written in
782 * memory, and in the end, you have a parsable feed. XML dump shows you the
783 * actual XML that SimplePie tries to parse, which may or may not be very
784 * different from the original feed.
787 * @since 1.0 Preview Release
788 * @param bool $enable Enable XML dump
790 function enable_xml_dump($enable = false)
792 $this->xml_dump = (bool) $enable;
796 * Enables/disables caching in SimplePie.
798 * This option allows you to disable caching all-together in SimplePie.
799 * However, disabling the cache can lead to longer load times.
802 * @since 1.0 Preview Release
803 * @param bool $enable Enable caching
805 function enable_cache($enable = true)
807 $this->cache = (bool) $enable;
811 * Set the length of time (in seconds) that the contents of a feed
815 * @param int $seconds The feed content cache duration.
817 function set_cache_duration($seconds = 3600)
819 $this->cache_duration = (int) $seconds;
823 * Set the length of time (in seconds) that the autodiscovered feed
824 * URL will be cached.
827 * @param int $seconds The autodiscovered feed URL cache duration.
829 function set_autodiscovery_cache_duration($seconds = 604800)
831 $this->autodiscovery_cache_duration = (int) $seconds;
835 * Set the file system location where the cached files should be stored.
838 * @param string $location The file system location.
840 function set_cache_location($location = './cache')
842 $this->cache_location = (string) $location;
846 * Determines whether feed items should be sorted into reverse chronological order.
849 * @param bool $enable Sort as reverse chronological order.
851 function enable_order_by_date($enable = true)
853 $this->order_by_date = (bool) $enable;
857 * Allows you to override the character encoding reported by the feed.
860 * @param string $encoding Character encoding.
862 function set_input_encoding($encoding = false)
866 $this->input_encoding = (string) $encoding;
870 $this->input_encoding = false;
875 * Set how much feed autodiscovery to do
878 * @see SIMPLEPIE_LOCATOR_NONE
879 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
880 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
881 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
882 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
883 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
884 * @see SIMPLEPIE_LOCATOR_ALL
885 * @param int $level Feed Autodiscovery Level (level can be a
886 * combination of the above constants, see bitwise OR operator)
888 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
890 $this->autodiscovery = (int) $level;
894 * Allows you to change which class SimplePie uses for caching.
895 * Useful when you are overloading or extending SimplePie's default classes.
898 * @param string $class Name of custom class.
899 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
900 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
902 function set_cache_class($class = 'SimplePie_Cache')
904 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
906 $this->cache_class = $class;
913 * Allows you to change which class SimplePie uses for auto-discovery.
914 * Useful when you are overloading or extending SimplePie's default classes.
917 * @param string $class Name of custom class.
918 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
919 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
921 function set_locator_class($class = 'SimplePie_Locator')
923 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
925 $this->locator_class = $class;
932 * Allows you to change which class SimplePie uses for XML parsing.
933 * Useful when you are overloading or extending SimplePie's default classes.
936 * @param string $class Name of custom class.
937 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
938 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
940 function set_parser_class($class = 'SimplePie_Parser')
942 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
944 $this->parser_class = $class;
951 * Allows you to change which class SimplePie uses for remote file fetching.
952 * Useful when you are overloading or extending SimplePie's default classes.
955 * @param string $class Name of custom class.
956 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
957 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
959 function set_file_class($class = 'SimplePie_File')
961 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
963 $this->file_class = $class;
970 * Allows you to change which class SimplePie uses for data sanitization.
971 * Useful when you are overloading or extending SimplePie's default classes.
974 * @param string $class Name of custom class.
975 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
976 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
978 function set_sanitize_class($class = 'SimplePie_Sanitize')
980 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
982 $this->sanitize =& new $class;
989 * Allows you to change which class SimplePie uses for handling feed items.
990 * Useful when you are overloading or extending SimplePie's default classes.
993 * @param string $class Name of custom class.
994 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
995 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
997 function set_item_class($class = 'SimplePie_Item')
999 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1001 $this->item_class = $class;
1008 * Allows you to change which class SimplePie uses for handling author data.
1009 * Useful when you are overloading or extending SimplePie's default classes.
1012 * @param string $class Name of custom class.
1013 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1014 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1016 function set_author_class($class = 'SimplePie_Author')
1018 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1020 $this->author_class = $class;
1027 * Allows you to change which class SimplePie uses for handling category data.
1028 * Useful when you are overloading or extending SimplePie's default classes.
1031 * @param string $class Name of custom class.
1032 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1033 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1035 function set_category_class($class = 'SimplePie_Category')
1037 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1039 $this->category_class = $class;
1046 * Allows you to change which class SimplePie uses for feed enclosures.
1047 * Useful when you are overloading or extending SimplePie's default classes.
1050 * @param string $class Name of custom class.
1051 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1052 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1054 function set_enclosure_class($class = 'SimplePie_Enclosure')
1056 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1058 $this->enclosure_class = $class;
1065 * Allows you to change which class SimplePie uses for <media:text> captions
1066 * Useful when you are overloading or extending SimplePie's default classes.
1069 * @param string $class Name of custom class.
1070 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1071 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1073 function set_caption_class($class = 'SimplePie_Caption')
1075 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1077 $this->caption_class = $class;
1084 * Allows you to change which class SimplePie uses for <media:copyright>
1085 * Useful when you are overloading or extending SimplePie's default classes.
1088 * @param string $class Name of custom class.
1089 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1090 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1092 function set_copyright_class($class = 'SimplePie_Copyright')
1094 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1096 $this->copyright_class = $class;
1103 * Allows you to change which class SimplePie uses for <media:credit>
1104 * Useful when you are overloading or extending SimplePie's default classes.
1107 * @param string $class Name of custom class.
1108 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1109 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1111 function set_credit_class($class = 'SimplePie_Credit')
1113 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1115 $this->credit_class = $class;
1122 * Allows you to change which class SimplePie uses for <media:rating>
1123 * Useful when you are overloading or extending SimplePie's default classes.
1126 * @param string $class Name of custom class.
1127 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1128 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1130 function set_rating_class($class = 'SimplePie_Rating')
1132 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1134 $this->rating_class = $class;
1141 * Allows you to change which class SimplePie uses for <media:restriction>
1142 * Useful when you are overloading or extending SimplePie's default classes.
1145 * @param string $class Name of custom class.
1146 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1147 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1149 function set_restriction_class($class = 'SimplePie_Restriction')
1151 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1153 $this->restriction_class = $class;
1160 * Allows you to override the default user agent string.
1163 * @param string $ua New user agent string.
1165 function set_useragent($ua = SIMPLEPIE_USERAGENT)
1167 $this->useragent = (string) $ua;
1171 * Set callback function to create cache filename with
1174 * @param mixed $function Callback function
1176 function set_cache_name_function($function = 'md5')
1178 if (is_callable($function))
1180 $this->cache_name_function = $function;
1185 * Set javascript query string parameter
1188 * @param mixed $get Javascript query string parameter
1190 function set_javascript($get = 'js')
1194 $this->javascript = (string) $get;
1198 $this->javascript = false;
1203 * Set options to make SP as fast as possible. Forgoes a
1204 * substantial amount of data sanitization in favor of speed.
1207 * @param bool $set Whether to set them or not
1209 function set_stupidly_fast($set = false)
1213 $this->enable_order_by_date(false);
1214 $this->remove_div(false);
1215 $this->strip_comments(false);
1216 $this->strip_htmltags(false);
1217 $this->strip_attributes(false);
1218 $this->set_image_handler(false);
1223 * Set maximum number of feeds to check with autodiscovery
1226 * @param int $max Maximum number of feeds to check
1228 function set_max_checked_feeds($max = 10)
1230 $this->max_checked_feeds = (int) $max;
1233 function remove_div($enable = true)
1235 $this->sanitize->remove_div($enable);
1238 function strip_htmltags($tags = '', $encode = null)
1242 $tags = $this->strip_htmltags;
1244 $this->sanitize->strip_htmltags($tags);
1245 if ($encode !== null)
1247 $this->sanitize->encode_instead_of_strip($tags);
1251 function encode_instead_of_strip($enable = true)
1253 $this->sanitize->encode_instead_of_strip($enable);
1256 function strip_attributes($attribs = '')
1258 if ($attribs === '')
1260 $attribs = $this->strip_attributes;
1262 $this->sanitize->strip_attributes($attribs);
1265 function set_output_encoding($encoding = 'UTF-8')
1267 $this->sanitize->set_output_encoding($encoding);
1270 function strip_comments($strip = false)
1272 $this->sanitize->strip_comments($strip);
1276 * Set element/attribute key/value pairs of HTML attributes
1277 * containing URLs that need to be resolved relative to the feed
1281 * @param array $element_attribute Element/attribute key/value pairs
1283 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'))
1285 $this->sanitize->set_url_replacements($element_attribute);
1289 * Set the handler to enable the display of cached favicons.
1292 * @param str $page Web-accessible path to the handler_favicon.php file.
1293 * @param str $qs The query string that the value should be passed to.
1295 function set_favicon_handler($page = false, $qs = 'i')
1299 $this->favicon_handler = $page . '?' . $qs . '=';
1303 $this->favicon_handler = '';
1308 * Set the handler to enable the display of cached images.
1311 * @param str $page Web-accessible path to the handler_image.php file.
1312 * @param str $qs The query string that the value should be passed to.
1314 function set_image_handler($page = false, $qs = 'i')
1318 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1322 $this->image_handler = '';
1328 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.1.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1332 if (isset($_GET[$this->javascript]))
1334 if (function_exists('ob_gzhandler'))
1336 ob_start('ob_gzhandler');
1338 header('Content-type: text/javascript; charset: UTF-8');
1339 header('Cache-Control: must-revalidate');
1340 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1342 function embed_odeo(link) {
1343 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>');
1346 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1347 if (placeholder != '') {
1348 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>');
1351 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>');
1355 function embed_flash(bgcolor, width, height, link, loop, type) {
1356 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>');
1359 function embed_flv(width, height, link, placeholder, loop, player) {
1360 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>');
1363 function embed_wmedia(width, height, link) {
1364 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1370 // Pass whatever was set with config options over to the sanitizer.
1371 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1372 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1374 if ($this->feed_url !== null || $this->raw_data !== null)
1376 $this->data = array();
1377 $this->multifeed_objects = array();
1380 if ($this->feed_url !== null)
1382 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1383 // Decide whether to enable caching
1384 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1386 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1388 // If it's enabled and we don't want an XML dump, use the cache
1389 if ($cache && !$this->xml_dump)
1392 $this->data = $cache->load();
1393 if (!empty($this->data))
1395 // If the cache is for an outdated build of SimplePie
1396 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1399 $this->data = array();
1401 // If we've hit a collision just rerun it with caching disabled
1402 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1405 $this->data = array();
1407 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1408 elseif (isset($this->data['feed_url']))
1410 // If the autodiscovery cache is still valid use it.
1411 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1413 // Do not need to do feed autodiscovery yet.
1414 if ($this->data['feed_url'] == $this->data['url'])
1417 $this->data = array();
1421 $this->set_feed_url($this->data['feed_url']);
1422 return $this->init();
1426 // Check if the cache has been updated
1427 elseif ($cache->mtime() + $this->cache_duration < time())
1429 // If we have last-modified and/or etag set
1430 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1433 if (isset($this->data['headers']['last-modified']))
1435 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1437 if (isset($this->data['headers']['etag']))
1439 $headers['if-none-match'] = $this->data['headers']['etag'];
1441 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1444 if ($file->status_code == 304)
1451 $headers = $file->headers;
1460 // If the cache is still valid, just return true
1466 // If the cache is empty, delete it
1470 $this->data = array();
1473 // 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.
1476 if (SimplePie_Misc::is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1478 $file =& $this->file;
1482 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1485 // If the file connection has an error, set SimplePie::error to that and quit
1486 if (!$file->success)
1488 $this->error = $file->error;
1489 if (!empty($this->data))
1499 // Check if the supplied URL is a feed, if it isn't, look for it.
1500 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds);
1501 if (!$locate->is_feed($file))
1503 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1505 if ($file = $locate->find($this->autodiscovery))
1509 if (!$cache->save(array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD)))
1511 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1513 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1515 $this->feed_url = $file->url;
1519 $this->error = "A feed could not be found at $this->feed_url";
1520 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1526 $headers = $file->headers;
1527 $data = trim($file->body);
1532 $data = $this->raw_data;
1535 // First check to see if input has been overridden.
1536 if ($this->input_encoding !== false)
1538 $encoding = $this->input_encoding;
1540 // Second try HTTP headers
1541 elseif (isset($headers['content-type']) && preg_match('/;[\x09\x20]*charset=([^;]*)/i', $headers['content-type'], $charset))
1543 $encoding = $charset[1];
1545 // Then prolog, if at the very start of the document
1546 elseif (preg_match("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')[\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*')([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", $data, $prolog))
1548 $encoding = substr($prolog[6], 1, -1);
1550 // UTF-32 Big Endian BOM
1551 elseif (strpos($data, "\x0\x0\xFE\xFF") === 0)
1553 $encoding = 'UTF-32be';
1555 // UTF-32 Little Endian BOM
1556 elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
1558 $encoding = 'UTF-32';
1560 // UTF-16 Big Endian BOM
1561 elseif (strpos($data, "\xFE\xFF") === 0)
1563 $encoding = 'UTF-16be';
1565 // UTF-16 Little Endian BOM
1566 elseif (strpos($data, "\xFF\xFE") === 0)
1568 $encoding = 'UTF-16le';
1571 elseif (strpos($data, "\xEF\xBB\xBF") === 0)
1573 $encoding = 'UTF-8';
1575 // Fallback to the default (US-ASCII for text/xml, ISO-8859-1 for text/* MIME types, UTF-8 otherwise)
1576 elseif (isset($headers['content-type']) && strtolower(SimplePie_Misc::parse_mime($headers['content-type'])) == 'text/xml')
1578 $encoding = 'US-ASCII';
1580 elseif (isset($headers['content-type']) && SimplePie_Misc::stripos(SimplePie_Misc::parse_mime($headers['content-type']), 'text/') === 0)
1582 $encoding = 'ISO-8859-1';
1586 $encoding = 'UTF-8';
1589 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1590 if ($encoding != 'UTF-8')
1592 $data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1595 // Strip illegal characters
1596 $data = SimplePie_Misc::utf8_bad_replace($data);
1598 $parser =& new $this->parser_class();
1599 $parser->pre_process($data, 'UTF-8');
1600 // If we want the XML, just output that and quit
1601 if ($this->xml_dump)
1603 header('Content-type: text/xml; charset=UTF-8');
1607 // If it's parsed fine
1608 elseif ($parser->parse($data))
1611 $this->data = $parser->get_data();
1612 if (isset($this->data['child']))
1614 if (isset($headers))
1616 $this->data['headers'] = $headers;
1618 $this->data['build'] = SIMPLEPIE_BUILD;
1620 // Cache the file if caching is enabled
1621 if ($cache && !$cache->save($this->data))
1623 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1629 $this->error = "A feed could not be found at $this->feed_url";
1630 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1634 // If we have an error, just set SimplePie::error to it and quit
1637 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1638 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1642 elseif (!empty($this->multifeed_url))
1646 $this->multifeed_objects = array();
1647 foreach ($this->multifeed_url as $url)
1651 // This keyword needs to defy coding standards for PHP4 compatibility
1652 $this->multifeed_objects[$i] = clone($this);
1656 $this->multifeed_objects[$i] = $this;
1658 $this->multifeed_objects[$i]->set_feed_url($url);
1659 $success |= $this->multifeed_objects[$i]->init();
1662 return (bool) $success;
1671 * Return the error message for the occured error
1674 * @return string Error message
1678 return $this->error;
1681 function get_encoding()
1683 return $this->sanitize->output_encoding;
1686 function handle_content_type($mime = 'text/html')
1688 if (!headers_sent())
1690 $header = "Content-type: $mime;";
1691 if ($this->get_encoding())
1693 $header .= ' charset=' . $this->get_encoding();
1697 $header .= ' charset=UTF-8';
1705 if (!isset($this->data['type']))
1707 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1708 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1710 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1712 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1714 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1716 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1718 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1719 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1720 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1721 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1723 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1725 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1726 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1727 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1728 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1730 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1733 elseif (isset($this->data['child']['']['rss']))
1735 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1736 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1738 switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1741 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1742 if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1744 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1747 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1751 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1758 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1762 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1766 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1770 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1777 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1780 return $this->data['type'];
1784 * Returns the URL for the favicon of the feed's website.
1789 function get_favicon()
1791 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1793 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1795 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1797 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1799 if ($this->cache && $this->favicon_handler)
1801 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $favicon), 'spi');
1805 return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1809 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1811 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1813 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1815 return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1819 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1820 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1827 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1834 * @todo If we have a perm redirect we should return the new URL
1835 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1836 * @todo Also, |atom:link|@rel=self
1838 function subscribe_url()
1840 if ($this->feed_url !== null)
1842 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1850 function subscribe_feed()
1852 if ($this->feed_url !== null)
1854 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1862 function subscribe_outlook()
1864 if ($this->feed_url !== null)
1866 return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1874 function subscribe_podcast()
1876 if ($this->feed_url !== null)
1878 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
1886 function subscribe_itunes()
1888 if ($this->feed_url !== null)
1890 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
1899 * Creates the subscribe_* methods' return data
1902 * @param string $feed_url String to prefix to the feed URL
1903 * @param string $site_url String to prefix to the site URL (and
1904 * suffix to the feed URL)
1905 * @return mixed URL if feed exists, false otherwise
1907 function subscribe_service($feed_url, $site_url = null)
1909 if ($this->subscribe_url())
1911 $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->subscribe_url());
1912 if ($site_url !== null && $this->get_link() !== null)
1914 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
1924 function subscribe_aol()
1926 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
1929 function subscribe_bloglines()
1931 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
1934 function subscribe_eskobo()
1936 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
1939 function subscribe_feedfeeds()
1941 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
1944 function subscribe_feedster()
1946 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
1949 function subscribe_google()
1951 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
1954 function subscribe_gritwire()
1956 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
1959 function subscribe_msn()
1961 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
1964 function subscribe_netvibes()
1966 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
1969 function subscribe_newsburst()
1971 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
1974 function subscribe_newsgator()
1976 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
1979 function subscribe_odeo()
1981 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
1984 function subscribe_podnova()
1986 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
1989 function subscribe_rojo()
1991 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
1994 function subscribe_yahoo()
1996 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
1999 function get_feed_tags($namespace, $tag)
2001 $type = $this->get_type();
2002 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2004 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2006 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2009 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2011 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2013 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2016 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2018 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2020 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2023 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2025 if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2027 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2033 function get_channel_tags($namespace, $tag)
2035 $type = $this->get_type();
2036 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2038 if ($return = $this->get_feed_tags($namespace, $tag))
2043 if ($type & SIMPLEPIE_TYPE_RSS_10)
2045 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2047 if (isset($channel[0]['child'][$namespace][$tag]))
2049 return $channel[0]['child'][$namespace][$tag];
2053 if ($type & SIMPLEPIE_TYPE_RSS_090)
2055 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2057 if (isset($channel[0]['child'][$namespace][$tag]))
2059 return $channel[0]['child'][$namespace][$tag];
2063 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2065 if ($channel = $this->get_feed_tags('', 'channel'))
2067 if (isset($channel[0]['child'][$namespace][$tag]))
2069 return $channel[0]['child'][$namespace][$tag];
2076 function get_image_tags($namespace, $tag)
2078 $type = $this->get_type();
2079 if ($type & SIMPLEPIE_TYPE_RSS_10)
2081 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2083 if (isset($image[0]['child'][$namespace][$tag]))
2085 return $image[0]['child'][$namespace][$tag];
2089 if ($type & SIMPLEPIE_TYPE_RSS_090)
2091 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2093 if (isset($image[0]['child'][$namespace][$tag]))
2095 return $image[0]['child'][$namespace][$tag];
2099 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2101 if ($image = $this->get_channel_tags('', 'image'))
2103 if (isset($image[0]['child'][$namespace][$tag]))
2105 return $image[0]['child'][$namespace][$tag];
2112 function get_base($element = array())
2114 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2116 return $element['xml_base'];
2118 elseif ($this->get_link() !== null)
2120 return $this->get_link();
2122 elseif (isset($this->data['headers']['content-location']))
2124 return SimplePie_Misc::absolutize_url($this->data['headers']['content-location'], $this->subscribe_url());
2128 return $this->subscribe_url();
2132 function sanitize($data, $type, $base = '')
2134 return $this->sanitize->sanitize($data, $type, $base);
2137 function get_title()
2139 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2141 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2143 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2145 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2147 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2149 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2151 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2153 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2155 elseif ($return = $this->get_channel_tags('', 'title'))
2157 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2159 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2161 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2163 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2165 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2173 function get_link($key = 0, $rel = 'alternate')
2175 $links = $this->get_links($rel);
2176 if (isset($links[$key]))
2178 return $links[$key];
2187 * Added for parity between the parent-level and the item/entry-level.
2189 function get_permalink()
2191 return $this->get_link(0);
2194 function get_links($rel = 'alternate')
2196 if (!isset($this->data['links']))
2198 $this->data['links'] = array();
2199 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2201 foreach ($links as $link)
2203 if (isset($link['attribs']['']['href']))
2205 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2206 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2210 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2212 foreach ($links as $link)
2214 if (isset($link['attribs']['']['href']))
2216 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2217 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2222 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2224 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2226 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2228 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2230 if ($links = $this->get_channel_tags('', 'link'))
2232 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2235 $keys = array_keys($this->data['links']);
2236 foreach ($keys as $key)
2238 if (SimplePie_Misc::is_isegment_nz_nc($key))
2240 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2242 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2243 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2247 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2250 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2252 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2254 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2258 if (isset($this->data['links'][$rel]))
2260 return $this->data['links'][$rel];
2268 function get_description()
2270 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2272 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2274 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2276 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2278 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2280 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2282 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2284 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2286 elseif ($return = $this->get_channel_tags('', 'description'))
2288 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2290 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2292 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2294 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2298 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2302 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2304 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2312 function get_copyright()
2314 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2316 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2318 elseif ($return = $this->get_channel_tags('', 'copyright'))
2320 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2322 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2324 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2326 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2328 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2336 function get_language()
2338 if ($return = $this->get_channel_tags('', 'language'))
2340 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2342 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2344 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2346 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2348 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2350 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2352 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2354 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2356 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2358 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2360 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2362 elseif (isset($this->data['headers']['content-language']))
2364 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2372 function get_latitude()
2374 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2376 return (float) $return[0]['data'];
2378 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2380 return (float) $match[1];
2388 function get_longitude()
2390 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2392 return (float) $return[0]['data'];
2394 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2396 return (float) $return[0]['data'];
2398 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2400 return (float) $match[2];
2408 function get_image_title()
2410 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2412 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2414 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2416 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2418 elseif ($return = $this->get_image_tags('', 'title'))
2420 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2422 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2424 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2426 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2428 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2436 function get_image_url()
2438 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2440 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2442 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2444 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2446 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2448 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2450 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2452 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2454 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2456 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2458 elseif ($return = $this->get_image_tags('', 'url'))
2460 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2468 function get_image_link()
2470 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2472 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2474 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2476 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2478 elseif ($return = $this->get_image_tags('', 'link'))
2480 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2488 function get_image_width()
2490 if ($return = $this->get_image_tags('', 'width'))
2492 return round($return[0]['data']);
2494 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2504 function get_image_height()
2506 if ($return = $this->get_image_tags('', 'height'))
2508 return round($return[0]['data']);
2510 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2520 function get_item_quantity($max = 0)
2522 $qty = count($this->get_items());
2529 return ($qty > $max) ? $max : $qty;
2533 function get_item($key = 0)
2535 $items = $this->get_items();
2536 if (isset($items[$key]))
2538 return $items[$key];
2546 function get_items($start = 0, $end = 0)
2548 if (!empty($this->multifeed_objects))
2550 return SimplePie::merge_items($this->multifeed_objects, $start, $end);
2552 elseif (!isset($this->data['items']))
2554 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2556 $keys = array_keys($items);
2557 foreach ($keys as $key)
2559 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2562 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2564 $keys = array_keys($items);
2565 foreach ($keys as $key)
2567 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2570 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2572 $keys = array_keys($items);
2573 foreach ($keys as $key)
2575 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2578 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2580 $keys = array_keys($items);
2581 foreach ($keys as $key)
2583 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2586 if ($items = $this->get_channel_tags('', 'item'))
2588 $keys = array_keys($items);
2589 foreach ($keys as $key)
2591 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2596 if (!empty($this->data['items']))
2598 // If we want to order it by date, check if all items have a date, and then sort it
2599 if ($this->order_by_date)
2601 if (!isset($this->data['ordered_items']))
2604 foreach ($this->data['items'] as $item)
2606 if (!$item->get_date('U'))
2613 $this->data['ordered_items'] = $this->data['items'];
2616 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2619 $items = $this->data['ordered_items'];
2623 $items = $this->data['items'];
2626 // Slice the data as desired
2629 return array_slice($items, $start);
2633 return array_slice($items, $start, $end);
2642 function sort_items($a, $b)
2644 return $a->get_date('U') <= $b->get_date('U');
2647 function merge_items($urls, $start = 0, $end = 0)
2649 if (is_array($urls) && sizeof($urls) > 0)
2652 foreach ($urls as $arg)
2654 if (SimplePie_Misc::is_a($arg, 'SimplePie'))
2656 $items = array_merge($items, $arg->get_items());
2660 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
2665 foreach ($items as $item)
2667 if (!$item->get_date('U'))
2676 usort($items, array('SimplePie', 'sort_items'));
2681 return array_slice($items, $start);
2685 return array_slice($items, $start, $end);
2690 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
2696 class SimplePie_Item
2699 var $data = array();
2701 function SimplePie_Item($feed, $data)
2703 $this->feed = $feed;
2704 $this->data = $data;
2707 function __toString()
2709 return md5(serialize($this->data));
2712 function get_item_tags($namespace, $tag)
2714 if (isset($this->data['child'][$namespace][$tag]))
2716 return $this->data['child'][$namespace][$tag];
2724 function get_base($element = array())
2726 return $this->feed->get_base($element);
2729 function sanitize($data, $type, $base = '')
2731 return $this->feed->sanitize($data, $type, $base);
2739 function get_id($hash = false)
2743 return $this->__toString();
2745 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
2747 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2749 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
2751 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2753 elseif ($return = $this->get_item_tags('', 'guid'))
2755 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2757 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
2759 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2761 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
2763 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2765 elseif (($return = $this->get_permalink()) !== null)
2769 elseif (($return = $this->get_title()) !== null)
2775 return $this->__toString();
2779 function get_title()
2781 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2783 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2785 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2787 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2789 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2791 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2793 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2795 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2797 elseif ($return = $this->get_item_tags('', 'title'))
2799 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2801 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2803 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2805 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2807 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2815 function get_description($description_only = false)
2817 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
2819 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2821 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
2823 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2825 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2827 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2829 elseif ($return = $this->get_item_tags('', 'description'))
2831 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2833 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2835 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2837 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2839 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2841 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2843 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2845 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2847 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2849 elseif (!$description_only)
2851 return $this->get_content(true);
2859 function get_content($content_only = false)
2861 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
2863 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2865 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
2867 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2869 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
2871 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2873 elseif (!$content_only)
2875 return $this->get_description(true);
2883 function get_category($key = 0)
2885 $categories = $this->get_categories();
2886 if (isset($categories[$key]))
2888 return $categories[$key];
2896 function get_categories()
2898 $categories = array();
2900 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2905 if (isset($category['attribs']['']['term']))
2907 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2909 if (isset($category['attribs']['']['scheme']))
2911 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2913 if (isset($category['attribs']['']['label']))
2915 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2917 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
2919 foreach ((array) $this->get_item_tags('', 'category') as $category)
2921 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2923 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2925 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2927 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2929 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2932 if (!empty($categories))
2934 return SimplePie_Misc::array_unique($categories);
2942 function get_author($key = 0)
2944 $authors = $this->get_authors();
2945 if (isset($authors[$key]))
2947 return $authors[$key];
2956 * @todo Atom inheritance (item author, source author, feed author)
2958 function get_authors()
2961 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2966 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2968 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2970 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2972 $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]));
2974 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2976 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2978 if ($name !== null || $email !== null || $uri !== null)
2980 $authors[] =& new $this->feed->author_class($name, $uri, $email);
2983 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2988 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2990 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2992 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2994 $uri = $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]));
2996 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2998 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3000 if ($name !== null || $email !== null || $uri !== null)
3002 $authors[] =& new $this->feed->author_class($name, $url, $email);
3005 if ($author = $this->get_item_tags('', 'author'))
3007 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3009 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3011 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3013 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3015 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3017 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3019 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3022 if (!empty($authors))
3024 return SimplePie_Misc::array_unique($authors);
3032 function get_date($date_format = 'j F Y, g:i a')
3034 if (!isset($this->data['date']))
3036 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3038 $this->data['date']['raw'] = $return[0]['data'];
3040 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3042 $this->data['date']['raw'] = $return[0]['data'];
3044 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3046 $this->data['date']['raw'] = $return[0]['data'];
3048 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3050 $this->data['date']['raw'] = $return[0]['data'];
3052 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3054 $this->data['date']['raw'] = $return[0]['data'];
3056 elseif ($return = $this->get_item_tags('', 'pubDate'))
3058 $this->data['date']['raw'] = $return[0]['data'];
3060 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3062 $this->data['date']['raw'] = $return[0]['data'];
3064 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3066 $this->data['date']['raw'] = $return[0]['data'];
3069 if (!empty($this->data['date']['raw']))
3071 $this->data['date']['parsed'] = SimplePie_Misc::parse_date($this->data['date']['raw']);
3075 $this->data['date'] = null;
3078 if ($this->data['date'])
3080 $date_format = (string) $date_format;
3081 switch ($date_format)
3084 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3087 return $this->data['date']['parsed'];
3090 return date($date_format, $this->data['date']['parsed']);
3099 function get_local_date($date_format = '%c')
3103 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3105 elseif (($date = $this->get_date('U')) !== null)
3107 return strftime($date_format, $date);
3115 function get_permalink()
3117 $link = $this->get_link();
3118 $enclosure = $this->get_enclosure(0);
3123 elseif ($enclosure !== null)
3125 return $enclosure->get_link();
3133 function get_link($key = 0, $rel = 'alternate')
3135 $links = $this->get_links($rel);
3136 if ($links[$key] !== null)
3138 return $links[$key];
3146 function get_links($rel = 'alternate')
3148 if (!isset($this->data['links']))
3150 $this->data['links'] = array();
3151 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3153 if (isset($link['attribs']['']['href']))
3155 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3156 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3160 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3162 if (isset($link['attribs']['']['href']))
3164 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3165 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3168 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3170 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3172 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3174 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3176 if ($links = $this->get_item_tags('', 'link'))
3178 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3180 if ($links = $this->get_item_tags('', 'guid'))
3182 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3184 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3188 $keys = array_keys($this->data['links']);
3189 foreach ($keys as $key)
3191 if (SimplePie_Misc::is_isegment_nz_nc($key))
3193 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3195 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3196 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3200 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3203 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3205 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3207 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3210 if (isset($this->data['links'][$rel]))
3212 return $this->data['links'][$rel];
3221 * @todo Add ability to prefer one type of content over another (in a media group).
3223 function get_enclosure($key = 0, $prefer = null)
3225 $enclosures = $this->get_enclosures();
3226 if (isset($enclosures[$key]))
3228 return $enclosures[$key];
3237 * Grabs all available enclosures (podcasts, etc.)
3239 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3241 * 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.
3243 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3244 * @todo Add support for itunes: tags. These should be relatively simple compared to media:.
3245 * @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).
3247 function get_enclosures()
3249 if (!isset($this->data['enclosures']))
3251 $this->data['enclosures'] = array();
3254 $captions_parent = null;
3255 $categories_parent = null;
3256 $copyrights_parent = null;
3257 $credits_parent = null;
3258 $description_parent = null;
3259 $duration_parent = null;
3260 $hashes_parent = null;
3261 $keywords_parent = null;
3262 $player_parent = null;
3263 $ratings_parent = null;
3264 $restrictions_parent = null;
3265 $thumbnails_parent = null;
3266 $title_parent = null;
3268 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3269 $parent = $this->get_feed();
3272 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3274 foreach ($captions as $caption)
3276 $caption_type = null;
3277 $caption_lang = null;
3278 $caption_startTime = null;
3279 $caption_endTime = null;
3280 $caption_text = null;
3281 if (isset($caption['attribs']['']['type']))
3283 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3285 if (isset($caption['attribs']['']['lang']))
3287 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3289 if (isset($caption['attribs']['']['start']))
3291 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3293 if (isset($caption['attribs']['']['end']))
3295 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3297 if (isset($caption['data']))
3299 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3301 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3304 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3306 foreach ($captions as $caption)
3308 $caption_type = null;
3309 $caption_lang = null;
3310 $caption_startTime = null;
3311 $caption_endTime = null;
3312 $caption_text = null;
3313 if (isset($caption['attribs']['']['type']))
3315 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3317 if (isset($caption['attribs']['']['lang']))
3319 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3321 if (isset($caption['attribs']['']['start']))
3323 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3325 if (isset($caption['attribs']['']['end']))
3327 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3329 if (isset($caption['data']))
3331 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3333 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3336 if (is_array($captions_parent))
3338 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3342 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3347 if (isset($category['data']))
3349 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3351 if (isset($category['attribs']['']['scheme']))
3353 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3357 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3359 if (isset($category['attribs']['']['label']))
3361 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3363 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3365 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3370 if (isset($category['data']))
3372 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3374 if (isset($category['attribs']['']['scheme']))
3376 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3380 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3382 if (isset($category['attribs']['']['label']))
3384 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3386 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3388 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3391 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3393 if (isset($category['attribs']['']['text']))
3395 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3397 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3399 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3401 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3403 if (isset($subcategory['attribs']['']['text']))
3405 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3407 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3411 if (is_array($categories_parent))
3413 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3417 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3419 $copyright_url = null;
3420 $copyright_label = null;
3421 if (isset($copyright[0]['attribs']['']['url']))
3423 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3425 if (isset($copyright[0]['data']))
3427 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3429 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3431 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3433 $copyright_url = null;
3434 $copyright_label = null;
3435 if (isset($copyright[0]['attribs']['']['url']))
3437 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3439 if (isset($copyright[0]['data']))
3441 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3443 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3447 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3449 foreach ($credits as $credit)
3451 $credit_role = null;
3452 $credit_scheme = null;
3453 $credit_name = null;
3454 if (isset($credit['attribs']['']['role']))
3456 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3458 if (isset($credit['attribs']['']['scheme']))
3460 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3464 $credit_scheme = 'urn:ebu';
3466 if (isset($credit['data']))
3468 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3470 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3473 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3475 foreach ($credits as $credit)
3477 $credit_role = null;
3478 $credit_scheme = null;
3479 $credit_name = null;
3480 if (isset($credit['attribs']['']['role']))
3482 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3484 if (isset($credit['attribs']['']['scheme']))
3486 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3490 $credit_scheme = 'urn:ebu';
3492 if (isset($credit['data']))
3494 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3496 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3499 if (is_array($credits_parent))
3501 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3505 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3507 if (isset($description_parent[0]['data']))
3509 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3512 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3514 if (isset($description_parent[0]['data']))
3516 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3521 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3526 if (isset($duration_parent[0]['data']))
3528 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3529 if (sizeof($temp) > 0)
3531 (int) $seconds = array_pop($temp);
3533 if (sizeof($temp) > 0)
3535 (int) $minutes = array_pop($temp);
3536 $seconds += $minutes * 60;
3538 if (sizeof($temp) > 0)
3540 (int) $hours = array_pop($temp);
3541 $seconds += $hours * 3600;
3544 $duration_parent = $seconds;
3549 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3551 foreach ($hashes_iterator as $hash)
3555 if (isset($hash['data']))
3557 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3559 if (isset($hash['attribs']['']['algo']))
3561 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3567 $hashes_parent[] = $algo.':'.$value;
3570 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3572 foreach ($hashes_iterator as $hash)
3576 if (isset($hash['data']))
3578 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3580 if (isset($hash['attribs']['']['algo']))
3582 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3588 $hashes_parent[] = $algo.':'.$value;
3591 if (is_array($hashes_parent))
3593 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
3597 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3599 if (isset($keywords[0]['data']))
3601 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3602 foreach ($temp as $word)
3604 $keywords_parent[] = trim($word);
3609 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3611 if (isset($keywords[0]['data']))
3613 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3614 foreach ($temp as $word)
3616 $keywords_parent[] = trim($word);
3621 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3623 if (isset($keywords[0]['data']))
3625 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3626 foreach ($temp as $word)
3628 $keywords_parent[] = trim($word);
3633 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3635 if (isset($keywords[0]['data']))
3637 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3638 foreach ($temp as $word)
3640 $keywords_parent[] = trim($word);
3645 if (is_array($keywords_parent))
3647 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
3651 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3653 if (isset($player_parent[0]['attribs']['']['url']))
3655 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3658 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3660 if (isset($player_parent[0]['attribs']['']['url']))
3662 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3667 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3669 foreach ($ratings as $rating)
3671 $rating_scheme = null;
3672 $rating_value = null;
3673 if (isset($rating['attribs']['']['scheme']))
3675 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3679 $rating_scheme = 'urn:simple';
3681 if (isset($rating['data']))
3683 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3685 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3688 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3690 foreach ($ratings as $rating)
3692 $rating_scheme = 'urn:itunes';
3693 $rating_value = null;
3694 if (isset($rating['data']))
3696 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3698 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3701 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3703 foreach ($ratings as $rating)
3705 $rating_scheme = null;
3706 $rating_value = null;
3707 if (isset($rating['attribs']['']['scheme']))
3709 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3713 $rating_scheme = 'urn:simple';
3715 if (isset($rating['data']))
3717 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3719 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3722 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3724 foreach ($ratings as $rating)
3726 $rating_scheme = 'urn:itunes';
3727 $rating_value = null;
3728 if (isset($rating['data']))
3730 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3732 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3735 if (is_array($ratings_parent))
3737 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
3741 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3743 foreach ($restrictions as $restriction)
3745 $restriction_relationship = null;
3746 $restriction_type = null;
3747 $restriction_value = null;
3748 if (isset($restriction['attribs']['']['relationship']))
3750 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3752 if (isset($restriction['attribs']['']['type']))
3754 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3756 if (isset($restriction['data']))
3758 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3760 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3763 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3765 foreach ($restrictions as $restriction)
3767 $restriction_relationship = 'allow';
3768 $restriction_type = null;
3769 $restriction_value = 'itunes';
3770 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3772 $restriction_relationship = 'deny';
3774 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3777 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3779 foreach ($restrictions as $restriction)
3781 $restriction_relationship = null;
3782 $restriction_type = null;
3783 $restriction_value = null;
3784 if (isset($restriction['attribs']['']['relationship']))
3786 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3788 if (isset($restriction['attribs']['']['type']))
3790 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3792 if (isset($restriction['data']))
3794 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3796 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3799 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3801 foreach ($restrictions as $restriction)
3803 $restriction_relationship = 'allow';
3804 $restriction_type = null;
3805 $restriction_value = 'itunes';
3806 if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3808 $restriction_relationship = 'deny';
3810 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3813 if (is_array($restrictions_parent))
3815 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
3819 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3821 foreach ($thumbnails as $thumbnail)
3823 if (isset($thumbnail['attribs']['']['url']))
3825 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3829 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3831 foreach ($thumbnails as $thumbnail)
3833 if (isset($thumbnail['attribs']['']['url']))
3835 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3841 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3843 if (isset($title_parent[0]['data']))
3845 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3848 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3850 if (isset($title_parent[0]['data']))
3852 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3859 // If we have media:group tags, loop through them.
3860 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
3862 // If we have media:content tags, loop through them.
3863 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
3865 if (isset($content['attribs']['']['url']))
3878 $samplingrate = null;
3888 $description = null;
3893 $restrictions = null;
3897 // Start checking the attributes of media:content
3898 if (isset($content['attribs']['']['bitrate']))
3900 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3902 if (isset($content['attribs']['']['channels']))
3904 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
3906 if (isset($content['attribs']['']['duration']))
3908 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
3912 $duration = $duration_parent;
3914 if (isset($content['attribs']['']['expression']))
3916 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
3918 if (isset($content['attribs']['']['framerate']))
3920 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
3922 if (isset($content['attribs']['']['height']))
3924 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
3926 if (isset($content['attribs']['']['lang']))
3928 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3930 if (isset($content['attribs']['']['fileSize']))
3932 $length = ceil($content['attribs']['']['fileSize']);
3934 if (isset($content['attribs']['']['medium']))
3936 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
3938 if (isset($content['attribs']['']['samplingrate']))
3940 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3942 if (isset($content['attribs']['']['type']))
3944 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3946 if (isset($content['attribs']['']['width']))
3948 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
3950 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3952 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
3955 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3957 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3959 $caption_type = null;
3960 $caption_lang = null;
3961 $caption_startTime = null;
3962 $caption_endTime = null;
3963 $caption_text = null;
3964 if (isset($caption['attribs']['']['type']))
3966 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3968 if (isset($caption['attribs']['']['lang']))
3970 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3972 if (isset($caption['attribs']['']['start']))
3974 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3976 if (isset($caption['attribs']['']['end']))
3978 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3980 if (isset($caption['data']))
3982 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3984 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3986 if (is_array($captions))
3988 $captions = array_values(SimplePie_Misc::array_unique($captions));
3991 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3993 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3995 $caption_type = null;
3996 $caption_lang = null;
3997 $caption_startTime = null;
3998 $caption_endTime = null;
3999 $caption_text = null;
4000 if (isset($caption['attribs']['']['type']))
4002 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4004 if (isset($caption['attribs']['']['lang']))
4006 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4008 if (isset($caption['attribs']['']['start']))
4010 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4012 if (isset($caption['attribs']['']['end']))
4014 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4016 if (isset($caption['data']))
4018 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4020 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4022 if (is_array($captions))
4024 $captions = array_values(SimplePie_Misc::array_unique($captions));
4029 $captions = $captions_parent;
4033 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4035 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4040 if (isset($category['data']))
4042 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4044 if (isset($category['attribs']['']['scheme']))
4046 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4050 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4052 if (isset($category['attribs']['']['label']))
4054 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4056 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4059 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4061 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4066 if (isset($category['data']))
4068 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4070 if (isset($category['attribs']['']['scheme']))
4072 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4076 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4078 if (isset($category['attribs']['']['label']))
4080 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4082 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4085 if (is_array($categories) && is_array($categories_parent))
4087 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4089 elseif (is_array($categories))
4091 $categories = array_values(SimplePie_Misc::array_unique($categories));
4093 elseif (is_array($categories_parent))
4095 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4099 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4101 $copyright_url = null;
4102 $copyright_label = null;
4103 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4105 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4107 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4109 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4111 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4113 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4115 $copyright_url = null;
4116 $copyright_label = null;
4117 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4119 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4121 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4123 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4125 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4129 $copyrights = $copyrights_parent;
4133 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4135 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4137 $credit_role = null;
4138 $credit_scheme = null;
4139 $credit_name = null;
4140 if (isset($credit['attribs']['']['role']))
4142 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4144 if (isset($credit['attribs']['']['scheme']))
4146 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4150 $credit_scheme = 'urn:ebu';
4152 if (isset($credit['data']))
4154 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4156 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4158 if (is_array($credits))
4160 $credits = array_values(SimplePie_Misc::array_unique($credits));
4163 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4165 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4167 $credit_role = null;
4168 $credit_scheme = null;
4169 $credit_name = null;
4170 if (isset($credit['attribs']['']['role']))
4172 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4174 if (isset($credit['attribs']['']['scheme']))
4176 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4180 $credit_scheme = 'urn:ebu';
4182 if (isset($credit['data']))
4184 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4186 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4188 if (is_array($credits))
4190 $credits = array_values(SimplePie_Misc::array_unique($credits));
4195 $credits = $credits_parent;
4199 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4201 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4203 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4205 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4209 $description = $description_parent;
4213 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4215 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4219 if (isset($hash['data']))
4221 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4223 if (isset($hash['attribs']['']['algo']))
4225 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4231 $hashes[] = $algo.':'.$value;
4233 if (is_array($hashes))
4235 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4238 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4240 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4244 if (isset($hash['data']))
4246 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4248 if (isset($hash['attribs']['']['algo']))
4250 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4256 $hashes[] = $algo.':'.$value;
4258 if (is_array($hashes))
4260 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4265 $hashes = $hashes_parent;
4269 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4271 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4273 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4274 foreach ($temp as $word)
4276 $keywords[] = trim($word);
4280 if (is_array($keywords))
4282 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4285 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4287 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4289 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4290 foreach ($temp as $word)
4292 $keywords[] = trim($word);
4296 if (is_array($keywords))
4298 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4303 $keywords = $keywords_parent;
4307 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4309 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4311 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4313 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4317 $player = $player_parent;
4321 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4323 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4325 $rating_scheme = null;
4326 $rating_value = null;
4327 if (isset($rating['attribs']['']['scheme']))
4329 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4333 $rating_scheme = 'urn:simple';
4335 if (isset($rating['data']))
4337 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4339 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4341 if (is_array($ratings))
4343 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4346 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4348 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4350 $rating_scheme = null;
4351 $rating_value = null;
4352 if (isset($rating['attribs']['']['scheme']))
4354 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4358 $rating_scheme = 'urn:simple';
4360 if (isset($rating['data']))
4362 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4364 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4366 if (is_array($ratings))
4368 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4373 $ratings = $ratings_parent;
4377 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4379 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4381 $restriction_relationship = null;
4382 $restriction_type = null;
4383 $restriction_value = null;
4384 if (isset($restriction['attribs']['']['relationship']))
4386 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4388 if (isset($restriction['attribs']['']['type']))
4390 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4392 if (isset($restriction['data']))
4394 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4396 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4398 if (is_array($restrictions))
4400 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4403 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4405 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4407 $restriction_relationship = null;
4408 $restriction_type = null;
4409 $restriction_value = null;
4410 if (isset($restriction['attribs']['']['relationship']))
4412 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4414 if (isset($restriction['attribs']['']['type']))
4416 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4418 if (isset($restriction['data']))
4420 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4422 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4424 if (is_array($restrictions))
4426 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4431 $restrictions = $restrictions_parent;
4435 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4437 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4439 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4441 if (is_array($thumbnails))
4443 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4446 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4448 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4450 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4452 if (is_array($thumbnails))
4454 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4459 $thumbnails = $thumbnails_parent;
4463 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4465 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4467 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4469 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4473 $title = $title_parent;
4476 $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);
4481 // If we have standalone media:content tags, loop through them.
4482 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4484 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4486 if (isset($content['attribs']['']['url']))
4499 $samplingrate = null;
4509 $description = null;
4514 $restrictions = null;
4518 // Start checking the attributes of media:content
4519 if (isset($content['attribs']['']['bitrate']))
4521 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4523 if (isset($content['attribs']['']['channels']))
4525 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4527 if (isset($content['attribs']['']['duration']))
4529 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4533 $duration = $duration_parent;
4535 if (isset($content['attribs']['']['expression']))
4537 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4539 if (isset($content['attribs']['']['framerate']))
4541 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4543 if (isset($content['attribs']['']['height']))
4545 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4547 if (isset($content['attribs']['']['lang']))
4549 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4551 if (isset($content['attribs']['']['fileSize']))
4553 $length = ceil($content['attribs']['']['fileSize']);
4555 if (isset($content['attribs']['']['medium']))
4557 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4559 if (isset($content['attribs']['']['samplingrate']))
4561 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4563 if (isset($content['attribs']['']['type']))
4565 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4567 if (isset($content['attribs']['']['width']))
4569 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4571 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4573 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4576 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4578 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4580 $caption_type = null;
4581 $caption_lang = null;
4582 $caption_startTime = null;
4583 $caption_endTime = null;
4584 $caption_text = null;
4585 if (isset($caption['attribs']['']['type']))
4587 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4589 if (isset($caption['attribs']['']['lang']))
4591 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4593 if (isset($caption['attribs']['']['start']))
4595 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4597 if (isset($caption['attribs']['']['end']))
4599 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4601 if (isset($caption['data']))
4603 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4605 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4607 if (is_array($captions))
4609 $captions = array_values(SimplePie_Misc::array_unique($captions));
4614 $captions = $captions_parent;
4618 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4620 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4625 if (isset($category['data']))
4627 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4629 if (isset($category['attribs']['']['scheme']))
4631 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4635 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4637 if (isset($category['attribs']['']['label']))
4639 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4641 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4644 if (is_array($categories) && is_array($categories_parent))
4646 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4648 elseif (is_array($categories))
4650 $categories = array_values(SimplePie_Misc::array_unique($categories));
4652 elseif (is_array($categories_parent))
4654 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4662 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4664 $copyright_url = null;
4665 $copyright_label = null;
4666 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4668 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4670 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4672 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4674 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4678 $copyrights = $copyrights_parent;
4682 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4684 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4686 $credit_role = null;
4687 $credit_scheme = null;
4688 $credit_name = null;
4689 if (isset($credit['attribs']['']['role']))
4691 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4693 if (isset($credit['attribs']['']['scheme']))
4695 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4699 $credit_scheme = 'urn:ebu';
4701 if (isset($credit['data']))
4703 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4705 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4707 if (is_array($credits))
4709 $credits = array_values(SimplePie_Misc::array_unique($credits));
4714 $credits = $credits_parent;
4718 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4720 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4724 $description = $description_parent;
4728 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4730 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4734 if (isset($hash['data']))
4736 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4738 if (isset($hash['attribs']['']['algo']))
4740 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4746 $hashes[] = $algo.':'.$value;
4748 if (is_array($hashes))
4750 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4755 $hashes = $hashes_parent;
4759 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4761 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4763 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4764 foreach ($temp as $word)
4766 $keywords[] = trim($word);
4770 if (is_array($keywords))
4772 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4777 $keywords = $keywords_parent;
4781 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4783 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4787 $player = $player_parent;
4791 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4793 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4795 $rating_scheme = null;
4796 $rating_value = null;
4797 if (isset($rating['attribs']['']['scheme']))
4799 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4803 $rating_scheme = 'urn:simple';
4805 if (isset($rating['data']))
4807 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4809 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4811 if (is_array($ratings))
4813 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4818 $ratings = $ratings_parent;
4822 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4824 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4826 $restriction_relationship = null;
4827 $restriction_type = null;
4828 $restriction_value = null;
4829 if (isset($restriction['attribs']['']['relationship']))
4831 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4833 if (isset($restriction['attribs']['']['type']))
4835 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4837 if (isset($restriction['data']))
4839 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4841 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4843 if (is_array($restrictions))
4845 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4850 $restrictions = $restrictions_parent;
4854 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4856 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4858 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4860 if (is_array($thumbnails))
4862 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4867 $thumbnails = $thumbnails_parent;
4871 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4873 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4877 $title = $title_parent;
4880 $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);
4885 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
4887 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4900 $samplingrate = null;
4905 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4906 if (isset($link['attribs']['']['type']))
4908 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4910 if (isset($link['attribs']['']['length']))
4912 $length = ceil($link['attribs']['']['length']);
4915 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4916 $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);
4920 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
4922 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4935 $samplingrate = null;
4940 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4941 if (isset($link['attribs']['']['type']))
4943 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4945 if (isset($link['attribs']['']['length']))
4947 $length = ceil($link['attribs']['']['length']);
4950 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4951 $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);
4955 if ($enclosure = $this->get_item_tags('', 'enclosure'))
4957 if (isset($enclosure[0]['attribs']['']['url']))
4970 $samplingrate = null;
4975 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
4976 if (isset($enclosure[0]['attribs']['']['type']))
4978 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4980 if (isset($enclosure[0]['attribs']['']['length']))
4982 $length = ceil($enclosure[0]['attribs']['']['length']);
4985 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4986 $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);
4989 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
4991 if (!empty($this->data['enclosures']))
4993 return $this->data['enclosures'];
5001 function get_latitude()
5003 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5005 return (float) $return[0]['data'];
5007 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5009 return (float) $match[1];
5017 function get_longitude()
5019 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5021 return (float) $return[0]['data'];
5023 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5025 return (float) $return[0]['data'];
5027 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5029 return (float) $match[2];
5038 * Creates the add_to_* methods' return data
5041 * @param string $item_url String to prefix to the item permalink
5042 * @param string $title_url String to prefix to the item title
5043 * (and suffix to the item permalink)
5044 * @return mixed URL if feed exists, false otherwise
5046 function add_to_service($item_url, $title_url = null)
5048 if ($this->get_permalink() !== null)
5050 $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5051 if ($title_url !== null && $this->get_title() !== null)
5053 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5063 function add_to_blinklist()
5065 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5068 function add_to_blogmarks()
5070 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5073 function add_to_delicious()
5075 return $this->add_to_service('http://del.icio.us/post/?v=3&url=', '&title=');
5078 function add_to_digg()
5080 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5083 function add_to_furl()
5085 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5088 function add_to_magnolia()
5090 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5093 function add_to_myweb20()
5095 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5098 function add_to_newsvine()
5100 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5103 function add_to_reddit()
5105 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5108 function add_to_segnalo()
5110 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5113 function add_to_simpy()
5115 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5118 function add_to_spurl()
5120 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5123 function add_to_wists()
5125 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5128 function search_technorati()
5130 return $this->add_to_service('http://www.technorati.com/search/');
5134 class SimplePie_Author
5140 // Constructor, used to input the data
5141 function SimplePie_Author($name = null, $link = null, $email = null)
5143 $this->name = $name;
5144 $this->link = $link;
5145 $this->email = $email;
5148 function __toString()
5150 // There is no $this->data here
5151 return md5(serialize($this));
5156 if ($this->name !== null)
5168 if ($this->link !== null)
5178 function get_email()
5180 if ($this->email !== null)
5182 return $this->email;
5191 class SimplePie_Category
5197 // Constructor, used to input the data
5198 function SimplePie_Category($term = null, $scheme = null, $label = null)
5200 $this->term = $term;
5201 $this->scheme = $scheme;
5202 $this->label = $label;
5205 function __toString()
5207 // There is no $this->data here
5208 return md5(serialize($this));
5213 if ($this->term !== null)
5223 function get_scheme()
5225 if ($this->scheme !== null)
5227 return $this->scheme;
5235 function get_label()
5237 if ($this->label !== null)
5239 return $this->label;
5243 return $this->get_term();
5248 class SimplePie_Enclosure
5278 // Constructor, used to input the data
5279 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)
5281 $this->bitrate = $bitrate;
5282 $this->captions = $captions;
5283 $this->categories = $categories;
5284 $this->channels = $channels;
5285 $this->copyright = $copyright;
5286 $this->credits = $credits;
5287 $this->description = $description;
5288 $this->duration = $duration;
5289 $this->expression = $expression;
5290 $this->framerate = $framerate;
5291 $this->hashes = $hashes;
5292 $this->height = $height;
5293 $this->javascript = $javascript;
5294 $this->keywords = $keywords;
5295 $this->lang = $lang;
5296 $this->length = $length;
5297 $this->link = $link;
5298 $this->medium = $medium;
5299 $this->player = $player;
5300 $this->ratings = $ratings;
5301 $this->restrictions = $restrictions;
5302 $this->samplingrate = $samplingrate;
5303 $this->thumbnails = $thumbnails;
5304 $this->title = $title;
5305 $this->type = $type;
5306 $this->width = $width;
5307 if (class_exists('idna_convert'))
5309 $idn =& new idna_convert;
5310 $parsed = SimplePie_Misc::parse_url($link);
5311 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
5313 $this->handler = $this->get_handler(); // Needs to load last
5316 function __toString()
5318 // There is no $this->data here
5319 return md5(serialize($this));
5322 function get_bitrate()
5324 if ($this->bitrate !== null)
5326 return $this->bitrate;
5334 function get_caption($key = 0)
5336 $captions = $this->get_captions();
5337 if (isset($captions[$key]))
5339 return $captions[$key];
5347 function get_captions()
5349 if ($this->captions !== null)
5351 return $this->captions;
5359 function get_category($key = 0)
5361 $categories = $this->get_categories();
5362 if (isset($categories[$key]))
5364 return $categories[$key];
5372 function get_categories()
5374 if ($this->categories !== null)
5376 return $this->categories;
5384 function get_channels()
5386 if ($this->channels !== null)
5388 return $this->channels;
5396 function get_copyright()
5398 if ($this->copyright !== null)
5400 return $this->copyright;
5408 function get_credit($key = 0)
5410 $credits = $this->get_credits();
5411 if (isset($credits[$key]))
5413 return $credits[$key];
5421 function get_credits()
5423 if ($this->credits !== null)
5425 return $this->credits;
5433 function get_description()
5435 if ($this->description !== null)
5437 return $this->description;
5445 function get_duration($convert = false)
5447 if ($this->duration !== null)
5451 $time = SimplePie_Misc::time_hms($this->duration);
5456 return $this->duration;
5465 function get_expression()
5467 if ($this->expression !== null)
5469 return $this->expression;
5477 function get_extension()
5479 if ($this->link !== null)
5481 $url = SimplePie_Misc::parse_url($this->link);
5482 if ($url['path'] !== '')
5484 return pathinfo($url['path'], PATHINFO_EXTENSION);
5490 function get_framerate()
5492 if ($this->framerate !== null)
5494 return $this->framerate;
5502 function get_handler()
5504 return $this->get_real_type(true);
5507 function get_hash($key = 0)
5509 $hashes = $this->get_hashes();
5510 if (isset($hashes[$key]))
5512 return $hashes[$key];
5520 function get_hashes()
5522 if ($this->hashes !== null)
5524 return $this->hashes;
5532 function get_height()
5534 if ($this->height !== null)
5536 return $this->height;
5544 function get_language()
5546 if ($this->lang !== null)
5556 function get_keyword($key = 0)
5558 $keywords = $this->get_keywords();
5559 if (isset($keywords[$key]))
5561 return $keywords[$key];
5569 function get_keywords()
5571 if ($this->keywords !== null)
5573 return $this->keywords;
5581 function get_length()
5583 if ($this->length !== null)
5585 return $this->length;
5595 if ($this->link !== null)
5597 return urldecode($this->link);
5605 function get_medium()
5607 if ($this->medium !== null)
5609 return $this->medium;
5617 function get_player()
5619 if ($this->player !== null)
5621 return $this->player;
5629 function get_rating($key = 0)
5631 $ratings = $this->get_ratings();
5632 if (isset($ratings[$key]))
5634 return $ratings[$key];
5642 function get_ratings()
5644 if ($this->ratings !== null)
5646 return $this->ratings;
5654 function get_restriction($key = 0)
5656 $restrictions = $this->get_restrictions();
5657 if (isset($restrictions[$key]))
5659 return $restrictions[$key];
5667 function get_restrictions()
5669 if ($this->restrictions !== null)
5671 return $this->restrictions;
5679 function get_sampling_rate()
5681 if ($this->samplingrate !== null)
5683 return $this->samplingrate;
5693 $length = $this->get_length();
5694 if ($length !== null)
5696 return round($length/1048576, 2);
5704 function get_thumbnail($key = 0)
5706 $thumbnails = $this->get_thumbnails();
5707 if (isset($thumbnails[$key]))
5709 return $thumbnails[$key];
5717 function get_thumbnails()
5719 if ($this->thumbnails !== null)
5721 return $this->thumbnails;
5729 function get_title()
5731 if ($this->title !== null)
5733 return $this->title;
5743 if ($this->type !== null)
5753 function get_width()
5755 if ($this->width !== null)
5757 return $this->width;
5765 function native_embed($options='')
5767 return $this->embed($options, true);
5771 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
5773 function embed($options = '', $native = false)
5783 $bgcolor = '#ffffff';
5785 $widescreen = false;
5786 $handler = $this->get_handler();
5787 $type = $this->get_real_type();
5789 // Process options and reassign values as necessary
5790 if (is_array($options))
5796 $options = explode(',', $options);
5797 foreach($options as $option)
5799 $opt = explode(':', $option, 2);
5800 if (isset($opt[0], $opt[1]))
5802 $opt[0] = trim($opt[0]);
5803 $opt[1] = trim($opt[1]);
5819 $altclass = $opt[1];
5839 $mediaplayer = $opt[1];
5843 $widescreen = $opt[1];
5850 $mime = explode('/', $type, 2);
5853 // Process values for 'auto'
5854 if ($width == 'auto')
5856 if ($mime == 'video')
5858 if ($height == 'auto')
5862 elseif ($widescreen)
5864 $width = round((intval($height)/9)*16);
5868 $width = round((intval($height)/3)*4);
5877 if ($height == 'auto')
5879 if ($mime == 'audio')
5883 elseif ($mime == 'video')
5885 if ($width == 'auto')
5896 elseif ($widescreen)
5898 $height = round((intval($width)/16)*9);
5902 $height = round((intval($width)/4)*3);
5910 elseif ($mime == 'audio')
5915 // Set proper placeholder value
5916 if ($mime == 'audio')
5918 $placeholder = $audio;
5920 elseif ($mime == 'video')
5922 $placeholder = $video;
5927 // Make sure the JS library is included
5930 static $javascript_outputted = null;
5931 if (!$javascript_outputted && $this->javascript)
5933 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
5934 $javascript_outputted = true;
5939 if ($handler == 'odeo')
5943 $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>';
5947 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
5952 elseif ($handler == 'flash')
5956 $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>";
5960 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
5964 // Flash Media Player file types.
5965 // Preferred handler for MP3 file types.
5966 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
5971 $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>";
5975 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
5979 // QuickTime 7 file types. Need to test with QuickTime 6.
5980 // Only handle MP3's if the Flash Media Player is not present.
5981 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
5986 if ($placeholder != ""){
5987 $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>";
5990 $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>";
5995 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
6000 elseif ($handler == 'wmedia')
6005 $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>";
6009 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
6014 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
6019 function get_real_type($find_handler = false)
6021 // If it's Odeo, let's get it out of the way.
6022 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
6027 // Mime-types by handler.
6028 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
6029 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
6030 $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
6031 $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
6032 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
6034 if ($this->get_type() !== null)
6036 $type = strtolower($this->type);
6043 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
6044 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
6046 switch (strtolower($this->get_extension()))
6051 $type = 'audio/acc';
6058 $type = 'audio/aiff';
6062 $type = 'audio/wav';
6069 $type = 'audio/midi';
6073 $type = 'audio/x-m4a';
6078 $type = 'audio/mp3';
6082 $type = 'audio/wav';
6086 $type = 'audio/x-ms-wax';
6090 $type = 'audio/x-ms-wma';
6096 $type = 'video/3gpp';
6101 $type = 'video/3gpp2';
6105 $type = 'video/x-ms-asf';
6109 $type = 'video/x-flv';
6123 $type = 'video/mpeg';
6127 $type = 'video/x-m4v';
6132 $type = 'video/quicktime';
6137 $type = 'video/mp4';
6141 $type = 'video/sd-video';
6145 $type = 'video/x-ms-wm';
6149 $type = 'video/x-ms-wmv';
6153 $type = 'video/x-ms-wvx';
6158 $type = 'application/futuresplash';
6162 $type = 'application/x-shockwave-flash';
6169 if (in_array($type, $types_flash))
6173 elseif (in_array($type, $types_fmedia))
6177 elseif (in_array($type, $types_quicktime))
6181 elseif (in_array($type, $types_wmedia))
6185 elseif (in_array($type, $types_mp3))
6201 class SimplePie_Caption
6209 // Constructor, used to input the data
6210 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
6212 $this->type = $type;
6213 $this->lang = $lang;
6214 $this->startTime = $startTime;
6215 $this->endTime = $endTime;
6216 $this->text = $text;
6219 function __toString()
6221 // There is no $this->data here
6222 return md5(serialize($this));
6225 function get_endtime()
6227 if ($this->endTime !== null)
6229 return $this->endTime;
6237 function get_language()
6239 if ($this->language !== null)
6241 return $this->language;
6249 function get_starttime()
6251 if ($this->startTime !== null)
6253 return $this->startTime;
6263 if ($this->text !== null)
6275 if ($this->type !== null)
6286 class SimplePie_Credit
6292 // Constructor, used to input the data
6293 function SimplePie_Credit($role = null, $scheme = null, $name = null)
6295 $this->role = $role;
6296 $this->scheme = $scheme;
6297 $this->name = $name;
6300 function __toString()
6302 // There is no $this->data here
6303 return md5(serialize($this));
6308 if ($this->role !== null)
6318 function get_scheme()
6320 if ($this->scheme !== null)
6322 return $this->scheme;
6332 if ($this->name !== null)
6343 class SimplePie_Copyright
6348 // Constructor, used to input the data
6349 function SimplePie_Copyright($url = null, $label = null)
6352 $this->label = $label;
6355 function __toString()
6357 // There is no $this->data here
6358 return md5(serialize($this));
6363 if ($this->url !== null)
6373 function get_attribution()
6375 if ($this->label !== null)
6377 return $this->label;
6386 class SimplePie_Rating
6391 // Constructor, used to input the data
6392 function SimplePie_Rating($scheme = null, $value = null)
6394 $this->scheme = $scheme;
6395 $this->value = $value;
6398 function __toString()
6400 // There is no $this->data here
6401 return md5(serialize($this));
6404 function get_scheme()
6406 if ($this->scheme !== null)
6408 return $this->scheme;
6416 function get_value()
6418 if ($this->value !== null)
6420 return $this->value;
6429 class SimplePie_Restriction
6435 // Constructor, used to input the data
6436 function SimplePie_Restriction($relationship = null, $type = null, $value = null)
6438 $this->relationship = $relationship;
6439 $this->type = $type;
6440 $this->value = $value;
6443 function __toString()
6445 // There is no $this->data here
6446 return md5(serialize($this));
6449 function get_relationship()
6451 if ($this->relationship !== null)
6453 return $this->relationship;
6463 if ($this->type !== null)
6473 function get_value()
6475 if ($this->value !== null)
6477 return $this->value;
6487 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
6489 class SimplePie_File
6493 var $success = true;
6494 var $headers = array();
6501 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
6503 if (class_exists('idna_convert'))
6505 $idn =& new idna_convert;
6506 $parsed = SimplePie_Misc::parse_url($url);
6507 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6510 $this->useragent = $useragent;
6511 if (preg_match('/^http(s)?:\/\//i', $url))
6513 if ($useragent === null)
6515 $useragent = ini_get('user_agent');
6516 $this->useragent = $useragent;
6518 if (!is_array($headers))
6522 if (!$force_fsockopen && extension_loaded('curl'))
6524 $this->method = 'curl';
6526 $headers2 = array();
6527 foreach ($headers as $key => $value)
6529 $headers2[] = "$key: $value";
6531 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
6533 curl_setopt($fp, CURLOPT_ENCODING, '');
6535 curl_setopt($fp, CURLOPT_URL, $url);
6536 curl_setopt($fp, CURLOPT_HEADER, 1);
6537 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
6538 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
6539 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
6540 curl_setopt($fp, CURLOPT_REFERER, $url);
6541 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
6542 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
6543 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
6545 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
6546 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
6549 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
6550 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
6552 $this->headers = curl_exec($fp);
6553 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
6555 curl_setopt($fp, CURLOPT_ENCODING, 'none');
6556 $this->headers = curl_exec($fp);
6558 if (curl_errno($fp))
6560 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
6561 $this->success = false;
6565 $info = curl_getinfo($fp);
6567 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
6568 $this->headers = array_pop($this->headers);
6569 $parser =& new SimplePie_HTTP_Parser($this->headers);
6570 if ($parser->parse())
6572 $this->headers = $parser->headers;
6573 $this->body = $parser->body;
6574 $this->status_code = $parser->status_code;
6575 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)
6578 if (isset($this->headers['content-location']))
6580 $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6584 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6586 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6593 $this->method = 'fsockopen';
6594 $url_parts = parse_url($url);
6595 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
6597 $url_parts['host'] = "ssl://$url_parts[host]";
6598 $url_parts['port'] = 443;
6600 if (!isset($url_parts['port']))
6602 $url_parts['port'] = 80;
6604 $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
6607 $this->error = 'fsockopen error: ' . $errstr;
6608 $this->success = false;
6612 if (function_exists('stream_set_timeout'))
6614 stream_set_timeout($fp, $timeout);
6618 socket_set_timeout($fp, $timeout);
6620 if (isset($url_parts['path']))
6622 if (isset($url_parts['query']))
6624 $get = "$url_parts[path]?$url_parts[query]";
6628 $get = $url_parts['path'];
6635 $out = "GET $get HTTP/1.0\r\n";
6636 $out .= "Host: $url_parts[host]\r\n";
6637 $out .= "User-Agent: $useragent\r\n";
6638 if (function_exists('gzinflate'))
6640 $out .= "Accept-Encoding: gzip,deflate\r\n";
6643 if (isset($url_parts['user']) && isset($url_parts['pass']))
6645 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
6647 foreach ($headers as $key => $value)
6649 $out .= "$key: $value\r\n";
6651 $out .= "Connection: Close\r\n\r\n";
6654 if (function_exists('stream_get_meta_data'))
6656 $info = stream_get_meta_data($fp);
6660 $info = socket_get_status($fp);
6663 $this->headers = '';
6664 while (!$info['eof'] && !$info['timed_out'])
6666 $this->headers .= fread($fp, 1160);
6667 if (function_exists('stream_get_meta_data'))
6669 $info = stream_get_meta_data($fp);
6673 $info = socket_get_status($fp);
6676 if (!$info['timed_out'])
6678 $parser =& new SimplePie_HTTP_Parser($this->headers);
6679 if ($parser->parse())
6681 $this->headers = $parser->headers;
6682 $this->body = $parser->body;
6683 $this->status_code = $parser->status_code;
6684 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)
6687 if (isset($this->headers['content-location']))
6689 $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6693 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6695 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6697 if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
6699 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
6701 $this->body = substr($this->body, 10);
6703 $this->body = gzinflate($this->body);
6709 $this->error = 'fsocket timed out';
6710 $this->success = false;
6716 elseif (function_exists('file_get_contents'))
6718 $this->method = 'file_get_contents';
6719 if (!$this->body = file_get_contents($url))
6721 $this->error = 'file_get_contents could not read the file';
6722 $this->success = false;
6727 $this->method = 'fopen';
6728 if (($fp = fopen($url, 'rb')) === false)
6730 $this->error = 'failed to open stream: No such file or directory';
6731 $this->success = false;
6738 $this->body .= fread($fp, 8192);
6747 * HTTP Response Parser
6749 * @package SimplePie
6750 * @todo Support HTTP Requests
6752 class SimplePie_HTTP_Parser
6760 var $http_version = '';
6768 var $status_code = '';
6779 * Key/value pairs of the headers
6784 var $headers = array();
6787 * Body of the response
6795 * Current state of the state machine
6800 var $state = 'start';
6811 * Input data length (to avoid calling strlen() everytime this is needed)
6816 var $data_length = 0;
6819 * Current position of the pointer
6827 * Name of the hedaer currently being parsed
6835 * Value of the hedaer currently being parsed
6843 * Create an instance of the class with the input data
6846 * @param string $data Input data
6848 function SimplePie_HTTP_Parser($data)
6850 $this->data = $data;
6851 $this->data_length = strlen($this->data);
6855 * Parse the input data
6858 * @return bool true on success, false on failure
6862 while ($this->state && $this->state != 'emit' && $this->has_data())
6864 $state = $this->state;
6868 if ($this->state == 'emit')
6874 $this->http_version = '';
6875 $this->status_code = '';
6876 $this->headers = array();
6883 * Check whether there is data beyond the pointer
6886 * @return bool true if there is further data, false if not
6890 return (bool) ($this->position < $this->data_length);
6894 * See if the next character is LWS
6897 * @return bool true if the next character is LWS, false if not
6899 function is_linear_whitespace()
6901 return (bool) (strspn($this->data, "\x09\x20", $this->position, 1)
6902 || (substr($this->data, $this->position, 2) == "\r\n" && strspn($this->data, "\x09\x20", $this->position + 2, 1))
6903 || (strspn($this->data, "\r\n", $this->position, 1) && strspn($this->data, "\x09\x20", $this->position + 1, 1)));
6907 * The starting state of the state machine, see if the data is a response or request
6913 $this->state = 'http_version_response';
6917 * Parse an HTTP-version string
6921 function http_version()
6923 if (preg_match('/^HTTP\/([0-9]+\.[0-9]+)/i', substr($this->data, $this->position, strcspn($this->data, "\r\n", $this->position)), $match))
6925 $this->position += strlen($match[0]);
6926 $this->http_version = $match[1];
6936 * Parse LWS, replacing consecutive characters with a single space
6940 function linear_whitespace()
6944 if (substr($this->data, $this->position, 2) == "\r\n")
6946 $this->position += 2;
6948 elseif (strspn($this->data, "\r\n", $this->position, 1))
6952 $this->position += strspn($this->data, "\x09\x20", $this->position);
6953 } while ($this->is_linear_whitespace());
6954 $this->value .= "\x20";
6958 * Parse an HTTP-version string within a response
6962 function http_version_response()
6964 if ($this->http_version() && $this->data[$this->position] == "\x20")
6966 $this->state = 'status_code';
6971 $this->state = false;
6976 * Parse a status code
6980 function status_code()
6982 if (strspn($this->data, '1234567890', $this->position, 3) == 3)
6984 $this->status_code = substr($this->data, $this->position, 3);
6985 $this->state = 'reason_phrase';
6986 $this->position += 3;
6990 $this->state = false;
6995 * Skip over the reason phrase (it has no normative value, and you can send absolutely anything here)
6999 function reason_phrase()
7001 $len = strcspn($this->data, "\r\n", $this->position);
7002 $this->reason = substr($this->data, $this->position, $len);
7003 $this->position += $len;
7004 if ($this->has_data())
7006 if (substr($this->data, $this->position, 2) == "\r\n")
7008 $this->position += 2;
7010 elseif (strspn($this->data, "\r\n", $this->position, 1))
7014 $this->state = 'name';
7019 * Parse a header name
7025 $len = strcspn($this->data, ':', $this->position);
7026 $this->name = substr($this->data, $this->position, $len);
7027 $this->position += $len;
7029 if ($this->has_data() && $this->data[$this->position] == ':')
7031 $this->state = 'value_next';
7036 $this->state = false;
7041 * See what state to move the state machine to while within non-quoted header values
7045 function value_next()
7047 if ($this->is_linear_whitespace())
7049 $this->state = 'value_linear_whitespace';
7051 elseif ($this->data[$this->position] == '"')
7053 $this->state = 'value_quote_next';
7056 elseif (substr($this->data, $this->position, 2) == "\r\n")
7058 $this->state = 'end_crlf';
7059 $this->position += 2;
7061 elseif (strspn($this->data, "\r\n", $this->position, 1))
7063 $this->state = 'end_crlf';
7068 $this->state = 'value_no_quote';
7073 * Parse a header value while outside quotes
7077 function value_no_quote()
7079 $len = strcspn($this->data, "\x09\x20\r\n\"", $this->position);
7080 $this->value .= substr($this->data, $this->position, $len);
7081 $this->state = 'value_next';
7082 $this->position += $len;
7086 * Parse LWS outside quotes
7090 function value_linear_whitespace()
7092 $this->linear_whitespace();
7093 $this->state = 'value_next';
7097 * See what state to move the state machine to while within quoted header values
7101 function value_quote_next()
7103 if ($this->is_linear_whitespace())
7105 $this->state = 'value_linear_whitespace_quote';
7109 switch ($this->data[$this->position])
7112 $this->state = 'value_next';
7117 $this->state = 'value_quote_char';
7122 $this->state = 'value_quote';
7129 * Parse a header value while within quotes
7133 function value_quote()
7135 $len = strcspn($this->data, "\x09\x20\r\n\"\\", $this->position);
7136 $this->value .= substr($this->data, $this->position, $len);
7137 $this->position += $len;
7138 $this->state = 'value_quote_next';
7142 * Parse an escaped character within quotes
7146 function value_quote_char()
7148 $this->value .= $this->data[$this->position];
7149 $this->state = 'value_quote_next';
7154 * Parse LWS within quotes
7158 function value_linear_whitespace_quote()
7160 $this->linear_whitespace();
7161 $this->state = 'value_quote_next';
7165 * Parse a CRLF, and see whether we have a further header, or whether we are followed by the body
7171 $this->name = strtolower($this->name);
7172 $this->value = trim($this->value, "\x20");
7173 if (isset($this->headers[$this->name]))
7175 $this->headers[$this->name] .= ', ' . $this->value;
7179 $this->headers[$this->name] = $this->value;
7182 if (substr($this->data, $this->position, 2) == "\r\n")
7184 $this->body = substr($this->data, $this->position + 2);
7185 $this->state = 'emit';
7187 elseif (strspn($this->data, "\r\n", $this->position, 1))
7189 $this->body = substr($this->data, $this->position + 1);
7190 $this->state = 'emit';
7196 $this->state = 'name';
7201 class SimplePie_Cache
7208 function SimplePie_Cache($location, $filename, $extension)
7210 $this->location = $location;
7211 $this->filename = rawurlencode($filename);
7212 $this->extension = rawurlencode($extension);
7213 $this->name = "$location/$this->filename.$this->extension";
7216 function save($data)
7218 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
7220 if (function_exists('file_put_contents'))
7222 return (bool) file_put_contents($this->name, serialize($data));
7226 $fp = fopen($this->name, 'wb');
7229 fwrite($fp, serialize($data));
7240 if (file_exists($this->name) && is_readable($this->name))
7242 if (function_exists('file_get_contents'))
7244 return unserialize(file_get_contents($this->name));
7246 elseif (($fp = fopen($this->name, 'rb')) !== false)
7251 $data .= fread($fp, 8192);
7254 return unserialize($data);
7262 if (file_exists($this->name))
7264 return filemtime($this->name);
7271 if (file_exists($this->name))
7273 return touch($this->name);
7280 if (file_exists($this->name))
7282 return unlink($this->name);
7288 class SimplePie_Misc
7290 function time_hms($seconds)
7294 $hours = floor($seconds / 3600);
7295 $remainder = $seconds % 3600;
7298 $time .= $hours.':';
7301 $minutes = floor($remainder / 60);
7302 $seconds = $remainder % 60;
7303 if ($minutes < 10 && $hours > 0)
7305 $minutes = '0' . $minutes;
7309 $seconds = '0' . $seconds;
7312 $time .= $minutes.':';
7318 function absolutize_url($relative, $base)
7320 if ($relative !== '')
7322 $relative = SimplePie_Misc::parse_url($relative);
7323 if ($relative['scheme'] !== '')
7325 $target = $relative;
7327 elseif ($base !== '')
7329 $base = SimplePie_Misc::parse_url($base);
7330 $target = SimplePie_Misc::parse_url('');
7331 if ($relative['authority'] !== '')
7333 $target = $relative;
7334 $target['scheme'] = $base['scheme'];
7338 $target['scheme'] = $base['scheme'];
7339 $target['authority'] = $base['authority'];
7340 if ($relative['path'] !== '')
7342 if (strpos($relative['path'], '/') === 0)
7344 $target['path'] = $relative['path'];
7346 elseif (($target['path'] = dirname("$base[path].")) == '/')
7348 $target['path'] .= $relative['path'];
7352 $target['path'] .= '/' . $relative['path'];
7354 if ($relative['query'] !== '')
7356 $target['query'] = $relative['query'];
7361 if ($base['path'] !== '')
7363 $target['path'] = $base['path'];
7367 $target['path'] = '/';
7369 if ($relative['query'] !== '')
7371 $target['query'] = $relative['query'];
7373 elseif ($base['query'] !== '')
7375 $target['query'] = $base['query'];
7379 if ($relative['fragment'] !== '')
7381 $target['fragment'] = $relative['fragment'];
7386 // No base URL, just return the relative URL
7387 $target = $relative;
7389 $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
7395 $return = SimplePie_Misc::normalize_url($return);
7399 function remove_dot_segments($input)
7402 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
7404 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
7405 if (strpos($input, '../') === 0)
7407 $input = substr($input, 3);
7409 elseif (strpos($input, './') === 0)
7411 $input = substr($input, 2);
7413 // 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,
7414 elseif (strpos($input, '/./') === 0)
7416 $input = substr_replace($input, '/', 0, 3);
7418 elseif ($input == '/.')
7422 // 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,
7423 elseif (strpos($input, '/../') === 0)
7425 $input = substr_replace($input, '/', 0, 4);
7426 $output = substr_replace($output, '', strrpos($output, '/'));
7428 elseif ($input == '/..')
7431 $output = substr_replace($output, '', strrpos($output, '/'));
7433 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
7434 elseif ($input == '.' || $input == '..')
7438 // 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
7439 elseif (($pos = strpos($input, '/', 1)) !== false)
7441 $output .= substr($input, 0, $pos);
7442 $input = substr_replace($input, '', 0, $pos);
7450 return $output . $input;
7453 function get_element($realname, $string)
7456 $name = preg_quote($realname, '/');
7457 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
7459 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
7461 $return[$i]['tag'] = $realname;
7462 $return[$i]['full'] = $matches[$i][0][0];
7463 $return[$i]['offset'] = $matches[$i][0][1];
7464 if (strlen($matches[$i][3][0]) <= 2)
7466 $return[$i]['self_closing'] = true;
7470 $return[$i]['self_closing'] = false;
7471 $return[$i]['content'] = $matches[$i][4][0];
7473 $return[$i]['attribs'] = array();
7474 if (isset($matches[$i][2][0]) && preg_match_all('/((?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([a-z0-9\-._:]*)))?\s/U', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
7476 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
7478 if (count($attribs[$j]) == 2)
7480 $attribs[$j][2] = $attribs[$j][1];
7482 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
7490 function element_implode($element)
7492 $full = "<$element[tag]";
7493 foreach ($element['attribs'] as $key => $value)
7495 $key = strtolower($key);
7496 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
7498 if ($element['self_closing'])
7504 $full .= ">$element[content]</$element[tag]>";
7509 function error($message, $level, $file, $line)
7514 $note = 'PHP Error';
7516 case E_USER_WARNING:
7517 $note = 'PHP Warning';
7520 $note = 'PHP Notice';
7523 $note = 'Unknown Error';
7526 error_log("$note: $message in $file on line $line", 0);
7531 * If a file has been cached, retrieve and display it.
7533 * This is most useful for caching images (get_favicon(), etc.),
7534 * however it works for all cached files. This WILL NOT display ANY
7535 * file/image/page/whatever, but rather only display what has already
7536 * been cached by SimplePie.
7539 * @see SimplePie::get_favicon()
7540 * @param str $identifier_url URL that is used to identify the content.
7541 * This may or may not be the actual URL of the live content.
7542 * @param str $cache_location Location of SimplePie's cache. Defaults
7544 * @param str $cache_extension The file extension that the file was
7545 * cached with. Defaults to 'spc'.
7546 * @param str $cache_class Name of the cache-handling class being used
7547 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
7548 * as-is unless you've overloaded the class.
7549 * @param str $cache_name_function Function that converts the filename
7550 * for saving. Defaults to 'md5'.
7552 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
7554 $cache =& new $cache_class($cache_location, call_user_func($cache_name_function, $identifier_url), $cache_extension);
7556 if ($file = $cache->load())
7558 header('Content-type:' . $file['headers']['content-type']);
7559 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
7564 die('Cached file for ' . $identifier_url . ' cannot be found.');
7567 function fix_protocol($url, $http = 1)
7569 $url = SimplePie_Misc::normalize_url($url);
7570 $parsed = SimplePie_Misc::parse_url($url);
7571 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
7573 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
7576 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
7578 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
7581 if ($http == 2 && $parsed['scheme'] !== '')
7585 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
7587 return substr_replace($url, 'podcast', 0, 4);
7589 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
7591 return substr_replace($url, 'itpc', 0, 4);
7599 function parse_url($url)
7601 static $cache = array();
7602 if (isset($cache[$url]))
7604 return $cache[$url];
7606 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
7608 for ($i = count($match); $i <= 9; $i++)
7612 return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
7616 return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
7620 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
7625 $return .= "$scheme:";
7627 if ($authority !== '')
7629 $return .= "//$authority";
7637 $return .= "?$query";
7639 if ($fragment !== '')
7641 $return .= "#$fragment";
7646 function normalize_url($url)
7648 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
7649 $url = SimplePie_Misc::parse_url($url);
7650 $url['scheme'] = strtolower($url['scheme']);
7651 if ($url['authority'] !== '')
7653 $url['authority'] = strtolower($url['authority']);
7654 $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
7656 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
7659 function percent_encoding_normalization($match)
7661 $integer = hexdec($match[1]);
7662 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
7664 return chr($integer);
7668 return strtoupper($match[0]);
7673 * Remove bad UTF-8 bytes
7675 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
7676 * FAQ: Multilingual Forms (modified to include full ASCII range)
7678 * @author Geoffrey Sneddon
7679 * @see http://www.w3.org/International/questions/qa-forms-utf-8
7680 * @param string $str String to remove bad UTF-8 bytes from
7681 * @return string UTF-8 string
7683 function utf8_bad_replace($str)
7685 if (function_exists('iconv'))
7687 return iconv('UTF-8', 'UTF-8//IGNORE', $str);
7689 elseif (function_exists('mb_convert_encoding'))
7691 return mb_convert_encoding($str, 'UTF-8', 'UTF-8');
7693 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))
7695 return implode("\xEF\xBF\xBD", $matches[0]);
7697 elseif ($str !== '')
7699 return "\xEF\xBF\xBD";
7707 function change_encoding($data, $input, $output)
7709 $input = SimplePie_Misc::encoding($input);
7710 $output = SimplePie_Misc::encoding($output);
7712 if (function_exists('iconv') && ($return = @iconv($input, "$output//IGNORE", $data)))
7716 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
7720 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
7724 elseif ($input == 'ISO-8859-1' && $output == 'UTF-8')
7726 return utf8_encode($data);
7728 elseif ($input == 'UTF-8' && $output == 'ISO-8859-1')
7730 return utf8_decode($data);
7735 function encoding($encoding)
7737 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
7738 switch (strtoupper($encoding))
7740 case 'ANSI_X3.4-1968':
7742 case 'ANSI_X3.4-1986':
7743 case 'ISO_646.IRV:1991':
7753 case 'ISO_8859-1:1987':
7762 return 'ISO-8859-1';
7764 case 'ISO_8859-2:1987':
7771 return 'ISO-8859-2';
7773 case 'ISO_8859-3:1988':
7780 return 'ISO-8859-3';
7782 case 'ISO_8859-4:1988':
7789 return 'ISO-8859-4';
7791 case 'ISO_8859-5:1988':
7796 case 'CSISOLATINCYRILLIC':
7797 return 'ISO-8859-5';
7799 case 'ISO_8859-6:1987':
7806 case 'CSISOLATINARABIC':
7807 return 'ISO-8859-6';
7809 case 'ISO_8859-7:1987':
7817 case 'CSISOLATINGREEK':
7818 return 'ISO-8859-7';
7820 case 'ISO_8859-8:1988':
7825 case 'CSISOLATINHEBREW':
7826 return 'ISO-8859-8';
7828 case 'ISO_8859-9:1989':
7835 return 'ISO-8859-9';
7840 case 'ISO_8859-10:1992':
7843 return 'ISO-8859-10';
7845 case 'ISO_6937-2-ADD':
7847 case 'CSISOTEXTCOMM':
7848 return 'ISO_6937-2-add';
7852 case 'CSHALFWIDTHKATAKANA':
7855 case 'JIS_ENCODING':
7856 case 'CSJISENCODING':
7857 return 'JIS_Encoding';
7864 case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
7865 case 'CSEUCPKDFMTJAPANESE':
7869 case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
7870 case 'CSEUCFIXWIDJAPANESE':
7871 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
7878 case 'CSISO4UNITEDKINGDOM':
7881 case 'SEN_850200_C':
7885 case 'CSISO11SWEDISHFORNAMES':
7886 return 'SEN_850200_C';
7891 case 'CSISO15ITALIAN':
7897 case 'CSISO17SPANISH':
7904 case 'CSISO21GERMAN':
7911 case 'CSISO60DANISHNORWEGIAN':
7912 case 'CSISO60NORWEGIAN1':
7919 case 'CSISO69FRENCH':
7920 return 'NF_Z_62-010';
7922 case 'ISO-10646-UTF-1':
7923 case 'CSISO10646UTF1':
7924 return 'ISO-10646-UTF-1';
7926 case 'ISO_646.BASIC:1983':
7928 case 'CSISO646BASIC1983':
7929 return 'ISO_646.basic:1983';
7935 case 'ISO_646.IRV:1983':
7938 case 'CSISO2INTLREFVERSION':
7939 return 'ISO_646.irv:1983';
7946 case 'NATS-SEFI-ADD':
7948 case 'CSNATSSEFIADD':
7949 return 'NATS-SEFI-ADD';
7956 case 'NATS-DANO-ADD':
7958 case 'CSNATSDANOADD':
7959 return 'NATS-DANO-ADD';
7961 case 'SEN_850200_B':
7967 case 'CSISO10SWEDISH':
7968 return 'SEN_850200_B';
7970 case 'KS_C_5601-1987':
7972 case 'KS_C_5601-1989':
7975 case 'CSKSC56011987':
7976 return 'KS_C_5601-1987';
7980 return 'ISO-2022-KR';
7988 return 'ISO-2022-JP';
7990 case 'ISO-2022-JP-2':
7991 case 'CSISO2022JP2':
7992 return 'ISO-2022-JP-2';
7994 case 'JIS_C6220-1969-JP':
7995 case 'JIS_C6220-1969':
7999 case 'CSISO13JISC6220JP':
8000 return 'JIS_C6220-1969-jp';
8002 case 'JIS_C6220-1969-RO':
8006 case 'CSISO14JISC6220RO':
8007 return 'JIS_C6220-1969-ro';
8012 case 'CSISO16PORTUGUESE':
8017 case 'CSISO18GREEK7OLD':
8018 return 'greek7-old';
8022 case 'CSISO19LATINGREEK':
8023 return 'latin-greek';
8025 case 'NF_Z_62-010_(1973)':
8028 case 'CSISO25FRENCH':
8029 return 'NF_Z_62-010_(1973)';
8031 case 'LATIN-GREEK-1':
8033 case 'CSISO27LATINGREEK1':
8034 return 'Latin-greek-1';
8038 case 'CSISO5427CYRILLIC':
8041 case 'JIS_C6226-1978':
8043 case 'CSISO42JISC62261978':
8044 return 'JIS_C6226-1978';
8048 case 'CSISO47BSVIEWDATA':
8049 return 'BS_viewdata';
8058 case 'CSISO50INIS8':
8061 case 'INIS-CYRILLIC':
8063 case 'CSISO51INISCYRILLIC':
8064 return 'INIS-cyrillic';
8066 case 'ISO_5427:1981':
8068 case 'ISO5427CYRILLIC1981':
8069 return 'ISO_5427:1981';
8071 case 'ISO_5428:1980':
8073 case 'CSISO5428GREEK':
8074 return 'ISO_5428:1980';
8080 case 'CSISO57GB1988':
8081 return 'GB_1988-80';
8086 case 'CSISO58GB231280':
8087 return 'GB_2312-80';
8093 case 'CSISO61NORWEGIAN2':
8096 case 'VIDEOTEX-SUPPL':
8098 case 'CSISO70VIDEOTEXSUPP1':
8099 return 'videotex-suppl';
8104 case 'CSISO84PORTUGUESE2':
8110 case 'CSISO85SPANISH2':
8117 case 'CSISO86HUNGARIAN':
8118 return 'MSZ_7795.3';
8120 case 'JIS_C6226-1983':
8123 case 'JIS_X0208-1983':
8124 case 'CSISO87JISX0208':
8125 return 'JIS_C6226-1983';
8129 case 'CSISO88GREEK7':
8136 case 'CSISO89ASMO449':
8143 case 'JIS_C6229-1984-A':
8146 case 'CSISO91JISC62291984A':
8147 return 'JIS_C6229-1984-a';
8149 case 'JIS_C6229-1984-B':
8151 case 'ISO646-JP-OCR-B':
8153 case 'CSISO92JISC62991984B':
8154 return 'JIS_C6229-1984-b';
8156 case 'JIS_C6229-1984-B-ADD':
8158 case 'JP-OCR-B-ADD':
8159 case 'CSISO93JIS62291984BADD':
8160 return 'JIS_C6229-1984-b-add';
8162 case 'JIS_C6229-1984-HAND':
8165 case 'CSISO94JIS62291984HAND':
8166 return 'JIS_C6229-1984-hand';
8168 case 'JIS_C6229-1984-HAND-ADD':
8170 case 'JP-OCR-HAND-ADD':
8171 case 'CSISO95JIS62291984HANDADD':
8172 return 'JIS_C6229-1984-hand-add';
8174 case 'JIS_C6229-1984-KANA':
8176 case 'CSISO96JISC62291984KANA':
8177 return 'JIS_C6229-1984-kana';
8179 case 'ISO_2033-1983':
8183 return 'ISO_2033-1983';
8185 case 'ANSI_X3.110-1983':
8187 case 'CSA_T500-1983':
8189 case 'CSISO99NAPLPS':
8190 return 'ANSI_X3.110-1983';
8194 case 'CSISO102T617BIT':
8200 case 'CSISO103T618BIT':
8203 case 'ECMA-CYRILLIC':
8206 case 'CSISO111ECMACYRILLIC':
8207 return 'ECMA-cyrillic';
8209 case 'CSA_Z243.4-1985-1':
8214 case 'CSISO121CANADIAN1':
8215 return 'CSA_Z243.4-1985-1';
8217 case 'CSA_Z243.4-1985-2':
8221 case 'CSISO122CANADIAN2':
8222 return 'CSA_Z243.4-1985-2';
8224 case 'CSA_Z243.4-1985-GR':
8226 case 'CSISO123CSAZ24341985GR':
8227 return 'CSA_Z243.4-1985-gr';
8229 case 'ISO_8859-6-E':
8231 case 'ISO-8859-6-E':
8232 return 'ISO-8859-6-E';
8234 case 'ISO_8859-6-I':
8236 case 'ISO-8859-6-I':
8237 return 'ISO-8859-6-I';
8241 case 'CSISO128T101G2':
8244 case 'ISO_8859-8-E':
8246 case 'ISO-8859-8-E':
8247 return 'ISO-8859-8-E';
8249 case 'ISO_8859-8-I':
8251 case 'ISO-8859-8-I':
8252 return 'ISO-8859-8-I';
8256 case 'CSISO139CSN369103':
8257 return 'CSN_369103';
8259 case 'JUS_I.B1.002':
8264 case 'CSISO141JUSIB1002':
8265 return 'JUS_I.B1.002';
8269 case 'CSISO143IECP271':
8272 case 'JUS_I.B1.003-SERB':
8275 case 'CSISO146SERBIAN':
8276 return 'JUS_I.B1.003-serb';
8278 case 'JUS_I.B1.003-MAC':
8281 case 'CSISO147MACEDONIAN':
8282 return 'JUS_I.B1.003-mac';
8287 case 'CSISO150GREEKCCITT':
8288 return 'greek-ccitt';
8290 case 'NC_NC00-10:81':
8294 case 'CSISO151CUBA':
8295 return 'NC_NC00-10:81';
8297 case 'ISO_6937-2-25':
8299 case 'CSISO6937ADD':
8300 return 'ISO_6937-2-25';
8302 case 'GOST_19768-74':
8303 case 'ST_SEV_358-88':
8305 case 'CSISO153GOST1976874':
8306 return 'GOST_19768-74';
8308 case 'ISO_8859-SUPP':
8311 case 'CSISO8859SUPP':
8312 return 'ISO_8859-supp';
8314 case 'ISO_10367-BOX':
8316 case 'CSISO10367BOX':
8317 return 'ISO_10367-box';
8325 case 'JIS_X0212-1990':
8328 case 'CSISO159JISX02121990':
8329 return 'JIS_X0212-1990';
8335 case 'CSISO646DANISH':
8351 case 'UNICODE-1-1-UTF-7':
8352 case 'CSUNICODE11UTF7':
8353 return 'UNICODE-1-1-UTF-7';
8356 return 'ISO-2022-CN';
8358 case 'ISO-2022-CN-EXT':
8359 return 'ISO-2022-CN-EXT';
8365 return 'ISO-8859-13';
8369 case 'ISO_8859-14:1998':
8374 return 'ISO-8859-14';
8379 return 'ISO-8859-15';
8383 case 'ISO_8859-16:2001':
8387 return 'ISO-8859-16';
8398 case 'OSD_EBCDIC_DF04_15':
8399 return 'OSD_EBCDIC_DF04_15';
8401 case 'OSD_EBCDIC_DF03_IRV':
8402 return 'OSD_EBCDIC_DF03_IRV';
8404 case 'OSD_EBCDIC_DF04_1':
8405 return 'OSD_EBCDIC_DF04_1';
8409 case 'ISO_TR_11548-1':
8411 return 'ISO-11548-1';
8414 case 'STRK1048-2002':
8419 case 'ISO-10646-UCS-2':
8421 return 'ISO-10646-UCS-2';
8423 case 'ISO-10646-UCS-4':
8425 return 'ISO-10646-UCS-4';
8427 case 'ISO-10646-UCS-BASIC':
8428 case 'CSUNICODEASCII':
8429 return 'ISO-10646-UCS-Basic';
8431 case 'ISO-10646-UNICODE-LATIN1':
8432 case 'CSUNICODELATIN1':
8434 return 'ISO-10646-Unicode-Latin1';
8436 case 'ISO-10646-J-1':
8437 return 'ISO-10646-J-1';
8439 case 'ISO-UNICODE-IBM-1261':
8440 case 'CSUNICODEIBM1261':
8441 return 'ISO-Unicode-IBM-1261';
8443 case 'ISO-UNICODE-IBM-1268':
8444 case 'CSUNICODEIBM1268':
8445 return 'ISO-Unicode-IBM-1268';
8447 case 'ISO-UNICODE-IBM-1276':
8448 case 'CSUNICODEIBM1276':
8449 return 'ISO-Unicode-IBM-1276';
8451 case 'ISO-UNICODE-IBM-1264':
8452 case 'CSUNICODEIBM1264':
8453 return 'ISO-Unicode-IBM-1264';
8455 case 'ISO-UNICODE-IBM-1265':
8456 case 'CSUNICODEIBM1265':
8457 return 'ISO-Unicode-IBM-1265';
8461 return 'UNICODE-1-1';
8495 case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
8496 case 'CSWINDOWS30LATIN1':
8497 return 'ISO-8859-1-Windows-3.0-Latin-1';
8499 case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
8500 case 'CSWINDOWS31LATIN1':
8501 return 'ISO-8859-1-Windows-3.1-Latin-1';
8503 case 'ISO-8859-2-WINDOWS-LATIN-2':
8504 case 'CSWINDOWS31LATIN2':
8505 return 'ISO-8859-2-Windows-Latin-2';
8507 case 'ISO-8859-9-WINDOWS-LATIN-5':
8508 case 'CSWINDOWS31LATIN5':
8509 return 'ISO-8859-9-Windows-Latin-5';
8517 case 'ADOBE-STANDARD-ENCODING':
8518 case 'CSADOBESTANDARDENCODING':
8519 return 'Adobe-Standard-Encoding';
8523 return 'Ventura-US';
8525 case 'VENTURA-INTERNATIONAL':
8526 case 'CSVENTURAINTERNATIONAL':
8527 return 'Ventura-International';
8537 case 'CSPC850MULTILINGUAL':
8540 case 'PC8-DANISH-NORWEGIAN':
8541 case 'CSPC8DANISHNORWEGIAN':
8542 return 'PC8-Danish-Norwegian';
8547 case 'CSPC862LATINHEBREW':
8551 case 'CSPC8TURKISH':
8552 return 'PC8-Turkish';
8555 case 'CSIBMSYMBOLS':
8556 return 'IBM-Symbols';
8568 return 'HP-Pi-font';
8574 case 'ADOBE-SYMBOL-ENCODING':
8576 return 'Adobe-Symbol-Encoding';
8580 return 'HP-DeskTop';
8582 case 'VENTURA-MATH':
8583 case 'CSVENTURAMATH':
8584 return 'Ventura-Math';
8586 case 'MICROSOFT-PUBLISHING':
8587 case 'CSMICROSOFTPUBLISHING':
8588 return 'Microsoft-Publishing';
8591 case 'CSWINDOWS31J':
8592 return 'Windows-31J';
8609 case 'EBCDIC-CP-US':
8610 case 'EBCDIC-CP-CA':
8611 case 'EBCDIC-CP-WT':
8612 case 'EBCDIC-CP-NL':
8640 case 'EBCDIC-CP-DK':
8641 case 'EBCDIC-CP-NO':
8647 case 'EBCDIC-CP-FI':
8648 case 'EBCDIC-CP-SE':
8654 case 'EBCDIC-CP-IT':
8666 case 'EBCDIC-CP-ES':
8672 case 'EBCDIC-CP-GB':
8678 case 'EBCDIC-JP-KANA':
8684 case 'EBCDIC-CP-FR':
8690 case 'EBCDIC-CP-AR1':
8696 case 'EBCDIC-CP-GR':
8702 case 'EBCDIC-CP-HE':
8709 case 'CSPC8CODEPAGE437':
8714 case 'EBCDIC-CP-BE':
8715 case 'EBCDIC-CP-CH':
8788 case 'EBCDIC-CP-ROECE':
8789 case 'EBCDIC-CP-YU':
8795 case 'EBCDIC-CP-IS':
8801 case 'EBCDIC-CYRILLIC':
8823 case 'EBCDIC-CP-TR':
8829 case 'EBCDIC-CP-AR2':
8838 case 'EBCDIC-AT-DE':
8839 case 'CSIBMEBCDICATDE':
8840 return 'EBCDIC-AT-DE';
8842 case 'EBCDIC-AT-DE-A':
8843 case 'CSEBCDICATDEA':
8844 return 'EBCDIC-AT-DE-A';
8846 case 'EBCDIC-CA-FR':
8847 case 'CSEBCDICCAFR':
8848 return 'EBCDIC-CA-FR';
8850 case 'EBCDIC-DK-NO':
8851 case 'CSEBCDICDKNO':
8852 return 'EBCDIC-DK-NO';
8854 case 'EBCDIC-DK-NO-A':
8855 case 'CSEBCDICDKNOA':
8856 return 'EBCDIC-DK-NO-A';
8858 case 'EBCDIC-FI-SE':
8859 case 'CSEBCDICFISE':
8860 return 'EBCDIC-FI-SE';
8862 case 'EBCDIC-FI-SE-A':
8863 case 'CSEBCDICFISEA':
8864 return 'EBCDIC-FI-SE-A';
8884 return 'EBCDIC-ES-A';
8888 return 'EBCDIC-ES-S';
8898 case 'UNKNOWN-8BIT':
8899 case 'CSUNKNOWN8BIT':
8900 return 'UNKNOWN-8BIT';
8923 return 'HZ-GB-2312';
8933 case 'CSPC775BALTIC':
8942 case 'PC-MULTILINGUAL-850+EURO':
8948 case 'EBCDIC-LATIN9--EURO':
8954 case 'EBCDIC-US-37+EURO':
8960 case 'EBCDIC-DE-273+EURO':
8966 case 'EBCDIC-DK-277+EURO':
8967 case 'EBCDIC-NO-277+EURO':
8973 case 'EBCDIC-FI-278+EURO':
8974 case 'EBCDIC-SE-278+EURO':
8980 case 'EBCDIC-IT-280+EURO':
8986 case 'EBCDIC-ES-284+EURO':
8992 case 'EBCDIC-GB-285+EURO':
8998 case 'EBCDIC-FR-297+EURO':
9004 case 'EBCDIC-INTERNATIONAL-500+EURO':
9010 case 'EBCDIC-IS-871+EURO':
9014 return 'Big5-HKSCS';
9024 case 'CYRILLIC-ASIAN':
9031 return 'Amiga-1251';
9033 case 'KOI7-SWITCHED':
9034 return 'KOI7-switched';
9044 case 'WINDOWS-1250':
9045 return 'windows-1250';
9047 case 'WINDOWS-1251':
9048 return 'windows-1251';
9050 case 'WINDOWS-1252':
9051 return 'windows-1252';
9053 case 'WINDOWS-1253':
9054 return 'windows-1253';
9056 case 'WINDOWS-1254':
9057 return 'windows-1254';
9059 case 'WINDOWS-1255':
9060 return 'windows-1255';
9062 case 'WINDOWS-1256':
9063 return 'windows-1256';
9065 case 'WINDOWS-1257':
9066 return 'windows-1257';
9068 case 'WINDOWS-1258':
9069 return 'windows-1258';
9072 return (string) $encoding;
9076 function get_curl_version()
9078 if (is_array($curl = curl_version()))
9080 $curl = $curl['version'];
9082 elseif (substr($curl, 0, 5) == 'curl/')
9084 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
9086 elseif (substr($curl, 0, 8) == 'libcurl/')
9088 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
9097 function is_subclass_of($class1, $class2)
9099 if (func_num_args() != 2)
9101 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
9103 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
9105 return is_subclass_of($class1, $class2);
9107 elseif (is_string($class1) && is_string($class2))
9109 if (class_exists($class1))
9111 if (class_exists($class2))
9113 $class2 = strtolower($class2);
9114 while ($class1 = strtolower(get_parent_class($class1)))
9116 if ($class1 == $class2)
9125 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
9132 * Strip HTML comments
9135 * @param string $data Data to strip comments from
9136 * @return string Comment stripped string
9138 function strip_comments($data)
9141 while (($start = strpos($data, '<!--')) !== false)
9143 $output .= substr($data, 0, $start);
9144 if (($end = strpos($data, '-->', $start)) !== false)
9146 $data = substr_replace($data, '', 0, $end + 3);
9153 return $output . $data;
9156 function parse_date($dt, $rfc822_tz = true)
9158 static $cache = array();
9159 if (!isset($cache[$dt][$rfc822_tz]))
9161 $dt = SimplePie_Misc::uncomment_rfc822($dt);
9163 Capturing subpatterns:
9173 10: ISO 8601 ordinal day
9177 14: ISO 8601 day of week
9191 28: Alphabetic Timezone
9193 if (preg_match('/^(?:(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)[,\s]+)?(([0-9]{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*([0-9]{4}|[0-9]{2}))|(([0-9]{2})(?:([0-9]{2})(?:(?:-|\s)*(?:([0-9]{2})([0-9]{2})|([0-9]{3})|([0-9]{2})(?:(?:-|\s)*([0-9]{2}))?|W([0-9]{2})(?:(?:-|\s)*([0-9]))?))?)?))((?:T|\s)+([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*))?)?)?(?:\s)*((?:(\+|-)([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*(?:([0-9]{2})(?:(?:,|\.)([0-9]*))?))?)|(UTC|GMT|EST|CST|MST|PST|EDT|CDT|MDT|PDT|UT|[A-IK-Z]))?)?$/i', $dt, $match))
9196 for ($i = count($match); $i <= 28; $i++)
9211 if ($match[1] !== '')
9213 if (strlen($match[4]) == 2)
9215 $year = ($match[4] < 70) ? "20$match[4]" : "19$match[4]";
9221 switch (strtolower($match[3]))
9277 if ($match[7] !== '')
9279 $year = "$match[6]$match[7]";
9281 // Two Digit Month/Day
9282 if ($match[11] !== '')
9284 $month = $match[11];
9285 if ($match[12] !== '')
9291 // Four Digit Month/Day
9292 elseif ($match[8] !== '')
9299 elseif ($match[10] !== '')
9305 elseif ($match[13] !== '')
9308 if ($match[14] !== '')
9313 $first_day_of_year = date('w', mktime(0, 0, 0, 1, 1, $year));
9314 if ($first_day_of_year == 0)
9316 $first_day_of_year = 7;
9319 $day = 7 * ($match[13] - 1) + $day - ($first_day_of_year - 1);
9324 $year = "$match[6]00";
9328 if ($match[15] !== '')
9331 $time += ($match[16] + ('.' . $match[17])) * 3600;
9332 $time += ($match[18] + ('.' . $match[19])) * 60;
9333 $time += $match[20] + ('.' . $match[21]);
9334 $hour = floor($time / 3600);
9335 $time -= $hour * 3600;
9336 $minute = floor($time / 60);
9337 $time -= $minute * 60;
9338 $second = round($time);
9341 if ($match[22] !== '')
9343 // Alphabetic Timezone
9344 if ($match[28] !== '')
9347 if (strlen($match[28]) == 1)
9349 if ($match[28] == 'Z' || $match[28] == 'z' || !$rfc822_tz)
9355 $timezone = ord(strtoupper($match[28]));
9362 if ($timezone <= 76)
9364 $timezone = -($timezone - 64);
9377 switch (strtoupper($match[28]))
9419 // Timezone difference from UTC
9423 $timezone += ($match[24] + ('.' . $match[25])) * 3600;
9424 $timezone += ($match[26] + ('.' . $match[27])) * 60;
9425 $timezone = (int) round($timezone);
9427 if ($match[23] == '-')
9429 $timezone = -$timezone;
9434 if ($timezone === false)
9436 $cache[$dt][$rfc822_tz] = mktime($hour, $minute, $second, $month, $day, $year);
9440 $cache[$dt][$rfc822_tz] = gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
9443 elseif (($time = strtotime($dt)) > 0)
9445 $cache[$dt][$rfc822_tz] = $time;
9449 $cache[$dt][$rfc822_tz] = false;
9452 return $cache[$dt][$rfc822_tz];
9456 * Decode HTML entities
9460 * @param string $data Input data
9461 * @return string Output data
9463 function entities_decode($data)
9465 $decoder = new SimplePie_Decode_HTML_Entities($data);
9466 return $decoder->parse();
9470 * Remove RFC822 comments
9472 * @author Tomas V.V.Cox <cox@idecnet.com>
9473 * @author Pierre-Alain Joye <pajoye@php.net>
9474 * @author Amir Mohammad Saied <amir@php.net>
9475 * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
9476 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
9477 * @version CVS: $Id: Validate.php,v 1.104 2006/11/17 16:32:06 amir Exp $
9478 * @link http://pear.php.net/package/Validate
9480 * @param string $data Data to strip comments from
9481 * @return string Comment stripped string
9483 function uncomment_rfc822($data)
9485 if ((version_compare(PHP_VERSION, '4.4.6', '>=') && version_compare(PHP_VERSION, '5', '<')) || version_compare(PHP_VERSION, '5.2.2', '>='))
9491 return preg_replace('/((?:(?:\\\\"|[^("])*(?:"(?:[^"\\\\\r]|\\\\.)*"\s*)?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/', '$1', $data);
9495 function parse_mime($mime)
9497 if (($pos = strpos($mime, ';')) === false)
9503 return trim(substr($mime, 0, $pos));
9507 function htmlspecialchars_decode($string, $quote_style)
9509 if (function_exists('htmlspecialchars_decode'))
9511 return htmlspecialchars_decode($string, $quote_style);
9515 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
9519 function atom_03_construct_type($attribs)
9521 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
9523 $mode = SIMPLEPIE_CONSTRUCT_BASE64;
9527 $mode = SIMPLEPIE_CONSTRUCT_NONE;
9529 if (isset($attribs['']['type']))
9531 switch (strtolower(trim($attribs['']['type'])))
9535 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9539 return SIMPLEPIE_CONSTRUCT_HTML | $mode;
9542 case 'application/xhtml+xml':
9543 return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
9546 return SIMPLEPIE_CONSTRUCT_NONE | $mode;
9551 return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9555 function atom_10_construct_type($attribs)
9557 if (isset($attribs['']['type']))
9559 switch (strtolower(trim($attribs['']['type'])))
9562 return SIMPLEPIE_CONSTRUCT_TEXT;
9565 return SIMPLEPIE_CONSTRUCT_HTML;
9568 return SIMPLEPIE_CONSTRUCT_XHTML;
9571 return SIMPLEPIE_CONSTRUCT_NONE;
9574 return SIMPLEPIE_CONSTRUCT_TEXT;
9577 function atom_10_content_construct_type($attribs)
9579 if (isset($attribs['']['type']))
9581 $type = strtolower(trim($attribs['']['type']));
9585 return SIMPLEPIE_CONSTRUCT_TEXT;
9588 return SIMPLEPIE_CONSTRUCT_HTML;
9591 return SIMPLEPIE_CONSTRUCT_XHTML;
9593 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
9595 return SIMPLEPIE_CONSTRUCT_NONE;
9599 return SIMPLEPIE_CONSTRUCT_BASE64;
9604 return SIMPLEPIE_CONSTRUCT_TEXT;
9608 function is_isegment_nz_nc($string)
9610 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);
9613 function space_seperated_tokens($string)
9615 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
9616 $string_length = strlen($string);
9618 $position = strspn($string, $space_characters);
9621 while ($position < $string_length)
9623 $len = strcspn($string, $space_characters, $position);
9624 $tokens[] = substr($string, $position, $len);
9626 $position += strspn($string, $space_characters, $position);
9632 function array_unique($array)
9634 if (version_compare(PHP_VERSION, '5.2', '>='))
9636 return array_unique($array);
9640 $array = (array) $array;
9641 $new_array = array();
9642 $new_array_strings = array();
9643 foreach ($array as $key => $value)
9645 if (is_object($value))
9647 if (method_exists($value, '__toString'))
9649 $cmp = $value->__toString();
9653 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
9656 elseif (is_array($value))
9658 $cmp = (string) reset($value);
9662 $cmp = (string) $value;
9664 if (!in_array($cmp, $new_array_strings))
9666 $new_array[$key] = $value;
9667 $new_array_strings[] = $cmp;
9675 * Converts a unicode codepoint to a UTF-8 character
9679 * @param int $codepoint Unicode codepoint
9680 * @return string UTF-8 character
9682 function codepoint_to_utf8($codepoint)
9684 static $cache = array();
9685 $codepoint = (int) $codepoint;
9686 if (isset($cache[$codepoint]))
9688 return $cache[$codepoint];
9690 elseif ($codepoint < 0)
9692 return $cache[$codepoint] = false;
9694 else if ($codepoint <= 0x7f)
9696 return $cache[$codepoint] = chr($codepoint);
9698 else if ($codepoint <= 0x7ff)
9700 return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
9702 else if ($codepoint <= 0xffff)
9704 return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9706 else if ($codepoint <= 0x10ffff)
9708 return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9712 // U+FFFD REPLACEMENT CHARACTER
9713 return $cache[$codepoint] = "\xEF\xBF\xBD";
9718 * Re-implementation of PHP 4.2.0's is_a()
9722 * @param object $object The tested object
9723 * @param string $class_name The class name
9724 * @return bool Returns true if the object is of this class or has this class as one of its parents, false otherwise
9726 function is_a($object, $class_name)
9728 if (function_exists('is_a'))
9730 return is_a($object, $class_name);
9732 elseif (!is_object($object))
9736 elseif (get_class($object) == strtolower($class_name))
9742 return is_subclass_of($object, $class_name);
9747 * Re-implementation of PHP 5's stripos()
9749 * Returns the numeric position of the first occurrence of needle in the
9754 * @param object $haystack
9755 * @param string $needle Note that the needle may be a string of one or more
9756 * characters. If needle is not a string, it is converted to an integer
9757 * and applied as the ordinal value of a character.
9758 * @param int $offset The optional offset parameter allows you to specify which
9759 * character in haystack to start searching. The position returned is still
9760 * relative to the beginning of haystack.
9761 * @return bool If needle is not found, stripos() will return boolean false.
9763 function stripos($haystack, $needle, $offset = 0)
9765 if (function_exists('stripos'))
9767 return stripos($haystack, $needle, $offset);
9771 if (is_string($needle))
9773 $needle = strtolower($needle);
9775 elseif (is_int($needle) || is_bool($needle) || is_double($needle))
9777 $needle = strtolower(chr($needle));
9781 trigger_error('needle is not a string or an integer', E_USER_WARNING);
9785 return strpos(strtolower($haystack), $needle, $offset);
9791 * Decode HTML Entities
9793 * This implements HTML5 as of revision 967 (2007-06-28)
9795 * @package SimplePie
9797 class SimplePie_Decode_HTML_Entities
9808 * Currently consumed bytes
9816 * Position of the current byte being parsed
9824 * Create an instance of the class with the input data
9827 * @param string $data Input data
9829 function SimplePie_Decode_HTML_Entities($data)
9831 $this->data = $data;
9835 * Parse the input data
9838 * @return string Output data
9842 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
9846 $this->consumed = '';
9852 * Consume the next byte
9855 * @return mixed The next byte, or false, if there is no more data
9859 if (isset($this->data[$this->position]))
9861 $this->consumed .= $this->data[$this->position];
9862 return $this->data[$this->position++];
9866 $this->consumed = false;
9872 * Consume a range of characters
9875 * @param string $chars Characters to consume
9876 * @return mixed A series of characters that match the range, or false
9878 function consume_range($chars)
9880 if ($len = strspn($this->data, $chars, $this->position))
9882 $data = substr($this->data, $this->position, $len);
9883 $this->consumed .= $data;
9884 $this->position += $len;
9889 $this->consumed = false;
9895 * Unconsume one byte
9899 function unconsume()
9901 $this->consumed = substr($this->consumed, 0, -1);
9912 switch ($this->consume())
9926 switch ($this->consume())
9930 $range = '0123456789ABCDEFabcdef';
9935 $range = '0123456789';
9941 if ($codepoint = $this->consume_range($range))
9943 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");
9947 $codepoint = hexdec($codepoint);
9951 $codepoint = intval($codepoint);
9954 if (isset($windows_1252_specials[$codepoint]))
9956 $replacement = $windows_1252_specials[$codepoint];
9960 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
9963 if ($this->consume() != ';')
9968 $consumed_length = strlen($this->consumed);
9969 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
9970 $this->position += strlen($replacement) - $consumed_length;
9975 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");
9977 for ($i = 0, $match = null; $i < 9 && $this->consume(); $i++)
9979 $consumed = substr($this->consumed, 1);
9980 if (isset($entities[$consumed]))
9986 if ($match !== null)
9988 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
9989 $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
9996 class SimplePie_Locator
10001 var $local = array();
10002 var $elsewhere = array();
10003 var $file_class = 'SimplePie_File';
10004 var $cached_entities = array();
10007 var $base_location = 0;
10008 var $checked_feeds = 0;
10009 var $max_checked_feeds = 10;
10011 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10)
10013 $this->file =& $file;
10014 $this->file_class = $file_class;
10015 $this->useragent = $useragent;
10016 $this->timeout = $timeout;
10017 $this->max_checked_feeds = $max_checked_feeds;
10020 function find($type = SIMPLEPIE_LOCATOR_ALL)
10022 if ($this->is_feed($this->file))
10024 return $this->file;
10027 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
10032 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
10037 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
10039 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
10044 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
10049 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
10054 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
10062 function is_feed(&$file)
10064 $body = SimplePie_Misc::strip_comments($file->body);
10065 if (preg_match('/<([^\s:]+:)?(rss|RDF|feed)' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/i', $body))
10072 function get_base()
10074 if (isset($this->file->headers['content-location']))
10076 $this->http_base = SimplePie_Misc::absolutize_url(trim($this->file->headers['content-location']), $this->file->url);
10080 $this->http_base = $this->file->url;
10082 $this->base = $this->http_base;
10083 $elements = SimplePie_Misc::get_element('base', $this->file->body);
10084 foreach ($elements as $element)
10086 if ($element['attribs']['href']['data'] !== '')
10088 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
10089 $this->base_location = $element['offset'];
10095 function autodiscovery()
10097 $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));
10099 foreach ($links as $link)
10101 if ($this->checked_feeds == $this->max_checked_feeds)
10105 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
10107 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
10109 if ($this->base_location < $link['offset'])
10111 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10115 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10118 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'))))
10120 $this->checked_feeds++;
10121 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
10122 if ($this->is_feed($feed))
10133 function get_links()
10135 $links = SimplePie_Misc::get_element('a', $this->file->body);
10136 foreach ($links as $link)
10138 if (isset($link['attribs']['href']['data']))
10140 $href = trim($link['attribs']['href']['data']);
10141 $parsed = SimplePie_Misc::parse_url($href);
10142 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
10144 if ($this->base_location < $link['offset'])
10146 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10150 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10153 $current = SimplePie_Misc::parse_url($this->file->url);
10155 if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
10157 $this->local[] = $href;
10161 $this->elsewhere[] = $href;
10166 $this->local = array_unique($this->local);
10167 $this->elsewhere = array_unique($this->elsewhere);
10168 if (!empty($this->local) || !empty($this->elsewhere))
10175 function extension(&$array)
10177 foreach ($array as $key => $value)
10179 if ($this->checked_feeds == $this->max_checked_feeds)
10183 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
10185 $this->checked_feeds++;
10186 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10187 if ($this->is_feed($feed))
10193 unset($array[$key]);
10200 function body(&$array)
10202 foreach ($array as $key => $value)
10204 if ($this->checked_feeds == $this->max_checked_feeds)
10208 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
10210 $this->checked_feeds++;
10211 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10212 if ($this->is_feed($feed))
10218 unset($array[$key]);
10226 class SimplePie_Parser
10232 var $current_column;
10234 var $separator = ' ';
10236 var $namespace = array('');
10237 var $element = array('');
10238 var $xml_base = array('');
10239 var $xml_base_explicit = array(false);
10240 var $xml_lang = array('');
10241 var $data = array();
10242 var $datas = array(array());
10243 var $current_xhtml_construct = -1;
10246 function pre_process(&$data, $encoding)
10248 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
10249 if (strtoupper($encoding) == 'US-ASCII')
10251 $this->encoding = 'UTF-8';
10255 $this->encoding = $encoding;
10259 // UTF-32 Big Endian BOM
10260 if (strpos($data, "\x0\x0\xFE\xFF") === 0)
10262 $data = substr($data, 4);
10264 // UTF-32 Little Endian BOM
10265 elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
10267 $data = substr($data, 4);
10269 // UTF-16 Big Endian BOM
10270 elseif (strpos($data, "\xFE\xFF") === 0)
10272 $data = substr($data, 2);
10274 // UTF-16 Little Endian BOM
10275 elseif (strpos($data, "\xFF\xFE") === 0)
10277 $data = substr($data, 2);
10280 elseif (strpos($data, "\xEF\xBB\xBF") === 0)
10282 $data = substr($data, 3);
10285 // Make sure the XML prolog is sane and has the correct encoding
10286 $data = preg_replace("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')([\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*'))?([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", '', $data);
10287 $data = "<?xml version='1.0' encoding='$encoding'?>\n" . $data;
10290 function parse(&$data)
10294 // Create the parser
10295 $this->xml = xml_parser_create_ns($this->encoding, $this->separator);
10296 xml_parser_set_option($this->xml, XML_OPTION_SKIP_WHITE, 1);
10297 xml_parser_set_option($this->xml, XML_OPTION_CASE_FOLDING, 0);
10298 xml_set_object($this->xml, $this);
10299 xml_set_character_data_handler($this->xml, 'cdata');
10300 xml_set_element_handler($this->xml, 'tag_open', 'tag_close');
10303 if (!xml_parse($this->xml, $data, true))
10305 $this->data = null;
10306 $this->error_code = xml_get_error_code($this->xml);
10307 $this->error_string = xml_error_string($this->error_code);
10310 $this->current_line = xml_get_current_line_number($this->xml);
10311 $this->current_column = xml_get_current_column_number($this->xml);
10312 $this->current_byte = xml_get_current_byte_index($this->xml);
10313 xml_parser_free($this->xml);
10317 function get_error_code()
10319 return $this->error_code;
10322 function get_error_string()
10324 return $this->error_string;
10327 function get_current_line()
10329 return $this->current_line;
10332 function get_current_column()
10334 return $this->current_column;
10337 function get_current_byte()
10339 return $this->current_byte;
10342 function get_data()
10344 return $this->data;
10347 function tag_open($parser, $tag, $attributes)
10349 if ($this->feed === 0)
10353 elseif ($this->feed == false)
10355 if (in_array($tag, array(
10356 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
10357 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
10359 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
10370 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
10372 $attribs = array();
10373 foreach ($attributes as $name => $value)
10375 list($attrib_namespace, $attribute) = $this->split_ns($name);
10376 $attribs[$attrib_namespace][$attribute] = $value;
10379 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
10381 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
10382 $this->xml_base_explicit[] = true;
10386 $this->xml_base[] = end($this->xml_base);
10387 $this->xml_base_explicit[] = end($this->xml_base_explicit);
10390 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
10392 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
10396 $this->xml_lang[] = end($this->xml_lang);
10399 if ($this->current_xhtml_construct >= 0)
10401 $this->current_xhtml_construct++;
10402 if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
10404 $this->data['data'] .= '<' . end($this->element);
10405 if (isset($attribs['']))
10407 foreach ($attribs[''] as $name => $value)
10409 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
10412 $this->data['data'] .= '>';
10417 $this->datas[] =& $this->data;
10418 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
10419 $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));
10420 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')
10421 || (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'))
10423 $this->current_xhtml_construct = 0;
10428 function cdata($parser, $cdata)
10430 if ($this->current_xhtml_construct >= 0)
10432 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
10434 elseif ($this->feed > 1)
10436 $this->data['data'] .= $cdata;
10440 function tag_close($parser, $tag)
10447 if ($this->current_xhtml_construct >= 0)
10449 $this->current_xhtml_construct--;
10450 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')))
10452 $this->data['data'] .= '</' . end($this->element) . '>';
10455 if ($this->current_xhtml_construct == -1)
10457 $this->data =& $this->datas[$this->feed];
10458 array_pop($this->datas);
10461 array_pop($this->element);
10462 array_pop($this->namespace);
10463 array_pop($this->xml_base);
10464 array_pop($this->xml_base_explicit);
10465 array_pop($this->xml_lang);
10469 function split_ns($string)
10471 static $cache = array();
10472 if (!isset($cache[$string]))
10474 if ($pos = strpos($string, $this->separator))
10476 static $separator_length;
10477 if (!$separator_length)
10479 $separator_length = strlen($this->separator);
10481 $cache[$string] = array(substr($string, 0, $pos), substr($string, $pos + $separator_length));
10485 $cache[$string] = array('', $string);
10488 return $cache[$string];
10493 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags
10495 class SimplePie_Sanitize
10501 var $remove_div = true;
10502 var $image_handler = '';
10503 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
10504 var $encode_instead_of_strip = false;
10505 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
10506 var $strip_comments = false;
10507 var $output_encoding = 'UTF-8';
10508 var $enable_cache = true;
10509 var $cache_location = './cache';
10510 var $cache_name_function = 'md5';
10511 var $cache_class = 'SimplePie_Cache';
10512 var $file_class = 'SimplePie_File';
10514 var $useragent = '';
10515 var $force_fsockopen = false;
10517 var $replace_url_attributes = array(
10520 'blockquote' => 'cite',
10522 'form' => 'action',
10523 'img' => array('longdesc', 'src'),
10529 function remove_div($enable = true)
10531 $this->remove_div = (bool) $enable;
10534 function set_image_handler($page = false)
10538 $this->image_handler = (string) $page;
10542 $this->image_handler = false;
10546 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
10548 if (isset($enable_cache))
10550 $this->enable_cache = (bool) $enable_cache;
10553 if ($cache_location)
10555 $this->cache_location = (string) $cache_location;
10558 if ($cache_name_function)
10560 $this->cache_name_function = (string) $cache_name_function;
10565 $this->cache_class = (string) $cache_class;
10569 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
10573 $this->file_class = (string) $file_class;
10578 $this->timeout = (string) $timeout;
10583 $this->useragent = (string) $useragent;
10586 if ($force_fsockopen)
10588 $this->force_fsockopen = (string) $force_fsockopen;
10592 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
10596 if (is_array($tags))
10598 $this->strip_htmltags = $tags;
10602 $this->strip_htmltags = explode(',', $tags);
10607 $this->strip_htmltags = false;
10611 function encode_instead_of_strip($encode = false)
10613 $this->encode_instead_of_strip = (bool) $encode;
10616 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
10620 if (is_array($attribs))
10622 $this->strip_attributes = $attribs;
10626 $this->strip_attributes = explode(',', $attribs);
10631 $this->strip_attributes = false;
10635 function strip_comments($strip = false)
10637 $this->strip_comments = (bool) $strip;
10640 function set_output_encoding($encoding = 'UTF-8')
10642 $this->output_encoding = (string) $encoding;
10646 * Set element/attribute key/value pairs of HTML attributes
10647 * containing URLs that need to be resolved relative to the feed
10651 * @param array $element_attribute Element/attribute key/value pairs
10653 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'))
10655 $this->replace_url_attributes = (array) $element_attribute;
10658 function sanitize($data, $type, $base = '')
10660 $data = trim($data);
10661 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
10663 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
10665 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/(\w+)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
10667 $type |= SIMPLEPIE_CONSTRUCT_HTML;
10671 $type |= SIMPLEPIE_CONSTRUCT_TEXT;
10675 if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
10677 $data = base64_decode($data);
10680 if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
10682 if ($this->remove_div)
10684 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
10685 $data = preg_replace('/<\/div>$/', '', $data);
10689 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
10693 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
10696 if ($this->strip_comments)
10698 $data = SimplePie_Misc::strip_comments($data);
10701 // Strip out HTML tags and attributes that might cause various security problems.
10702 // Based on recommendations by Mark Pilgrim at:
10703 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
10704 if ($this->strip_htmltags)
10706 foreach ($this->strip_htmltags as $tag)
10708 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
10709 while (preg_match($pcre, $data))
10711 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
10716 if ($this->strip_attributes)
10718 foreach ($this->strip_attributes as $attrib)
10720 $data = preg_replace('/ '. trim($attrib) .'=("|")(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|'|<|>|\+|{|})*("|")/i', '', $data);
10721 $data = preg_replace('/ '. trim($attrib) .'=(\'|')(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|"|"|<|>|\+|{|})*(\'|')/i', '', $data);
10722 $data = preg_replace('/ '. trim($attrib) .'=(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\+|{|})*/i', '', $data);
10726 // Replace relative URLs
10727 $this->base = $base;
10728 foreach ($this->replace_url_attributes as $element => $attributes)
10730 $data = $this->replace_urls($data, $element, $attributes);
10733 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
10734 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
10736 $images = SimplePie_Misc::get_element('img', $data);
10737 foreach ($images as $img)
10739 if (isset($img['attribs']['src']['data']))
10741 $image_url = $img['attribs']['src']['data'];
10742 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $image_url), 'spi');
10744 if ($cache->load())
10746 $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10747 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10751 $file =& new $this->file_class($image_url, $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
10752 $headers = $file->headers;
10754 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
10756 if (!$cache->save(array('headers' => $file->headers, 'body' => $file->body)))
10758 trigger_error("$cache->name is not writeable", E_USER_WARNING);
10760 $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10761 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10768 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
10769 $data = trim($data);
10772 if ($type & SIMPLEPIE_CONSTRUCT_IRI)
10774 $data = SimplePie_Misc::absolutize_url($data, $base);
10777 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
10779 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
10782 if ($this->output_encoding != 'UTF-8')
10784 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
10790 function replace_urls($data, $tag, $attributes)
10792 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
10794 $elements = SimplePie_Misc::get_element($tag, $data);
10795 foreach ($elements as $element)
10797 if (is_array($attributes))
10799 foreach ($attributes as $attribute)
10801 if (isset($element['attribs'][$attribute]['data']))
10803 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
10804 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10808 elseif (isset($element['attribs'][$attributes]['data']))
10810 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
10811 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10818 function do_strip_htmltags($match)
10820 if ($this->encode_instead_of_strip)
10822 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
10824 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
10825 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
10826 return "<$match[1]$match[2]>$match[3]</$match[1]>";
10830 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
10833 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))