5 * A PHP-Based RSS and Atom Feed Framework.
6 * Takes the hard work out of managing a complete RSS/Atom solution.
8 * Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
11 * Redistribution and use in source and binary forms, with or without modification, are
12 * permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright notice, this list of
15 * conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright notice, this list
18 * of conditions and the following disclaimer in the documentation and/or other materials
19 * provided with the distribution.
21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
22 * to endorse or promote products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon, Ryan McCue
39 * @author Geoffrey Sneddon
41 * @link http://simplepie.org/ SimplePie
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.3-dev');
58 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
60 define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc
::parse_date(substr('$Date$', 7, 25)) ? SimplePie_Misc
::parse_date(substr('$Date$', 7, 25)) : filemtime(__FILE__
)));
63 * SimplePie Website URL
65 define('SIMPLEPIE_URL', 'http://simplepie.org');
69 * @see SimplePie::set_useragent()
71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME
. '/' . SIMPLEPIE_VERSION
. ' (Feed Parser; ' . SIMPLEPIE_URL
. '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD
);
76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL
. '" title="' . SIMPLEPIE_NAME
. ' ' . SIMPLEPIE_VERSION
. '">' . SIMPLEPIE_NAME
. '</a>');
80 * @see SimplePie::set_autodiscovery_level()
82 define('SIMPLEPIE_LOCATOR_NONE', 0);
85 * Feed Link Element Autodiscovery
86 * @see SimplePie::set_autodiscovery_level()
88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
91 * Local Feed Extension Autodiscovery
92 * @see SimplePie::set_autodiscovery_level()
94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
97 * Local Feed Body Autodiscovery
98 * @see SimplePie::set_autodiscovery_level()
100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
103 * Remote Feed Extension Autodiscovery
104 * @see SimplePie::set_autodiscovery_level()
106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
109 * Remote Feed Body Autodiscovery
110 * @see SimplePie::set_autodiscovery_level()
112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
115 * All Feed Autodiscovery
116 * @see SimplePie::set_autodiscovery_level()
118 define('SIMPLEPIE_LOCATOR_ALL', 31);
123 define('SIMPLEPIE_TYPE_NONE', 0);
128 define('SIMPLEPIE_TYPE_RSS_090', 1);
131 * RSS 0.91 (Netscape)
133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
136 * RSS 0.91 (Userland)
138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
141 * RSS 0.91 (both Netscape and Userland)
143 define('SIMPLEPIE_TYPE_RSS_091', 6);
148 define('SIMPLEPIE_TYPE_RSS_092', 8);
153 define('SIMPLEPIE_TYPE_RSS_093', 16);
158 define('SIMPLEPIE_TYPE_RSS_094', 32);
163 define('SIMPLEPIE_TYPE_RSS_10', 64);
168 define('SIMPLEPIE_TYPE_RSS_20', 128);
173 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
176 * Non-RDF-based RSS (truly intended as syndication format)
178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
183 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
188 define('SIMPLEPIE_TYPE_ATOM_03', 256);
193 define('SIMPLEPIE_TYPE_ATOM_10', 512);
198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
203 define('SIMPLEPIE_TYPE_ALL', 1023);
208 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
218 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
226 * base64-encoded construct
228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
233 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
236 * A construct that might be HTML
238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
243 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
248 define('SIMPLEPIE_SAME_CASE', 1);
251 * Change to lowercase
253 define('SIMPLEPIE_LOWERCASE', 2);
256 * Change to uppercase
258 define('SIMPLEPIE_UPPERCASE', 4);
261 * PCRE for HTML attributes
263 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
266 * PCRE for XML attributes
268 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
273 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
278 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
283 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
288 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
293 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
298 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
301 * RSS 1.0 Content Module Namespace
303 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
307 * (Stupid, I know, but I'm certain it will confuse people less with support.)
309 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
314 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
319 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
322 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
324 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
329 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
332 * Media RSS Namespace
334 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
337 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
339 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
342 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
344 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
347 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
349 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
352 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
354 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
357 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
359 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
362 * iTunes RSS Namespace
364 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
369 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
372 * IANA Link Relations Registry
374 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
377 * Whether we're running on PHP5
379 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION
, '5.0.0', '>='));
384 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
389 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
394 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
397 * fsockopen() file source
399 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
404 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
407 * file_get_contents() file source
409 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
419 * @var array Raw data
422 public $data = array();
425 * @var mixed Error string
431 * @var object Instance of SimplePie_Sanitize (or other class)
432 * @see SimplePie::set_sanitize_class()
438 * @var string SimplePie Useragent
439 * @see SimplePie::set_useragent()
442 public $useragent = SIMPLEPIE_USERAGENT
;
445 * @var string Feed URL
446 * @see SimplePie::set_feed_url()
452 * @var object Instance of SimplePie_File to use as a feed
453 * @see SimplePie::set_file()
459 * @var string Raw feed data
460 * @see SimplePie::set_raw_data()
466 * @var int Timeout for fetching remote files
467 * @see SimplePie::set_timeout()
470 public $timeout = 10;
473 * @var bool Forces fsockopen() to be used for remote files instead
474 * of cURL, even if a new enough version is installed
475 * @see SimplePie::force_fsockopen()
478 public $force_fsockopen = false;
481 * @var bool Force the given data/URL to be treated as a feed no matter what
483 * @see SimplePie::force_feed()
486 public $force_feed = false;
489 * @var bool Enable/Disable XML dump
490 * @see SimplePie::enable_xml_dump()
493 public $xml_dump = false;
496 * @var bool Enable/Disable Caching
497 * @see SimplePie::enable_cache()
500 public $cache = true;
503 * @var int Cache duration (in seconds)
504 * @see SimplePie::set_cache_duration()
507 public $cache_duration = 3600;
510 * @var int Auto-discovery cache duration (in seconds)
511 * @see SimplePie::set_autodiscovery_cache_duration()
514 public $autodiscovery_cache_duration = 604800; // 7 Days.
517 * @var string Cache location (relative to executing script)
518 * @see SimplePie::set_cache_location()
521 public $cache_location = './cache';
524 * @var string Function that creates the cache filename
525 * @see SimplePie::set_cache_name_function()
528 public $cache_name_function = 'md5';
531 * @var bool Reorder feed by date descending
532 * @see SimplePie::enable_order_by_date()
535 public $order_by_date = true;
538 * @var mixed Force input encoding to be set to the follow value
539 * (false, or anything type-cast to false, disables this feature)
540 * @see SimplePie::set_input_encoding()
543 public $input_encoding = false;
546 * @var int Feed Autodiscovery Level
547 * @see SimplePie::set_autodiscovery_level()
550 public $autodiscovery = SIMPLEPIE_LOCATOR_ALL
;
553 * @var string Class used for caching feeds
554 * @see SimplePie::set_cache_class()
557 public $cache_class = 'SimplePie_Cache';
560 * @var string Class used for locating feeds
561 * @see SimplePie::set_locator_class()
564 public $locator_class = 'SimplePie_Locator';
567 * @var string Class used for parsing feeds
568 * @see SimplePie::set_parser_class()
571 public $parser_class = 'SimplePie_Parser';
574 * @var string Class used for fetching feeds
575 * @see SimplePie::set_file_class()
578 public $file_class = 'SimplePie_File';
581 * @var string Class used for items
582 * @see SimplePie::set_item_class()
585 public $item_class = 'SimplePie_Item';
588 * @var string Class used for authors
589 * @see SimplePie::set_author_class()
592 public $author_class = 'SimplePie_Author';
595 * @var string Class used for categories
596 * @see SimplePie::set_category_class()
599 public $category_class = 'SimplePie_Category';
602 * @var string Class used for enclosures
603 * @see SimplePie::set_enclosures_class()
606 public $enclosure_class = 'SimplePie_Enclosure';
609 * @var string Class used for Media RSS <media:text> captions
610 * @see SimplePie::set_caption_class()
613 public $caption_class = 'SimplePie_Caption';
616 * @var string Class used for Media RSS <media:copyright>
617 * @see SimplePie::set_copyright_class()
620 public $copyright_class = 'SimplePie_Copyright';
623 * @var string Class used for Media RSS <media:credit>
624 * @see SimplePie::set_credit_class()
627 public $credit_class = 'SimplePie_Credit';
630 * @var string Class used for Media RSS <media:rating>
631 * @see SimplePie::set_rating_class()
634 public $rating_class = 'SimplePie_Rating';
637 * @var string Class used for Media RSS <media:restriction>
638 * @see SimplePie::set_restriction_class()
641 public $restriction_class = 'SimplePie_Restriction';
644 * @var string Class used for content-type sniffing
645 * @see SimplePie::set_content_type_sniffer_class()
648 public $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
651 * @var string Class used for item sources.
652 * @see SimplePie::set_source_class()
655 public $source_class = 'SimplePie_Source';
658 * @var mixed Set javascript query string parameter (false, or
659 * anything type-cast to false, disables this feature)
660 * @see SimplePie::set_javascript()
663 public $javascript = 'js';
666 * @var int Maximum number of feeds to check with autodiscovery
667 * @see SimplePie::set_max_checked_feeds()
670 public $max_checked_feeds = 10;
673 * @var array All the feeds found during the autodiscovery process
674 * @see SimplePie::get_all_discovered_feeds()
677 public $all_discovered_feeds = array();
680 * @var string Web-accessible path to the handler_image.php file.
681 * @see SimplePie::set_image_handler()
684 public $image_handler = '';
687 * @var array Stores the URLs when multiple feeds are being initialized.
688 * @see SimplePie::set_feed_url()
691 public $multifeed_url = array();
694 * @var array Stores SimplePie objects when multiple feeds initialized.
697 public $multifeed_objects = array();
700 * @var array Stores the get_object_vars() array for use with multifeeds.
701 * @see SimplePie::set_feed_url()
704 public $config_settings = null;
707 * @var integer Stores the number of items to return per-feed with multifeeds.
708 * @see SimplePie::set_item_limit()
711 public $item_limit = 0;
714 * @var array Stores the default attributes to be stripped by strip_attributes().
715 * @see SimplePie::strip_attributes()
718 public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
721 * @var array Stores the default tags to be stripped by strip_htmltags().
722 * @see SimplePie::strip_htmltags()
725 public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
728 * The SimplePie class contains feed level data and options
730 * There are two ways that you can create a new SimplePie object. The first
731 * is by passing a feed URL as a parameter to the SimplePie constructor
732 * (as well as optionally setting the cache location and cache expiry). This
733 * will initialise the whole feed with all of the default settings, and you
734 * can begin accessing methods and properties immediately.
736 * The second way is to create the SimplePie object with no parameters
737 * at all. This will enable you to set configuration options. After setting
738 * them, you must initialise the feed using $feed->init(). At that point the
739 * object's methods and properties will be available to you. This format is
740 * what is used throughout this documentation.
743 * @since 1.0 Preview Release
745 public function __construct()
747 if (version_compare(PHP_VERSION
, '5.0', '<'))
749 trigger_error('PHP 4.x is no longer supported. Please upgrade to PHP 5.2 or newer.');
753 // Other objects, instances created here so we can set options on them
754 $this->sanitize
= new SimplePie_Sanitize();
756 if (func_num_args() > 0)
758 trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.');
763 * Used for converting object to a string
765 public function __toString()
767 return md5(serialize($this->data
));
771 * Remove items that link back to this before destroying this object
773 public function __destruct()
775 if ((version_compare(PHP_VERSION
, '5.3', '<') ||
!gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
777 if (!empty($this->data
['items']))
779 foreach ($this->data
['items'] as $item)
783 unset($item, $this->data
['items']);
785 if (!empty($this->data
['ordered_items']))
787 foreach ($this->data
['ordered_items'] as $item)
791 unset($item, $this->data
['ordered_items']);
797 * Force the given data/URL to be treated as a feed no matter what it
802 * @param bool $enable Force the given data/URL to be treated as a feed
804 public function force_feed($enable = false)
806 $this->force_feed
= (bool) $enable;
810 * This is the URL of the feed you want to parse.
812 * This allows you to enter the URL of the feed you want to parse, or the
813 * website you want to try to use auto-discovery on. This takes priority
814 * over any set raw data.
816 * You can set multiple feeds to mash together by passing an array instead
817 * of a string for the $url. Remember that with each additional feed comes
818 * additional processing and resources.
821 * @since 1.0 Preview Release
822 * @param mixed $url This is the URL (or array of URLs) that you want to parse.
823 * @see SimplePie::set_raw_data()
825 public function set_feed_url($url)
829 $this->multifeed_url
= array();
830 foreach ($url as $value)
832 $this->multifeed_url
[] = SimplePie_Misc
::fix_protocol($value, 1);
837 $this->feed_url
= SimplePie_Misc
::fix_protocol($url, 1);
842 * Provides an instance of SimplePie_File to use as a feed
845 * @param object &$file Instance of SimplePie_File (or subclass)
846 * @return bool True on success, false on failure
848 public function set_file(&$file)
850 if (is_a($file, 'SimplePie_File'))
852 $this->feed_url
= $file->url
;
853 $this->file
=& $file;
860 * Allows you to use a string of RSS/Atom data instead of a remote feed.
862 * If you have a feed available as a string in PHP, you can tell SimplePie
863 * to parse that data string instead of a remote feed. Any set feed URL
868 * @param string $data RSS or Atom data as a string.
869 * @see SimplePie::set_feed_url()
871 public function set_raw_data($data)
873 $this->raw_data
= $data;
877 * Allows you to override the default timeout for fetching remote feeds.
879 * This allows you to change the maximum time the feed's server to respond
880 * and send the feed back.
884 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
886 public function set_timeout($timeout = 10)
888 $this->timeout
= (int) $timeout;
892 * Forces SimplePie to use fsockopen() instead of the preferred cURL
897 * @param bool $enable Force fsockopen() to be used
899 public function force_fsockopen($enable = false)
901 $this->force_fsockopen
= (bool) $enable;
905 * Enables/disables caching in SimplePie.
907 * This option allows you to disable caching all-together in SimplePie.
908 * However, disabling the cache can lead to longer load times.
911 * @since 1.0 Preview Release
912 * @param bool $enable Enable caching
914 public function enable_cache($enable = true)
916 $this->cache
= (bool) $enable;
920 * Set the length of time (in seconds) that the contents of a feed
924 * @param int $seconds The feed content cache duration.
926 public function set_cache_duration($seconds = 3600)
928 $this->cache_duration
= (int) $seconds;
932 * Set the length of time (in seconds) that the autodiscovered feed
933 * URL will be cached.
936 * @param int $seconds The autodiscovered feed URL cache duration.
938 public function set_autodiscovery_cache_duration($seconds = 604800)
940 $this->autodiscovery_cache_duration
= (int) $seconds;
944 * Set the file system location where the cached files should be stored.
947 * @param string $location The file system location.
949 public function set_cache_location($location = './cache')
951 $this->cache_location
= (string) $location;
955 * Determines whether feed items should be sorted into reverse chronological order.
958 * @param bool $enable Sort as reverse chronological order.
960 public function enable_order_by_date($enable = true)
962 $this->order_by_date
= (bool) $enable;
966 * Allows you to override the character encoding reported by the feed.
969 * @param string $encoding Character encoding.
971 public function set_input_encoding($encoding = false)
975 $this->input_encoding
= (string) $encoding;
979 $this->input_encoding
= false;
984 * Set how much feed autodiscovery to do
987 * @see SIMPLEPIE_LOCATOR_NONE
988 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
989 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
990 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
991 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
992 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
993 * @see SIMPLEPIE_LOCATOR_ALL
994 * @param int $level Feed Autodiscovery Level (level can be a
995 * combination of the above constants, see bitwise OR operator)
997 public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL
)
999 $this->autodiscovery
= (int) $level;
1003 * Allows you to change which class SimplePie uses for caching.
1004 * Useful when you are overloading or extending SimplePie's default classes.
1007 * @param string $class Name of custom class.
1008 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1010 public function set_cache_class($class = 'SimplePie_Cache')
1012 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Cache'))
1014 $this->cache_class
= $class;
1021 * Allows you to change which class SimplePie uses for auto-discovery.
1022 * Useful when you are overloading or extending SimplePie's default classes.
1025 * @param string $class Name of custom class.
1026 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1028 public function set_locator_class($class = 'SimplePie_Locator')
1030 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Locator'))
1032 $this->locator_class
= $class;
1039 * Allows you to change which class SimplePie uses for XML parsing.
1040 * Useful when you are overloading or extending SimplePie's default classes.
1043 * @param string $class Name of custom class.
1044 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1046 public function set_parser_class($class = 'SimplePie_Parser')
1048 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Parser'))
1050 $this->parser_class
= $class;
1057 * Allows you to change which class SimplePie uses for remote file fetching.
1058 * Useful when you are overloading or extending SimplePie's default classes.
1061 * @param string $class Name of custom class.
1062 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1064 public function set_file_class($class = 'SimplePie_File')
1066 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_File'))
1068 $this->file_class
= $class;
1075 * Allows you to change which class SimplePie uses for data sanitization.
1076 * Useful when you are overloading or extending SimplePie's default classes.
1079 * @param string $class Name of custom class.
1080 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1082 public function set_sanitize_class($class = 'SimplePie_Sanitize')
1084 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Sanitize'))
1086 $this->sanitize
= new $class();
1093 * Allows you to change which class SimplePie uses for handling feed items.
1094 * Useful when you are overloading or extending SimplePie's default classes.
1097 * @param string $class Name of custom class.
1098 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1100 public function set_item_class($class = 'SimplePie_Item')
1102 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Item'))
1104 $this->item_class
= $class;
1111 * Allows you to change which class SimplePie uses for handling author data.
1112 * Useful when you are overloading or extending SimplePie's default classes.
1115 * @param string $class Name of custom class.
1116 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1118 public function set_author_class($class = 'SimplePie_Author')
1120 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Author'))
1122 $this->author_class
= $class;
1129 * Allows you to change which class SimplePie uses for handling category data.
1130 * Useful when you are overloading or extending SimplePie's default classes.
1133 * @param string $class Name of custom class.
1134 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1136 public function set_category_class($class = 'SimplePie_Category')
1138 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Category'))
1140 $this->category_class
= $class;
1147 * Allows you to change which class SimplePie uses for feed enclosures.
1148 * Useful when you are overloading or extending SimplePie's default classes.
1151 * @param string $class Name of custom class.
1152 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1154 public function set_enclosure_class($class = 'SimplePie_Enclosure')
1156 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Enclosure'))
1158 $this->enclosure_class
= $class;
1165 * Allows you to change which class SimplePie uses for <media:text> captions
1166 * Useful when you are overloading or extending SimplePie's default classes.
1169 * @param string $class Name of custom class.
1170 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1172 public function set_caption_class($class = 'SimplePie_Caption')
1174 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Caption'))
1176 $this->caption_class
= $class;
1183 * Allows you to change which class SimplePie uses for <media:copyright>
1184 * Useful when you are overloading or extending SimplePie's default classes.
1187 * @param string $class Name of custom class.
1188 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1190 public function set_copyright_class($class = 'SimplePie_Copyright')
1192 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Copyright'))
1194 $this->copyright_class
= $class;
1201 * Allows you to change which class SimplePie uses for <media:credit>
1202 * Useful when you are overloading or extending SimplePie's default classes.
1205 * @param string $class Name of custom class.
1206 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1208 public function set_credit_class($class = 'SimplePie_Credit')
1210 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Credit'))
1212 $this->credit_class
= $class;
1219 * Allows you to change which class SimplePie uses for <media:rating>
1220 * Useful when you are overloading or extending SimplePie's default classes.
1223 * @param string $class Name of custom class.
1224 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1226 public function set_rating_class($class = 'SimplePie_Rating')
1228 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Rating'))
1230 $this->rating_class
= $class;
1237 * Allows you to change which class SimplePie uses for <media:restriction>
1238 * Useful when you are overloading or extending SimplePie's default classes.
1241 * @param string $class Name of custom class.
1242 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1244 public function set_restriction_class($class = 'SimplePie_Restriction')
1246 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Restriction'))
1248 $this->restriction_class
= $class;
1255 * Allows you to change which class SimplePie uses for content-type sniffing.
1256 * Useful when you are overloading or extending SimplePie's default classes.
1259 * @param string $class Name of custom class.
1260 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1262 public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1264 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1266 $this->content_type_sniffer_class
= $class;
1273 * Allows you to change which class SimplePie uses item sources.
1274 * Useful when you are overloading or extending SimplePie's default classes.
1277 * @param string $class Name of custom class.
1278 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1280 public function set_source_class($class = 'SimplePie_Source')
1282 if (SimplePie_Misc
::is_subclass_of($class, 'SimplePie_Source'))
1284 $this->source_class
= $class;
1291 * Allows you to override the default user agent string.
1294 * @param string $ua New user agent string.
1296 public function set_useragent($ua = SIMPLEPIE_USERAGENT
)
1298 $this->useragent
= (string) $ua;
1302 * Set callback function to create cache filename with
1305 * @param mixed $function Callback function
1307 public function set_cache_name_function($function = 'md5')
1309 if (is_callable($function))
1311 $this->cache_name_function
= $function;
1316 * Set javascript query string parameter
1319 * @param mixed $get Javascript query string parameter
1321 public function set_javascript($get = 'js')
1325 $this->javascript
= (string) $get;
1329 $this->javascript
= false;
1334 * Set options to make SP as fast as possible. Forgoes a
1335 * substantial amount of data sanitization in favor of speed.
1338 * @param bool $set Whether to set them or not
1340 public function set_stupidly_fast($set = false)
1344 $this->enable_order_by_date(false);
1345 $this->remove_div(false);
1346 $this->strip_comments(false);
1347 $this->strip_htmltags(false);
1348 $this->strip_attributes(false);
1349 $this->set_image_handler(false);
1354 * Set maximum number of feeds to check with autodiscovery
1357 * @param int $max Maximum number of feeds to check
1359 public function set_max_checked_feeds($max = 10)
1361 $this->max_checked_feeds
= (int) $max;
1364 public function remove_div($enable = true)
1366 $this->sanitize
->remove_div($enable);
1369 public function strip_htmltags($tags = '', $encode = null)
1373 $tags = $this->strip_htmltags
;
1375 $this->sanitize
->strip_htmltags($tags);
1376 if ($encode !== null)
1378 $this->sanitize
->encode_instead_of_strip($tags);
1382 public function encode_instead_of_strip($enable = true)
1384 $this->sanitize
->encode_instead_of_strip($enable);
1387 public function strip_attributes($attribs = '')
1389 if ($attribs === '')
1391 $attribs = $this->strip_attributes
;
1393 $this->sanitize
->strip_attributes($attribs);
1396 public function set_output_encoding($encoding = 'UTF-8')
1398 $this->sanitize
->set_output_encoding($encoding);
1401 public function strip_comments($strip = false)
1403 $this->sanitize
->strip_comments($strip);
1407 * Set element/attribute key/value pairs of HTML attributes
1408 * containing URLs that need to be resolved relative to the feed
1412 * @param array $element_attribute Element/attribute key/value pairs
1414 public 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'))
1416 $this->sanitize
->set_url_replacements($element_attribute);
1420 * Set the handler to enable the display of cached images.
1423 * @param str $page Web-accessible path to the handler_image.php file.
1424 * @param str $qs The query string that the value should be passed to.
1426 public function set_image_handler($page = false, $qs = 'i')
1428 if ($page !== false)
1430 $this->sanitize
->set_image_handler($page . '?' . $qs . '=');
1434 $this->image_handler
= '';
1439 * Set the limit for items returned per-feed with multifeeds.
1442 * @param integer $limit The maximum number of items to return.
1444 public function set_item_limit($limit = 0)
1446 $this->item_limit
= (int) $limit;
1449 public function init()
1451 // Check absolute bare minimum requirements.
1452 if ((function_exists('version_compare') && version_compare(PHP_VERSION
, '5.0', '<')) ||
!extension_loaded('xml') ||
!extension_loaded('pcre'))
1456 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1457 elseif (!extension_loaded('xmlreader'))
1459 static $xml_is_sane = null;
1460 if ($xml_is_sane === null)
1462 $parser_check = xml_parser_create();
1463 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1464 xml_parser_free($parser_check);
1465 $xml_is_sane = isset($values[0]['value']);
1473 if (isset($_GET[$this->javascript
]))
1475 SimplePie_Misc
::output_javascript();
1479 // Pass whatever was set with config options over to the sanitizer.
1480 $this->sanitize
->pass_cache_data($this->cache
, $this->cache_location
, $this->cache_name_function
, $this->cache_class
);
1481 $this->sanitize
->pass_file_data($this->file_class
, $this->timeout
, $this->useragent
, $this->force_fsockopen
);
1483 if ($this->feed_url
!== null ||
$this->raw_data
!== null)
1485 $this->error
= null;
1486 $this->data
= array();
1487 $this->multifeed_objects
= array();
1490 if ($this->feed_url
!== null)
1492 $parsed_feed_url = SimplePie_Misc
::parse_url($this->feed_url
);
1493 // Decide whether to enable caching
1494 if ($this->cache
&& $parsed_feed_url['scheme'] !== '')
1496 $cache = call_user_func(array($this->cache_class
, 'create'), $this->cache_location
, call_user_func($this->cache_name_function
, $this->feed_url
), 'spc');
1498 // If it's enabled and we don't want an XML dump, use the cache
1499 if ($cache && !$this->xml_dump
)
1502 $this->data
= $cache->load();
1503 if (!empty($this->data
))
1505 // If the cache is for an outdated build of SimplePie
1506 if (!isset($this->data
['build']) ||
$this->data
['build'] !== SIMPLEPIE_BUILD
)
1509 $this->data
= array();
1511 // If we've hit a collision just rerun it with caching disabled
1512 elseif (isset($this->data
['url']) && $this->data
['url'] !== $this->feed_url
)
1515 $this->data
= array();
1517 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1518 elseif (isset($this->data
['feed_url']))
1520 // If the autodiscovery cache is still valid use it.
1521 if ($cache->mtime() +
$this->autodiscovery_cache_duration
> time())
1523 // Do not need to do feed autodiscovery yet.
1524 if ($this->data
['feed_url'] === $this->data
['url'])
1527 $this->data
= array();
1531 $this->set_feed_url($this->data
['feed_url']);
1532 return $this->init();
1536 // Check if the cache has been updated
1537 elseif ($cache->mtime() +
$this->cache_duration
< time())
1539 // If we have last-modified and/or etag set
1540 if (isset($this->data
['headers']['last-modified']) ||
isset($this->data
['headers']['etag']))
1543 if (isset($this->data
['headers']['last-modified']))
1545 $headers['if-modified-since'] = $this->data
['headers']['last-modified'];
1547 if (isset($this->data
['headers']['etag']))
1549 $headers['if-none-match'] = '"' . $this->data
['headers']['etag'] . '"';
1552 $file = new $this->file_class($this->feed_url
, $this->timeout
/10, 5, $headers, $this->useragent
, $this->force_fsockopen
);
1556 if ($file->status_code
=== 304)
1563 $headers = $file->headers
;
1572 // If the cache is still valid, just return true
1578 // If the cache is empty, delete it
1582 $this->data
= array();
1585 // 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.
1588 if (is_a($this->file
, 'SimplePie_File') && $this->file
->url
=== $this->feed_url
)
1590 $file =& $this->file
;
1594 $file = new $this->file_class($this->feed_url
, $this->timeout
, 5, null, $this->useragent
, $this->force_fsockopen
);
1597 // If the file connection has an error, set SimplePie::error to that and quit
1598 if (!$file->success
&& !($file->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
=== 0 ||
($file->status_code
=== 200 ||
$file->status_code
> 206 && $file->status_code
< 300)))
1600 $this->error
= $file->error
;
1601 if (!empty($this->data
))
1611 if (!$this->force_feed
)
1613 // Check if the supplied URL is a feed, if it isn't, look for it.
1614 $locate = new $this->locator_class($file, $this->timeout
, $this->useragent
, $this->file_class
, $this->max_checked_feeds
, $this->content_type_sniffer_class
);
1616 if (!$locate->is_feed($file))
1618 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1620 if ($file = $locate->find($this->autodiscovery
, $this->all_discovered_feeds
))
1624 $this->data
= array('url' => $this->feed_url
, 'feed_url' => $file->url
, 'build' => SIMPLEPIE_BUILD
);
1625 if (!$cache->save($this))
1627 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING
);
1629 $cache = call_user_func(array($this->cache_class
, 'create'), $this->cache_location
, call_user_func($this->cache_name_function
, $file->url
), 'spc');
1631 $this->feed_url
= $file->url
;
1635 $this->error
= "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME
. " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
1636 SimplePie_Misc
::error($this->error
, E_USER_NOTICE
, __FILE__
, __LINE__
);
1643 $headers = $file->headers
;
1644 $data = $file->body
;
1645 $sniffer = new $this->content_type_sniffer_class($file);
1646 $sniffed = $sniffer->get_type();
1650 $data = $this->raw_data
;
1653 // Set up array of possible encodings
1654 $encodings = array();
1656 // First check to see if input has been overridden.
1657 if ($this->input_encoding
!== false)
1659 $encodings[] = $this->input_encoding
;
1662 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1663 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1665 // RFC 3023 (only applies to sniffed content)
1666 if (isset($sniffed))
1668 if (in_array($sniffed, $application_types) ||
substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1670 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1672 $encodings[] = strtoupper($charset[1]);
1674 $encodings = array_merge($encodings, SimplePie_Misc
::xml_encoding($data));
1675 $encodings[] = 'UTF-8';
1677 elseif (in_array($sniffed, $text_types) ||
substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1679 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1681 $encodings[] = $charset[1];
1683 $encodings[] = 'US-ASCII';
1685 // Text MIME-type default
1686 elseif (substr($sniffed, 0, 5) === 'text/')
1688 $encodings[] = 'US-ASCII';
1692 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1693 $encodings = array_merge($encodings, SimplePie_Misc
::xml_encoding($data));
1694 $encodings[] = 'UTF-8';
1695 $encodings[] = 'ISO-8859-1';
1697 // There's no point in trying an encoding twice
1698 $encodings = array_unique($encodings);
1700 // If we want the XML, just output that with the most likely encoding and quit
1701 if ($this->xml_dump
)
1703 header('Content-type: text/xml; charset=' . $encodings[0]);
1708 // Loop through each possible encoding, till we return something, or run out of possibilities
1709 foreach ($encodings as $encoding)
1711 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1712 if ($utf8_data = SimplePie_Misc
::change_encoding($data, $encoding, 'UTF-8'))
1714 // Create new parser
1715 $parser = new $this->parser_class();
1717 // If it's parsed fine
1718 if ($parser->parse($utf8_data, 'UTF-8'))
1720 $this->data
= $parser->get_data();
1721 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE
)
1723 if (isset($headers))
1725 $this->data
['headers'] = $headers;
1727 $this->data
['build'] = SIMPLEPIE_BUILD
;
1729 // Cache the file if caching is enabled
1730 if ($cache && !$cache->save($this))
1732 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING
);
1738 $this->error
= "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1739 SimplePie_Misc
::error($this->error
, E_USER_NOTICE
, __FILE__
, __LINE__
);
1748 // We have an error, just set SimplePie_Misc::error to it and quit
1749 $this->error
= sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1753 $this->error
= 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
1756 SimplePie_Misc
::error($this->error
, E_USER_NOTICE
, __FILE__
, __LINE__
);
1760 elseif (!empty($this->multifeed_url
))
1764 $this->multifeed_objects
= array();
1765 foreach ($this->multifeed_url
as $url)
1767 $this->multifeed_objects
[$i] = clone $this;
1768 $this->multifeed_objects
[$i]->set_feed_url($url);
1769 $success |
= $this->multifeed_objects
[$i]->init();
1772 return (bool) $success;
1781 * Return the error message for the occured error
1784 * @return string Error message
1786 public function error()
1788 return $this->error
;
1791 public function get_encoding()
1793 return $this->sanitize
->output_encoding
;
1796 public function handle_content_type($mime = 'text/html')
1798 if (!headers_sent())
1800 $header = "Content-type: $mime;";
1801 if ($this->get_encoding())
1803 $header .= ' charset=' . $this->get_encoding();
1807 $header .= ' charset=UTF-8';
1813 public function get_type()
1815 if (!isset($this->data
['type']))
1817 $this->data
['type'] = SIMPLEPIE_TYPE_ALL
;
1818 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed']))
1820 $this->data
['type'] &= SIMPLEPIE_TYPE_ATOM_10
;
1822 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed']))
1824 $this->data
['type'] &= SIMPLEPIE_TYPE_ATOM_03
;
1826 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF']))
1828 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['channel'])
1829 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['image'])
1830 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['item'])
1831 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['textinput']))
1833 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_10
;
1835 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['channel'])
1836 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['image'])
1837 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['item'])
1838 ||
isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['textinput']))
1840 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_090
;
1843 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss']))
1845 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_ALL
;
1846 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['attribs']['']['version']))
1848 switch (trim($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['attribs']['']['version']))
1851 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_091
;
1852 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['skiphours']['hour'][0]['data']))
1854 switch (trim($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['skiphours']['hour'][0]['data']))
1857 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE
;
1861 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND
;
1868 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_092
;
1872 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_093
;
1876 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_094
;
1880 $this->data
['type'] &= SIMPLEPIE_TYPE_RSS_20
;
1887 $this->data
['type'] = SIMPLEPIE_TYPE_NONE
;
1890 return $this->data
['type'];
1894 * @todo If we have a perm redirect we should return the new URL
1895 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1896 * @todo Also, |atom:link|@rel=self
1898 public function subscribe_url()
1900 if ($this->feed_url
!== null)
1902 return $this->sanitize($this->feed_url
, SIMPLEPIE_CONSTRUCT_IRI
);
1910 public function get_feed_tags($namespace, $tag)
1912 $type = $this->get_type();
1913 if ($type & SIMPLEPIE_TYPE_ATOM_10
)
1915 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]['child'][$namespace][$tag]))
1917 return $this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]['child'][$namespace][$tag];
1920 if ($type & SIMPLEPIE_TYPE_ATOM_03
)
1922 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]['child'][$namespace][$tag]))
1924 return $this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]['child'][$namespace][$tag];
1927 if ($type & SIMPLEPIE_TYPE_RSS_RDF
)
1929 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][$namespace][$tag]))
1931 return $this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['child'][$namespace][$tag];
1934 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION
)
1936 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][$namespace][$tag]))
1938 return $this->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][$namespace][$tag];
1944 public function get_channel_tags($namespace, $tag)
1946 $type = $this->get_type();
1947 if ($type & SIMPLEPIE_TYPE_ATOM_ALL
)
1949 if ($return = $this->get_feed_tags($namespace, $tag))
1954 if ($type & SIMPLEPIE_TYPE_RSS_10
)
1956 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'channel'))
1958 if (isset($channel[0]['child'][$namespace][$tag]))
1960 return $channel[0]['child'][$namespace][$tag];
1964 if ($type & SIMPLEPIE_TYPE_RSS_090
)
1966 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'channel'))
1968 if (isset($channel[0]['child'][$namespace][$tag]))
1970 return $channel[0]['child'][$namespace][$tag];
1974 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION
)
1976 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'channel'))
1978 if (isset($channel[0]['child'][$namespace][$tag]))
1980 return $channel[0]['child'][$namespace][$tag];
1987 public function get_image_tags($namespace, $tag)
1989 $type = $this->get_type();
1990 if ($type & SIMPLEPIE_TYPE_RSS_10
)
1992 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'image'))
1994 if (isset($image[0]['child'][$namespace][$tag]))
1996 return $image[0]['child'][$namespace][$tag];
2000 if ($type & SIMPLEPIE_TYPE_RSS_090
)
2002 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'image'))
2004 if (isset($image[0]['child'][$namespace][$tag]))
2006 return $image[0]['child'][$namespace][$tag];
2010 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION
)
2012 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'image'))
2014 if (isset($image[0]['child'][$namespace][$tag]))
2016 return $image[0]['child'][$namespace][$tag];
2023 public function get_base($element = array())
2025 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION
) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2027 return $element['xml_base'];
2029 elseif ($this->get_link() !== null)
2031 return $this->get_link();
2035 return $this->subscribe_url();
2039 public function sanitize($data, $type, $base = '')
2041 return $this->sanitize
->sanitize($data, $type, $base);
2044 public function get_title()
2046 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'title'))
2048 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2050 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'title'))
2052 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2054 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'title'))
2056 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2058 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'title'))
2060 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2062 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'title'))
2064 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2066 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'title'))
2068 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2070 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'title'))
2072 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2080 public function get_category($key = 0)
2082 $categories = $this->get_categories();
2083 if (isset($categories[$key]))
2085 return $categories[$key];
2093 public function get_categories()
2095 $categories = array();
2097 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'category') as $category)
2102 if (isset($category['attribs']['']['term']))
2104 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT
);
2106 if (isset($category['attribs']['']['scheme']))
2108 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
2110 if (isset($category['attribs']['']['label']))
2112 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
2114 $categories[] = new $this->category_class($term, $scheme, $label);
2116 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'category') as $category)
2118 // This is really the label, but keep this as the term also for BC.
2119 // Label will also work on retrieving because that falls back to term.
2120 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2121 if (isset($category['attribs']['']['domain']))
2123 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT
);
2129 $categories[] = new $this->category_class($term, $scheme, null);
2131 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'subject') as $category)
2133 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
2135 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'subject') as $category)
2137 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
2140 if (!empty($categories))
2142 return SimplePie_Misc
::array_unique($categories);
2150 public function get_author($key = 0)
2152 $authors = $this->get_authors();
2153 if (isset($authors[$key]))
2155 return $authors[$key];
2163 public function get_authors()
2166 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'author') as $author)
2171 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
2173 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2175 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
2177 $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]));
2179 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
2181 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2183 if ($name !== null ||
$email !== null ||
$uri !== null)
2185 $authors[] = new $this->author_class($name, $uri, $email);
2188 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'author'))
2193 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
2195 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2197 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
2199 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
2201 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
2203 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2205 if ($name !== null ||
$email !== null ||
$url !== null)
2207 $authors[] = new $this->author_class($name, $url, $email);
2210 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'creator') as $author)
2212 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
2214 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'creator') as $author)
2216 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
2218 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'author') as $author)
2220 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
2223 if (!empty($authors))
2225 return SimplePie_Misc
::array_unique($authors);
2233 public function get_contributor($key = 0)
2235 $contributors = $this->get_contributors();
2236 if (isset($contributors[$key]))
2238 return $contributors[$key];
2246 public function get_contributors()
2248 $contributors = array();
2249 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'contributor') as $contributor)
2254 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
2256 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2258 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
2260 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]));
2262 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
2264 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2266 if ($name !== null ||
$email !== null ||
$uri !== null)
2268 $contributors[] = new $this->author_class($name, $uri, $email);
2271 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'contributor') as $contributor)
2276 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
2278 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2280 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
2282 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
2284 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
2286 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2288 if ($name !== null ||
$email !== null ||
$url !== null)
2290 $contributors[] = new $this->author_class($name, $url, $email);
2294 if (!empty($contributors))
2296 return SimplePie_Misc
::array_unique($contributors);
2304 public function get_link($key = 0, $rel = 'alternate')
2306 $links = $this->get_links($rel);
2307 if (isset($links[$key]))
2309 return $links[$key];
2318 * Added for parity between the parent-level and the item/entry-level.
2320 public function get_permalink()
2322 return $this->get_link(0);
2325 public function get_links($rel = 'alternate')
2327 if (!isset($this->data
['links']))
2329 $this->data
['links'] = array();
2330 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'link'))
2332 foreach ($links as $link)
2334 if (isset($link['attribs']['']['href']))
2336 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
2337 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
2341 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'link'))
2343 foreach ($links as $link)
2345 if (isset($link['attribs']['']['href']))
2347 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
2348 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
2353 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'link'))
2355 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
2357 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'link'))
2359 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
2361 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'link'))
2363 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
2366 $keys = array_keys($this->data
['links']);
2367 foreach ($keys as $key)
2369 if (SimplePie_Misc
::is_isegment_nz_nc($key))
2371 if (isset($this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]))
2373 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] = array_merge($this->data
['links'][$key], $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]);
2374 $this->data
['links'][$key] =& $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key];
2378 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] =& $this->data
['links'][$key];
2381 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
)
2383 $this->data
['links'][substr($key, 41)] =& $this->data
['links'][$key];
2385 $this->data
['links'][$key] = array_unique($this->data
['links'][$key]);
2389 if (isset($this->data
['links'][$rel]))
2391 return $this->data
['links'][$rel];
2399 public function get_all_discovered_feeds()
2401 return $this->all_discovered_feeds
;
2404 public function get_description()
2406 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'subtitle'))
2408 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2410 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'tagline'))
2412 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2414 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'description'))
2416 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2418 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'description'))
2420 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2422 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'description'))
2424 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
2426 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'description'))
2428 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2430 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'description'))
2432 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2434 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'summary'))
2436 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
2438 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'subtitle'))
2440 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
2448 public function get_copyright()
2450 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'rights'))
2452 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2454 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'copyright'))
2456 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2458 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'copyright'))
2460 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2462 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'rights'))
2464 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2466 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'rights'))
2468 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2476 public function get_language()
2478 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'language'))
2480 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2482 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'language'))
2484 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2486 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'language'))
2488 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2490 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]['xml_lang']))
2492 return $this->sanitize($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
2494 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]['xml_lang']))
2496 return $this->sanitize($this->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
2498 elseif (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['xml_lang']))
2500 return $this->sanitize($this->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
2502 elseif (isset($this->data
['headers']['content-language']))
2504 return $this->sanitize($this->data
['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT
);
2512 public function get_latitude()
2515 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lat'))
2517 return (float) $return[0]['data'];
2519 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2521 return (float) $match[1];
2529 public function get_longitude()
2531 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'long'))
2533 return (float) $return[0]['data'];
2535 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lon'))
2537 return (float) $return[0]['data'];
2539 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2541 return (float) $match[2];
2549 public function get_image_title()
2551 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'title'))
2553 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2555 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'title'))
2557 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2559 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'title'))
2561 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2563 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'title'))
2565 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2567 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'title'))
2569 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2577 public function get_image_url()
2579 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'image'))
2581 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
);
2583 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'logo'))
2585 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2587 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'icon'))
2589 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2591 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'url'))
2593 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2595 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'url'))
2597 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2599 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'url'))
2601 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2609 public function get_image_link()
2611 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'link'))
2613 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2615 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'link'))
2617 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2619 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'link'))
2621 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
2629 public function get_image_width()
2631 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'width'))
2633 return round($return[0]['data']);
2635 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION
&& $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'url'))
2645 public function get_image_height()
2647 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'height'))
2649 return round($return[0]['data']);
2651 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION
&& $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'url'))
2661 public function get_item_quantity($max = 0)
2664 $qty = count($this->get_items());
2671 return ($qty > $max) ?
$max : $qty;
2675 public function get_item($key = 0)
2677 $items = $this->get_items();
2678 if (isset($items[$key]))
2680 return $items[$key];
2688 public function get_items($start = 0, $end = 0)
2690 if (!isset($this->data
['items']))
2692 if (!empty($this->multifeed_objects
))
2694 $this->data
['items'] = SimplePie
::merge_items($this->multifeed_objects
, $start, $end, $this->item_limit
);
2698 $this->data
['items'] = array();
2699 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'entry'))
2701 $keys = array_keys($items);
2702 foreach ($keys as $key)
2704 $this->data
['items'][] = new $this->item_class($this, $items[$key]);
2707 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'entry'))
2709 $keys = array_keys($items);
2710 foreach ($keys as $key)
2712 $this->data
['items'][] = new $this->item_class($this, $items[$key]);
2715 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'item'))
2717 $keys = array_keys($items);
2718 foreach ($keys as $key)
2720 $this->data
['items'][] = new $this->item_class($this, $items[$key]);
2723 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'item'))
2725 $keys = array_keys($items);
2726 foreach ($keys as $key)
2728 $this->data
['items'][] = new $this->item_class($this, $items[$key]);
2731 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'item'))
2733 $keys = array_keys($items);
2734 foreach ($keys as $key)
2736 $this->data
['items'][] = new $this->item_class($this, $items[$key]);
2742 if (!empty($this->data
['items']))
2744 // If we want to order it by date, check if all items have a date, and then sort it
2745 if ($this->order_by_date
&& empty($this->multifeed_objects
))
2747 if (!isset($this->data
['ordered_items']))
2750 foreach ($this->data
['items'] as $item)
2752 if (!$item->get_date('U'))
2759 $this->data
['ordered_items'] = $this->data
['items'];
2762 usort($this->data
['ordered_items'], array(&$this, 'sort_items'));
2765 $items = $this->data
['ordered_items'];
2769 $items = $this->data
['items'];
2772 // Slice the data as desired
2775 return array_slice($items, $start);
2779 return array_slice($items, $start, $end);
2791 public function sort_items($a, $b)
2793 return $a->get_date('U') <= $b->get_date('U');
2799 public function merge_items($urls, $start = 0, $end = 0, $limit = 0)
2801 if (is_array($urls) && sizeof($urls) > 0)
2804 foreach ($urls as $arg)
2806 if (is_a($arg, 'SimplePie'))
2808 $items = array_merge($items, $arg->get_items(0, $limit));
2812 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING
);
2817 foreach ($items as $item)
2819 if (!$item->get_date('U'))
2828 usort($items, array('SimplePie', 'sort_items'));
2833 return array_slice($items, $start);
2837 return array_slice($items, $start, $end);
2842 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING
);
2848 class SimplePie_Item
2851 var $data = array();
2853 public function __construct($feed, $data)
2855 $this->feed
= $feed;
2856 $this->data
= $data;
2859 public function __toString()
2861 return md5(serialize($this->data
));
2865 * Remove items that link back to this before destroying this object
2867 public function __destruct()
2869 if ((version_compare(PHP_VERSION
, '5.3', '<') ||
!gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
2875 public function get_item_tags($namespace, $tag)
2877 if (isset($this->data
['child'][$namespace][$tag]))
2879 return $this->data
['child'][$namespace][$tag];
2887 public function get_base($element = array())
2889 return $this->feed
->get_base($element);
2892 public function sanitize($data, $type, $base = '')
2894 return $this->feed
->sanitize($data, $type, $base);
2897 public function get_feed()
2902 public function get_id($hash = false)
2906 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'id'))
2908 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2910 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'id'))
2912 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2914 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'guid'))
2916 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2918 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'identifier'))
2920 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2922 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'identifier'))
2924 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2926 elseif (($return = $this->get_permalink()) !== null)
2930 elseif (($return = $this->get_title()) !== null)
2935 if ($this->get_permalink() !== null ||
$this->get_title() !== null)
2937 return md5($this->get_permalink() . $this->get_title());
2941 return md5(serialize($this->data
));
2945 public function get_title()
2947 if (!isset($this->data
['title']))
2949 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'title'))
2951 $this->data
['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2953 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'title'))
2955 $this->data
['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2957 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'title'))
2959 $this->data
['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2961 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'title'))
2963 $this->data
['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2965 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'title'))
2967 $this->data
['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2969 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'title'))
2971 $this->data
['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2973 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'title'))
2975 $this->data
['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
2979 $this->data
['title'] = null;
2982 return $this->data
['title'];
2985 public function get_description($description_only = false)
2987 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'summary'))
2989 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2991 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'summary'))
2993 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2995 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'description'))
2997 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
2999 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'description'))
3001 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
3003 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'description'))
3005 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3007 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'description'))
3009 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3011 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'summary'))
3013 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
3015 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'subtitle'))
3017 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3019 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'description'))
3021 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
);
3024 elseif (!$description_only)
3026 return $this->get_content(true);
3034 public function get_content($content_only = false)
3036 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'content'))
3038 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3040 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'content'))
3042 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3044 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT
, 'encoded'))
3046 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
3048 elseif (!$content_only)
3050 return $this->get_description(true);
3058 public function get_category($key = 0)
3060 $categories = $this->get_categories();
3061 if (isset($categories[$key]))
3063 return $categories[$key];
3071 public function get_categories()
3073 $categories = array();
3075 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'category') as $category)
3080 if (isset($category['attribs']['']['term']))
3082 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT
);
3084 if (isset($category['attribs']['']['scheme']))
3086 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3088 if (isset($category['attribs']['']['label']))
3090 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
3092 $categories[] = new $this->feed
->category_class($term, $scheme, $label);
3094 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'category') as $category)
3096 // This is really the label, but keep this as the term also for BC.
3097 // Label will also work on retrieving because that falls back to term.
3098 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3099 if (isset($category['attribs']['']['domain']))
3101 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT
);
3107 $categories[] = new $this->feed
->category_class($term, $scheme, null);
3109 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'subject') as $category)
3111 $categories[] = new $this->feed
->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
3113 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'subject') as $category)
3115 $categories[] = new $this->feed
->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
3118 if (!empty($categories))
3120 return SimplePie_Misc
::array_unique($categories);
3128 public function get_author($key = 0)
3130 $authors = $this->get_authors();
3131 if (isset($authors[$key]))
3133 return $authors[$key];
3141 public function get_contributor($key = 0)
3143 $contributors = $this->get_contributors();
3144 if (isset($contributors[$key]))
3146 return $contributors[$key];
3154 public function get_contributors()
3156 $contributors = array();
3157 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'contributor') as $contributor)
3162 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
3164 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3166 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
3168 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]));
3170 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
3172 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3174 if ($name !== null ||
$email !== null ||
$uri !== null)
3176 $contributors[] = new $this->feed
->author_class($name, $uri, $email);
3179 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'contributor') as $contributor)
3184 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
3186 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3188 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
3190 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
3192 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
3194 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3196 if ($name !== null ||
$email !== null ||
$url !== null)
3198 $contributors[] = new $this->feed
->author_class($name, $url, $email);
3202 if (!empty($contributors))
3204 return SimplePie_Misc
::array_unique($contributors);
3212 public function get_authors()
3215 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'author') as $author)
3220 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
3222 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3224 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
3226 $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]));
3228 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
3230 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3232 if ($name !== null ||
$email !== null ||
$uri !== null)
3234 $authors[] = new $this->feed
->author_class($name, $uri, $email);
3237 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'author'))
3242 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
3244 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3246 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
3248 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
3250 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
3252 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3254 if ($name !== null ||
$email !== null ||
$url !== null)
3256 $authors[] = new $this->feed
->author_class($name, $url, $email);
3259 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'author'))
3261 $authors[] = new $this->feed
->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3263 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'creator') as $author)
3265 $authors[] = new $this->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
3267 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'creator') as $author)
3269 $authors[] = new $this->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
3271 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'author') as $author)
3273 $authors[] = new $this->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
3276 if (!empty($authors))
3278 return SimplePie_Misc
::array_unique($authors);
3280 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3284 elseif ($authors = $this->feed
->get_authors())
3294 public function get_copyright()
3296 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'rights'))
3298 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3300 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'rights'))
3302 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3304 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'rights'))
3306 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3314 public function get_date($date_format = 'j F Y, g:i a')
3316 if (!isset($this->data
['date']))
3318 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'published'))
3320 $this->data
['date']['raw'] = $return[0]['data'];
3322 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'updated'))
3324 $this->data
['date']['raw'] = $return[0]['data'];
3326 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'issued'))
3328 $this->data
['date']['raw'] = $return[0]['data'];
3330 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'created'))
3332 $this->data
['date']['raw'] = $return[0]['data'];
3334 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'modified'))
3336 $this->data
['date']['raw'] = $return[0]['data'];
3338 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'pubDate'))
3340 $this->data
['date']['raw'] = $return[0]['data'];
3342 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'date'))
3344 $this->data
['date']['raw'] = $return[0]['data'];
3346 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'date'))
3348 $this->data
['date']['raw'] = $return[0]['data'];
3351 if (!empty($this->data
['date']['raw']))
3353 $parser = SimplePie_Parse_Date
::get();
3354 $this->data
['date']['parsed'] = $parser->parse($this->data
['date']['raw']);
3358 $this->data
['date'] = null;
3361 if ($this->data
['date'])
3363 $date_format = (string) $date_format;
3364 switch ($date_format)
3367 return $this->sanitize($this->data
['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT
);
3370 return $this->data
['date']['parsed'];
3373 return date($date_format, $this->data
['date']['parsed']);
3382 public function get_local_date($date_format = '%c')
3386 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT
);
3388 elseif (($date = $this->get_date('U')) !== null && $date !== false)
3390 return strftime($date_format, $date);
3398 public function get_permalink()
3400 $link = $this->get_link();
3401 $enclosure = $this->get_enclosure(0);
3406 elseif ($enclosure !== null)
3408 return $enclosure->get_link();
3416 public function get_link($key = 0, $rel = 'alternate')
3418 $links = $this->get_links($rel);
3419 if ($links[$key] !== null)
3421 return $links[$key];
3429 public function get_links($rel = 'alternate')
3431 if (!isset($this->data
['links']))
3433 $this->data
['links'] = array();
3434 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'link') as $link)
3436 if (isset($link['attribs']['']['href']))
3438 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
3439 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
3443 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'link') as $link)
3445 if (isset($link['attribs']['']['href']))
3447 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
3448 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
3451 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'link'))
3453 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
3455 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'link'))
3457 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
3459 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'link'))
3461 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
3463 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'guid'))
3465 if (!isset($links[0]['attribs']['']['isPermaLink']) ||
strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
3467 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
3471 $keys = array_keys($this->data
['links']);
3472 foreach ($keys as $key)
3474 if (SimplePie_Misc
::is_isegment_nz_nc($key))
3476 if (isset($this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]))
3478 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] = array_merge($this->data
['links'][$key], $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]);
3479 $this->data
['links'][$key] =& $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key];
3483 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] =& $this->data
['links'][$key];
3486 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
)
3488 $this->data
['links'][substr($key, 41)] =& $this->data
['links'][$key];
3490 $this->data
['links'][$key] = array_unique($this->data
['links'][$key]);
3493 if (isset($this->data
['links'][$rel]))
3495 return $this->data
['links'][$rel];
3504 * @todo Add ability to prefer one type of content over another (in a media group).
3506 public function get_enclosure($key = 0, $prefer = null)
3508 $enclosures = $this->get_enclosures();
3509 if (isset($enclosures[$key]))
3511 return $enclosures[$key];
3520 * Grabs all available enclosures (podcasts, etc.)
3522 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3524 * 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.
3526 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3527 * @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).
3529 public function get_enclosures()
3531 if (!isset($this->data
['enclosures']))
3533 $this->data
['enclosures'] = array();
3536 $captions_parent = null;
3537 $categories_parent = null;
3538 $copyrights_parent = null;
3539 $credits_parent = null;
3540 $description_parent = null;
3541 $duration_parent = null;
3542 $hashes_parent = null;
3543 $keywords_parent = null;
3544 $player_parent = null;
3545 $ratings_parent = null;
3546 $restrictions_parent = null;
3547 $thumbnails_parent = null;
3548 $title_parent = null;
3550 // Let's do the channel and item-level ones first, and just re-use them if we need to.
3551 $parent = $this->get_feed();
3554 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'text'))
3556 foreach ($captions as $caption)
3558 $caption_type = null;
3559 $caption_lang = null;
3560 $caption_startTime = null;
3561 $caption_endTime = null;
3562 $caption_text = null;
3563 if (isset($caption['attribs']['']['type']))
3565 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
3567 if (isset($caption['attribs']['']['lang']))
3569 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
3571 if (isset($caption['attribs']['']['start']))
3573 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT
);
3575 if (isset($caption['attribs']['']['end']))
3577 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT
);
3579 if (isset($caption['data']))
3581 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3583 $captions_parent[] = new $this->feed
->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3586 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'text'))
3588 foreach ($captions as $caption)
3590 $caption_type = null;
3591 $caption_lang = null;
3592 $caption_startTime = null;
3593 $caption_endTime = null;
3594 $caption_text = null;
3595 if (isset($caption['attribs']['']['type']))
3597 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
3599 if (isset($caption['attribs']['']['lang']))
3601 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
3603 if (isset($caption['attribs']['']['start']))
3605 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT
);
3607 if (isset($caption['attribs']['']['end']))
3609 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT
);
3611 if (isset($caption['data']))
3613 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3615 $captions_parent[] = new $this->feed
->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3618 if (is_array($captions_parent))
3620 $captions_parent = array_values(SimplePie_Misc
::array_unique($captions_parent));
3624 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'category') as $category)
3629 if (isset($category['data']))
3631 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3633 if (isset($category['attribs']['']['scheme']))
3635 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3639 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3641 if (isset($category['attribs']['']['label']))
3643 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
3645 $categories_parent[] = new $this->feed
->category_class($term, $scheme, $label);
3647 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'category') as $category)
3652 if (isset($category['data']))
3654 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3656 if (isset($category['attribs']['']['scheme']))
3658 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3662 $scheme = 'http://search.yahoo.com/mrss/category_schema';
3664 if (isset($category['attribs']['']['label']))
3666 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
3668 $categories_parent[] = new $this->feed
->category_class($term, $scheme, $label);
3670 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'category') as $category)
3673 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3675 if (isset($category['attribs']['']['text']))
3677 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT
);
3679 $categories_parent[] = new $this->feed
->category_class($term, $scheme, $label);
3681 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES
]['category']))
3683 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES
]['category'] as $subcategory)
3685 if (isset($subcategory['attribs']['']['text']))
3687 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT
);
3689 $categories_parent[] = new $this->feed
->category_class($term, $scheme, $label);
3693 if (is_array($categories_parent))
3695 $categories_parent = array_values(SimplePie_Misc
::array_unique($categories_parent));
3699 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'copyright'))
3701 $copyright_url = null;
3702 $copyright_label = null;
3703 if (isset($copyright[0]['attribs']['']['url']))
3705 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT
);
3707 if (isset($copyright[0]['data']))
3709 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3711 $copyrights_parent = new $this->feed
->copyright_class($copyright_url, $copyright_label);
3713 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'copyright'))
3715 $copyright_url = null;
3716 $copyright_label = null;
3717 if (isset($copyright[0]['attribs']['']['url']))
3719 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT
);
3721 if (isset($copyright[0]['data']))
3723 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3725 $copyrights_parent = new $this->feed
->copyright_class($copyright_url, $copyright_label);
3729 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'credit'))
3731 foreach ($credits as $credit)
3733 $credit_role = null;
3734 $credit_scheme = null;
3735 $credit_name = null;
3736 if (isset($credit['attribs']['']['role']))
3738 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT
);
3740 if (isset($credit['attribs']['']['scheme']))
3742 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3746 $credit_scheme = 'urn:ebu';
3748 if (isset($credit['data']))
3750 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3752 $credits_parent[] = new $this->feed
->credit_class($credit_role, $credit_scheme, $credit_name);
3755 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'credit'))
3757 foreach ($credits as $credit)
3759 $credit_role = null;
3760 $credit_scheme = null;
3761 $credit_name = null;
3762 if (isset($credit['attribs']['']['role']))
3764 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT
);
3766 if (isset($credit['attribs']['']['scheme']))
3768 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3772 $credit_scheme = 'urn:ebu';
3774 if (isset($credit['data']))
3776 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3778 $credits_parent[] = new $this->feed
->credit_class($credit_role, $credit_scheme, $credit_name);
3781 if (is_array($credits_parent))
3783 $credits_parent = array_values(SimplePie_Misc
::array_unique($credits_parent));
3787 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'description'))
3789 if (isset($description_parent[0]['data']))
3791 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3794 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'description'))
3796 if (isset($description_parent[0]['data']))
3798 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3803 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'duration'))
3808 if (isset($duration_parent[0]['data']))
3810 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3811 if (sizeof($temp) > 0)
3813 $seconds = (int) array_pop($temp);
3815 if (sizeof($temp) > 0)
3817 $minutes = (int) array_pop($temp);
3818 $seconds +
= $minutes * 60;
3820 if (sizeof($temp) > 0)
3822 $hours = (int) array_pop($temp);
3823 $seconds +
= $hours * 3600;
3826 $duration_parent = $seconds;
3831 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'hash'))
3833 foreach ($hashes_iterator as $hash)
3837 if (isset($hash['data']))
3839 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3841 if (isset($hash['attribs']['']['algo']))
3843 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT
);
3849 $hashes_parent[] = $algo.':'.$value;
3852 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'hash'))
3854 foreach ($hashes_iterator as $hash)
3858 if (isset($hash['data']))
3860 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3862 if (isset($hash['attribs']['']['algo']))
3864 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT
);
3870 $hashes_parent[] = $algo.':'.$value;
3873 if (is_array($hashes_parent))
3875 $hashes_parent = array_values(SimplePie_Misc
::array_unique($hashes_parent));
3879 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'keywords'))
3881 if (isset($keywords[0]['data']))
3883 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3884 foreach ($temp as $word)
3886 $keywords_parent[] = trim($word);
3891 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'keywords'))
3893 if (isset($keywords[0]['data']))
3895 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3896 foreach ($temp as $word)
3898 $keywords_parent[] = trim($word);
3903 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'keywords'))
3905 if (isset($keywords[0]['data']))
3907 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3908 foreach ($temp as $word)
3910 $keywords_parent[] = trim($word);
3915 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'keywords'))
3917 if (isset($keywords[0]['data']))
3919 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
3920 foreach ($temp as $word)
3922 $keywords_parent[] = trim($word);
3927 if (is_array($keywords_parent))
3929 $keywords_parent = array_values(SimplePie_Misc
::array_unique($keywords_parent));
3933 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'player'))
3935 if (isset($player_parent[0]['attribs']['']['url']))
3937 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
3940 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'player'))
3942 if (isset($player_parent[0]['attribs']['']['url']))
3944 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
3949 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'rating'))
3951 foreach ($ratings as $rating)
3953 $rating_scheme = null;
3954 $rating_value = null;
3955 if (isset($rating['attribs']['']['scheme']))
3957 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3961 $rating_scheme = 'urn:simple';
3963 if (isset($rating['data']))
3965 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3967 $ratings_parent[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
3970 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'explicit'))
3972 foreach ($ratings as $rating)
3974 $rating_scheme = 'urn:itunes';
3975 $rating_value = null;
3976 if (isset($rating['data']))
3978 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
3980 $ratings_parent[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
3983 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'rating'))
3985 foreach ($ratings as $rating)
3987 $rating_scheme = null;
3988 $rating_value = null;
3989 if (isset($rating['attribs']['']['scheme']))
3991 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
3995 $rating_scheme = 'urn:simple';
3997 if (isset($rating['data']))
3999 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4001 $ratings_parent[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
4004 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'explicit'))
4006 foreach ($ratings as $rating)
4008 $rating_scheme = 'urn:itunes';
4009 $rating_value = null;
4010 if (isset($rating['data']))
4012 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4014 $ratings_parent[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
4017 if (is_array($ratings_parent))
4019 $ratings_parent = array_values(SimplePie_Misc
::array_unique($ratings_parent));
4023 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'restriction'))
4025 foreach ($restrictions as $restriction)
4027 $restriction_relationship = null;
4028 $restriction_type = null;
4029 $restriction_value = null;
4030 if (isset($restriction['attribs']['']['relationship']))
4032 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT
);
4034 if (isset($restriction['attribs']['']['type']))
4036 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4038 if (isset($restriction['data']))
4040 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4042 $restrictions_parent[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4045 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'block'))
4047 foreach ($restrictions as $restriction)
4049 $restriction_relationship = 'allow';
4050 $restriction_type = null;
4051 $restriction_value = 'itunes';
4052 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4054 $restriction_relationship = 'deny';
4056 $restrictions_parent[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4059 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'restriction'))
4061 foreach ($restrictions as $restriction)
4063 $restriction_relationship = null;
4064 $restriction_type = null;
4065 $restriction_value = null;
4066 if (isset($restriction['attribs']['']['relationship']))
4068 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT
);
4070 if (isset($restriction['attribs']['']['type']))
4072 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4074 if (isset($restriction['data']))
4076 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4078 $restrictions_parent[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4081 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'block'))
4083 foreach ($restrictions as $restriction)
4085 $restriction_relationship = 'allow';
4086 $restriction_type = null;
4087 $restriction_value = 'itunes';
4088 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4090 $restriction_relationship = 'deny';
4092 $restrictions_parent[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4095 if (is_array($restrictions_parent))
4097 $restrictions_parent = array_values(SimplePie_Misc
::array_unique($restrictions_parent));
4101 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'thumbnail'))
4103 foreach ($thumbnails as $thumbnail)
4105 if (isset($thumbnail['attribs']['']['url']))
4107 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4111 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'thumbnail'))
4113 foreach ($thumbnails as $thumbnail)
4115 if (isset($thumbnail['attribs']['']['url']))
4117 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4123 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'title'))
4125 if (isset($title_parent[0]['data']))
4127 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4130 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'title'))
4132 if (isset($title_parent[0]['data']))
4134 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4152 $samplingrate = null;
4162 $description = null;
4167 $restrictions = null;
4171 // If we have media:group tags, loop through them.
4172 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS
, 'group') as $group)
4174 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['content']))
4176 // If we have media:content tags, loop through them.
4177 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['content'] as $content)
4179 if (isset($content['attribs']['']['url']))
4192 $samplingrate = null;
4202 $description = null;
4207 $restrictions = null;
4211 // Start checking the attributes of media:content
4212 if (isset($content['attribs']['']['bitrate']))
4214 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4216 if (isset($content['attribs']['']['channels']))
4218 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT
);
4220 if (isset($content['attribs']['']['duration']))
4222 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT
);
4226 $duration = $duration_parent;
4228 if (isset($content['attribs']['']['expression']))
4230 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT
);
4232 if (isset($content['attribs']['']['framerate']))
4234 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4236 if (isset($content['attribs']['']['height']))
4238 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT
);
4240 if (isset($content['attribs']['']['lang']))
4242 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
4244 if (isset($content['attribs']['']['fileSize']))
4246 $length = ceil($content['attribs']['']['fileSize']);
4248 if (isset($content['attribs']['']['medium']))
4250 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT
);
4252 if (isset($content['attribs']['']['samplingrate']))
4254 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4256 if (isset($content['attribs']['']['type']))
4258 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4260 if (isset($content['attribs']['']['width']))
4262 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT
);
4264 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4266 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4269 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text']))
4271 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text'] as $caption)
4273 $caption_type = null;
4274 $caption_lang = null;
4275 $caption_startTime = null;
4276 $caption_endTime = null;
4277 $caption_text = null;
4278 if (isset($caption['attribs']['']['type']))
4280 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4282 if (isset($caption['attribs']['']['lang']))
4284 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
4286 if (isset($caption['attribs']['']['start']))
4288 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT
);
4290 if (isset($caption['attribs']['']['end']))
4292 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT
);
4294 if (isset($caption['data']))
4296 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4298 $captions[] = new $this->feed
->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4300 if (is_array($captions))
4302 $captions = array_values(SimplePie_Misc
::array_unique($captions));
4305 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text']))
4307 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text'] as $caption)
4309 $caption_type = null;
4310 $caption_lang = null;
4311 $caption_startTime = null;
4312 $caption_endTime = null;
4313 $caption_text = null;
4314 if (isset($caption['attribs']['']['type']))
4316 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4318 if (isset($caption['attribs']['']['lang']))
4320 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
4322 if (isset($caption['attribs']['']['start']))
4324 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT
);
4326 if (isset($caption['attribs']['']['end']))
4328 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT
);
4330 if (isset($caption['data']))
4332 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4334 $captions[] = new $this->feed
->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4336 if (is_array($captions))
4338 $captions = array_values(SimplePie_Misc
::array_unique($captions));
4343 $captions = $captions_parent;
4347 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category']))
4349 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category'] as $category)
4354 if (isset($category['data']))
4356 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4358 if (isset($category['attribs']['']['scheme']))
4360 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4364 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4366 if (isset($category['attribs']['']['label']))
4368 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
4370 $categories[] = new $this->feed
->category_class($term, $scheme, $label);
4373 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category']))
4375 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category'] as $category)
4380 if (isset($category['data']))
4382 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4384 if (isset($category['attribs']['']['scheme']))
4386 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4390 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4392 if (isset($category['attribs']['']['label']))
4394 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
4396 $categories[] = new $this->feed
->category_class($term, $scheme, $label);
4399 if (is_array($categories) && is_array($categories_parent))
4401 $categories = array_values(SimplePie_Misc
::array_unique(array_merge($categories, $categories_parent)));
4403 elseif (is_array($categories))
4405 $categories = array_values(SimplePie_Misc
::array_unique($categories));
4407 elseif (is_array($categories_parent))
4409 $categories = array_values(SimplePie_Misc
::array_unique($categories_parent));
4413 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright']))
4415 $copyright_url = null;
4416 $copyright_label = null;
4417 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url']))
4419 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT
);
4421 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data']))
4423 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4425 $copyrights = new $this->feed
->copyright_class($copyright_url, $copyright_label);
4427 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright']))
4429 $copyright_url = null;
4430 $copyright_label = null;
4431 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url']))
4433 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT
);
4435 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data']))
4437 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4439 $copyrights = new $this->feed
->copyright_class($copyright_url, $copyright_label);
4443 $copyrights = $copyrights_parent;
4447 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit']))
4449 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit'] as $credit)
4451 $credit_role = null;
4452 $credit_scheme = null;
4453 $credit_name = null;
4454 if (isset($credit['attribs']['']['role']))
4456 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT
);
4458 if (isset($credit['attribs']['']['scheme']))
4460 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4464 $credit_scheme = 'urn:ebu';
4466 if (isset($credit['data']))
4468 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4470 $credits[] = new $this->feed
->credit_class($credit_role, $credit_scheme, $credit_name);
4472 if (is_array($credits))
4474 $credits = array_values(SimplePie_Misc
::array_unique($credits));
4477 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit']))
4479 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit'] as $credit)
4481 $credit_role = null;
4482 $credit_scheme = null;
4483 $credit_name = null;
4484 if (isset($credit['attribs']['']['role']))
4486 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT
);
4488 if (isset($credit['attribs']['']['scheme']))
4490 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4494 $credit_scheme = 'urn:ebu';
4496 if (isset($credit['data']))
4498 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4500 $credits[] = new $this->feed
->credit_class($credit_role, $credit_scheme, $credit_name);
4502 if (is_array($credits))
4504 $credits = array_values(SimplePie_Misc
::array_unique($credits));
4509 $credits = $credits_parent;
4513 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description']))
4515 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4517 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description']))
4519 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4523 $description = $description_parent;
4527 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash']))
4529 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash'] as $hash)
4533 if (isset($hash['data']))
4535 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4537 if (isset($hash['attribs']['']['algo']))
4539 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT
);
4545 $hashes[] = $algo.':'.$value;
4547 if (is_array($hashes))
4549 $hashes = array_values(SimplePie_Misc
::array_unique($hashes));
4552 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash']))
4554 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash'] as $hash)
4558 if (isset($hash['data']))
4560 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4562 if (isset($hash['attribs']['']['algo']))
4564 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT
);
4570 $hashes[] = $algo.':'.$value;
4572 if (is_array($hashes))
4574 $hashes = array_values(SimplePie_Misc
::array_unique($hashes));
4579 $hashes = $hashes_parent;
4583 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords']))
4585 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data']))
4587 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
4588 foreach ($temp as $word)
4590 $keywords[] = trim($word);
4594 if (is_array($keywords))
4596 $keywords = array_values(SimplePie_Misc
::array_unique($keywords));
4599 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords']))
4601 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data']))
4603 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
4604 foreach ($temp as $word)
4606 $keywords[] = trim($word);
4610 if (is_array($keywords))
4612 $keywords = array_values(SimplePie_Misc
::array_unique($keywords));
4617 $keywords = $keywords_parent;
4621 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player']))
4623 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4625 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player']))
4627 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4631 $player = $player_parent;
4635 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating']))
4637 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating'] as $rating)
4639 $rating_scheme = null;
4640 $rating_value = null;
4641 if (isset($rating['attribs']['']['scheme']))
4643 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4647 $rating_scheme = 'urn:simple';
4649 if (isset($rating['data']))
4651 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4653 $ratings[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
4655 if (is_array($ratings))
4657 $ratings = array_values(SimplePie_Misc
::array_unique($ratings));
4660 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating']))
4662 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating'] as $rating)
4664 $rating_scheme = null;
4665 $rating_value = null;
4666 if (isset($rating['attribs']['']['scheme']))
4668 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4672 $rating_scheme = 'urn:simple';
4674 if (isset($rating['data']))
4676 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4678 $ratings[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
4680 if (is_array($ratings))
4682 $ratings = array_values(SimplePie_Misc
::array_unique($ratings));
4687 $ratings = $ratings_parent;
4691 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction']))
4693 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction'] as $restriction)
4695 $restriction_relationship = null;
4696 $restriction_type = null;
4697 $restriction_value = null;
4698 if (isset($restriction['attribs']['']['relationship']))
4700 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT
);
4702 if (isset($restriction['attribs']['']['type']))
4704 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4706 if (isset($restriction['data']))
4708 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4710 $restrictions[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4712 if (is_array($restrictions))
4714 $restrictions = array_values(SimplePie_Misc
::array_unique($restrictions));
4717 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction']))
4719 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction'] as $restriction)
4721 $restriction_relationship = null;
4722 $restriction_type = null;
4723 $restriction_value = null;
4724 if (isset($restriction['attribs']['']['relationship']))
4726 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT
);
4728 if (isset($restriction['attribs']['']['type']))
4730 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4732 if (isset($restriction['data']))
4734 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4736 $restrictions[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4738 if (is_array($restrictions))
4740 $restrictions = array_values(SimplePie_Misc
::array_unique($restrictions));
4745 $restrictions = $restrictions_parent;
4749 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail']))
4751 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail'] as $thumbnail)
4753 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4755 if (is_array($thumbnails))
4757 $thumbnails = array_values(SimplePie_Misc
::array_unique($thumbnails));
4760 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail']))
4762 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail'] as $thumbnail)
4764 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4766 if (is_array($thumbnails))
4768 $thumbnails = array_values(SimplePie_Misc
::array_unique($thumbnails));
4773 $thumbnails = $thumbnails_parent;
4777 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title']))
4779 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4781 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title']))
4783 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4787 $title = $title_parent;
4790 $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);
4796 // If we have standalone media:content tags, loop through them.
4797 if (isset($this->data
['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['content']))
4799 foreach ((array) $this->data
['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['content'] as $content)
4801 if (isset($content['attribs']['']['url']) ||
isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player']))
4814 $samplingrate = null;
4824 $description = null;
4829 $restrictions = null;
4833 // Start checking the attributes of media:content
4834 if (isset($content['attribs']['']['bitrate']))
4836 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4838 if (isset($content['attribs']['']['channels']))
4840 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT
);
4842 if (isset($content['attribs']['']['duration']))
4844 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT
);
4848 $duration = $duration_parent;
4850 if (isset($content['attribs']['']['expression']))
4852 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT
);
4854 if (isset($content['attribs']['']['framerate']))
4856 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4858 if (isset($content['attribs']['']['height']))
4860 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT
);
4862 if (isset($content['attribs']['']['lang']))
4864 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
4866 if (isset($content['attribs']['']['fileSize']))
4868 $length = ceil($content['attribs']['']['fileSize']);
4870 if (isset($content['attribs']['']['medium']))
4872 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT
);
4874 if (isset($content['attribs']['']['samplingrate']))
4876 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT
);
4878 if (isset($content['attribs']['']['type']))
4880 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4882 if (isset($content['attribs']['']['width']))
4884 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT
);
4886 if (isset($content['attribs']['']['url']))
4888 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
4890 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4893 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text']))
4895 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['text'] as $caption)
4897 $caption_type = null;
4898 $caption_lang = null;
4899 $caption_startTime = null;
4900 $caption_endTime = null;
4901 $caption_text = null;
4902 if (isset($caption['attribs']['']['type']))
4904 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
4906 if (isset($caption['attribs']['']['lang']))
4908 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
4910 if (isset($caption['attribs']['']['start']))
4912 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT
);
4914 if (isset($caption['attribs']['']['end']))
4916 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT
);
4918 if (isset($caption['data']))
4920 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4922 $captions[] = new $this->feed
->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4924 if (is_array($captions))
4926 $captions = array_values(SimplePie_Misc
::array_unique($captions));
4931 $captions = $captions_parent;
4935 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category']))
4937 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['category'] as $category)
4942 if (isset($category['data']))
4944 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4946 if (isset($category['attribs']['']['scheme']))
4948 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
4952 $scheme = 'http://search.yahoo.com/mrss/category_schema';
4954 if (isset($category['attribs']['']['label']))
4956 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
4958 $categories[] = new $this->feed
->category_class($term, $scheme, $label);
4961 if (is_array($categories) && is_array($categories_parent))
4963 $categories = array_values(SimplePie_Misc
::array_unique(array_merge($categories, $categories_parent)));
4965 elseif (is_array($categories))
4967 $categories = array_values(SimplePie_Misc
::array_unique($categories));
4969 elseif (is_array($categories_parent))
4971 $categories = array_values(SimplePie_Misc
::array_unique($categories_parent));
4979 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright']))
4981 $copyright_url = null;
4982 $copyright_label = null;
4983 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url']))
4985 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT
);
4987 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data']))
4989 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
4991 $copyrights = new $this->feed
->copyright_class($copyright_url, $copyright_label);
4995 $copyrights = $copyrights_parent;
4999 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit']))
5001 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['credit'] as $credit)
5003 $credit_role = null;
5004 $credit_scheme = null;
5005 $credit_name = null;
5006 if (isset($credit['attribs']['']['role']))
5008 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT
);
5010 if (isset($credit['attribs']['']['scheme']))
5012 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
5016 $credit_scheme = 'urn:ebu';
5018 if (isset($credit['data']))
5020 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5022 $credits[] = new $this->feed
->credit_class($credit_role, $credit_scheme, $credit_name);
5024 if (is_array($credits))
5026 $credits = array_values(SimplePie_Misc
::array_unique($credits));
5031 $credits = $credits_parent;
5035 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description']))
5037 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5041 $description = $description_parent;
5045 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash']))
5047 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['hash'] as $hash)
5051 if (isset($hash['data']))
5053 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5055 if (isset($hash['attribs']['']['algo']))
5057 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT
);
5063 $hashes[] = $algo.':'.$value;
5065 if (is_array($hashes))
5067 $hashes = array_values(SimplePie_Misc
::array_unique($hashes));
5072 $hashes = $hashes_parent;
5076 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords']))
5078 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data']))
5080 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
));
5081 foreach ($temp as $word)
5083 $keywords[] = trim($word);
5087 if (is_array($keywords))
5089 $keywords = array_values(SimplePie_Misc
::array_unique($keywords));
5094 $keywords = $keywords_parent;
5098 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player']))
5100 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
5104 $player = $player_parent;
5108 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating']))
5110 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['rating'] as $rating)
5112 $rating_scheme = null;
5113 $rating_value = null;
5114 if (isset($rating['attribs']['']['scheme']))
5116 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
5120 $rating_scheme = 'urn:simple';
5122 if (isset($rating['data']))
5124 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5126 $ratings[] = new $this->feed
->rating_class($rating_scheme, $rating_value);
5128 if (is_array($ratings))
5130 $ratings = array_values(SimplePie_Misc
::array_unique($ratings));
5135 $ratings = $ratings_parent;
5139 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction']))
5141 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['restriction'] as $restriction)
5143 $restriction_relationship = null;
5144 $restriction_type = null;
5145 $restriction_value = null;
5146 if (isset($restriction['attribs']['']['relationship']))
5148 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT
);
5150 if (isset($restriction['attribs']['']['type']))
5152 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
5154 if (isset($restriction['data']))
5156 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5158 $restrictions[] = new $this->feed
->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5160 if (is_array($restrictions))
5162 $restrictions = array_values(SimplePie_Misc
::array_unique($restrictions));
5167 $restrictions = $restrictions_parent;
5171 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail']))
5173 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['thumbnail'] as $thumbnail)
5175 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
);
5177 if (is_array($thumbnails))
5179 $thumbnails = array_values(SimplePie_Misc
::array_unique($thumbnails));
5184 $thumbnails = $thumbnails_parent;
5188 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title']))
5190 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS
]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5194 $title = $title_parent;
5197 $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);
5202 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'link') as $link)
5204 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5217 $samplingrate = null;
5222 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
5223 if (isset($link['attribs']['']['type']))
5225 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
5227 if (isset($link['attribs']['']['length']))
5229 $length = ceil($link['attribs']['']['length']);
5232 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5233 $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);
5237 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'link') as $link)
5239 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5252 $samplingrate = null;
5257 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
5258 if (isset($link['attribs']['']['type']))
5260 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
5262 if (isset($link['attribs']['']['length']))
5264 $length = ceil($link['attribs']['']['length']);
5267 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5268 $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);
5272 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'enclosure'))
5274 if (isset($enclosure[0]['attribs']['']['url']))
5287 $samplingrate = null;
5292 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($enclosure[0]));
5293 if (isset($enclosure[0]['attribs']['']['type']))
5295 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT
);
5297 if (isset($enclosure[0]['attribs']['']['length']))
5299 $length = ceil($enclosure[0]['attribs']['']['length']);
5302 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5303 $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);
5307 if (sizeof($this->data
['enclosures']) === 0 && ($url ||
$type ||
$length ||
$bitrate ||
$captions_parent ||
$categories_parent ||
$channels ||
$copyrights_parent ||
$credits_parent ||
$description_parent ||
$duration_parent ||
$expression ||
$framerate ||
$hashes_parent ||
$height ||
$keywords_parent ||
$lang ||
$medium ||
$player_parent ||
$ratings_parent ||
$restrictions_parent ||
$samplingrate ||
$thumbnails_parent ||
$title_parent ||
$width))
5309 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5310 $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);
5313 $this->data
['enclosures'] = array_values(SimplePie_Misc
::array_unique($this->data
['enclosures']));
5315 if (!empty($this->data
['enclosures']))
5317 return $this->data
['enclosures'];
5325 public function get_latitude()
5327 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lat'))
5329 return (float) $return[0]['data'];
5331 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5333 return (float) $match[1];
5341 public function get_longitude()
5343 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'long'))
5345 return (float) $return[0]['data'];
5347 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lon'))
5349 return (float) $return[0]['data'];
5351 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5353 return (float) $match[2];
5361 public function get_source()
5363 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'source'))
5365 return new $this->feed
->source_class($this, $return[0]);
5374 class SimplePie_Source
5377 var $data = array();
5379 public function __construct($item, $data)
5381 $this->item
= $item;
5382 $this->data
= $data;
5385 public function __toString()
5387 return md5(serialize($this->data
));
5390 public function get_source_tags($namespace, $tag)
5392 if (isset($this->data
['child'][$namespace][$tag]))
5394 return $this->data
['child'][$namespace][$tag];
5402 public function get_base($element = array())
5404 return $this->item
->get_base($element);
5407 public function sanitize($data, $type, $base = '')
5409 return $this->item
->sanitize($data, $type, $base);
5412 public function get_item()
5417 public function get_title()
5419 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'title'))
5421 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5423 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'title'))
5425 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5427 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'title'))
5429 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5431 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'title'))
5433 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5435 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'title'))
5437 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5439 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'title'))
5441 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5443 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'title'))
5445 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5453 public function get_category($key = 0)
5455 $categories = $this->get_categories();
5456 if (isset($categories[$key]))
5458 return $categories[$key];
5466 public function get_categories()
5468 $categories = array();
5470 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'category') as $category)
5475 if (isset($category['attribs']['']['term']))
5477 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT
);
5479 if (isset($category['attribs']['']['scheme']))
5481 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT
);
5483 if (isset($category['attribs']['']['label']))
5485 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT
);
5487 $categories[] = new $this->item
->feed
->category_class($term, $scheme, $label);
5489 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'category') as $category)
5491 // This is really the label, but keep this as the term also for BC.
5492 // Label will also work on retrieving because that falls back to term.
5493 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5494 if (isset($category['attribs']['']['domain']))
5496 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT
);
5502 $categories[] = new $this->item
->feed
->category_class($term, $scheme, null);
5504 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'subject') as $category)
5506 $categories[] = new $this->item
->feed
->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
5508 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'subject') as $category)
5510 $categories[] = new $this->item
->feed
->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
5513 if (!empty($categories))
5515 return SimplePie_Misc
::array_unique($categories);
5523 public function get_author($key = 0)
5525 $authors = $this->get_authors();
5526 if (isset($authors[$key]))
5528 return $authors[$key];
5536 public function get_authors()
5539 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'author') as $author)
5544 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
5546 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5548 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
5550 $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]));
5552 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
5554 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5556 if ($name !== null ||
$email !== null ||
$uri !== null)
5558 $authors[] = new $this->item
->feed
->author_class($name, $uri, $email);
5561 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'author'))
5566 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
5568 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5570 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
5572 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
5574 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
5576 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5578 if ($name !== null ||
$email !== null ||
$url !== null)
5580 $authors[] = new $this->item
->feed
->author_class($name, $url, $email);
5583 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'creator') as $author)
5585 $authors[] = new $this->item
->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
5587 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'creator') as $author)
5589 $authors[] = new $this->item
->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
5591 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'author') as $author)
5593 $authors[] = new $this->item
->feed
->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT
), null, null);
5596 if (!empty($authors))
5598 return SimplePie_Misc
::array_unique($authors);
5606 public function get_contributor($key = 0)
5608 $contributors = $this->get_contributors();
5609 if (isset($contributors[$key]))
5611 return $contributors[$key];
5619 public function get_contributors()
5621 $contributors = array();
5622 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'contributor') as $contributor)
5627 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data']))
5629 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5631 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data']))
5633 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['uri'][0]));
5635 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data']))
5637 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5639 if ($name !== null ||
$email !== null ||
$uri !== null)
5641 $contributors[] = new $this->item
->feed
->author_class($name, $uri, $email);
5644 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'contributor') as $contributor)
5649 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data']))
5651 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5653 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data']))
5655 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['url'][0]));
5657 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data']))
5659 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5661 if ($name !== null ||
$email !== null ||
$url !== null)
5663 $contributors[] = new $this->item
->feed
->author_class($name, $url, $email);
5667 if (!empty($contributors))
5669 return SimplePie_Misc
::array_unique($contributors);
5677 public function get_link($key = 0, $rel = 'alternate')
5679 $links = $this->get_links($rel);
5680 if (isset($links[$key]))
5682 return $links[$key];
5691 * Added for parity between the parent-level and the item/entry-level.
5693 public function get_permalink()
5695 return $this->get_link(0);
5698 public function get_links($rel = 'alternate')
5700 if (!isset($this->data
['links']))
5702 $this->data
['links'] = array();
5703 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'link'))
5705 foreach ($links as $link)
5707 if (isset($link['attribs']['']['href']))
5709 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
5710 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
5714 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'link'))
5716 foreach ($links as $link)
5718 if (isset($link['attribs']['']['href']))
5720 $link_rel = (isset($link['attribs']['']['rel'])) ?
$link['attribs']['']['rel'] : 'alternate';
5721 $this->data
['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($link));
5726 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'link'))
5728 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
5730 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'link'))
5732 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
5734 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'link'))
5736 $this->data
['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($links[0]));
5739 $keys = array_keys($this->data
['links']);
5740 foreach ($keys as $key)
5742 if (SimplePie_Misc
::is_isegment_nz_nc($key))
5744 if (isset($this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]))
5746 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] = array_merge($this->data
['links'][$key], $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key]);
5747 $this->data
['links'][$key] =& $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key];
5751 $this->data
['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
. $key] =& $this->data
['links'][$key];
5754 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY
)
5756 $this->data
['links'][substr($key, 41)] =& $this->data
['links'][$key];
5758 $this->data
['links'][$key] = array_unique($this->data
['links'][$key]);
5762 if (isset($this->data
['links'][$rel]))
5764 return $this->data
['links'][$rel];
5772 public function get_description()
5774 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'subtitle'))
5776 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5778 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'tagline'))
5780 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5782 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10
, 'description'))
5784 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5786 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090
, 'description'))
5788 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5790 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'description'))
5792 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML
, $this->get_base($return[0]));
5794 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'description'))
5796 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5798 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'description'))
5800 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5802 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'summary'))
5804 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
5806 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'subtitle'))
5808 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML
, $this->get_base($return[0]));
5816 public function get_copyright()
5818 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'rights'))
5820 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5822 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03
, 'copyright'))
5824 return $this->sanitize($return[0]['data'], SimplePie_Misc
::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5826 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'copyright'))
5828 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5830 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'rights'))
5832 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5834 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'rights'))
5836 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5844 public function get_language()
5846 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20
, 'language'))
5848 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5850 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11
, 'language'))
5852 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5854 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10
, 'language'))
5856 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT
);
5858 elseif (isset($this->data
['xml_lang']))
5860 return $this->sanitize($this->data
['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT
);
5868 public function get_latitude()
5870 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lat'))
5872 return (float) $return[0]['data'];
5874 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5876 return (float) $match[1];
5884 public function get_longitude()
5886 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'long'))
5888 return (float) $return[0]['data'];
5890 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO
, 'lon'))
5892 return (float) $return[0]['data'];
5894 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS
, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5896 return (float) $match[2];
5904 public function get_image_url()
5906 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES
, 'image'))
5908 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI
);
5910 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'logo'))
5912 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
5914 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10
, 'icon'))
5916 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI
, $this->get_base($return[0]));
5925 class SimplePie_Author
5931 // Constructor, used to input the data
5932 public function __construct($name = null, $link = null, $email = null)
5934 $this->name
= $name;
5935 $this->link
= $link;
5936 $this->email
= $email;
5939 public function __toString()
5941 // There is no $this->data here
5942 return md5(serialize($this));
5945 public function get_name()
5947 if ($this->name
!== null)
5957 public function get_link()
5959 if ($this->link
!== null)
5969 public function get_email()
5971 if ($this->email
!== null)
5973 return $this->email
;
5982 class SimplePie_Category
5988 // Constructor, used to input the data
5989 public function __construct($term = null, $scheme = null, $label = null)
5991 $this->term
= $term;
5992 $this->scheme
= $scheme;
5993 $this->label
= $label;
5996 public function __toString()
5998 // There is no $this->data here
5999 return md5(serialize($this));
6002 public function get_term()
6004 if ($this->term
!== null)
6014 public function get_scheme()
6016 if ($this->scheme
!== null)
6018 return $this->scheme
;
6026 public function get_label()
6028 if ($this->label
!== null)
6030 return $this->label
;
6034 return $this->get_term();
6039 class SimplePie_Enclosure
6069 // Constructor, used to input the data
6070 public function __construct($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)
6072 $this->bitrate
= $bitrate;
6073 $this->captions
= $captions;
6074 $this->categories
= $categories;
6075 $this->channels
= $channels;
6076 $this->copyright
= $copyright;
6077 $this->credits
= $credits;
6078 $this->description
= $description;
6079 $this->duration
= $duration;
6080 $this->expression
= $expression;
6081 $this->framerate
= $framerate;
6082 $this->hashes
= $hashes;
6083 $this->height
= $height;
6084 $this->javascript
= $javascript;
6085 $this->keywords
= $keywords;
6086 $this->lang
= $lang;
6087 $this->length
= $length;
6088 $this->link
= $link;
6089 $this->medium
= $medium;
6090 $this->player
= $player;
6091 $this->ratings
= $ratings;
6092 $this->restrictions
= $restrictions;
6093 $this->samplingrate
= $samplingrate;
6094 $this->thumbnails
= $thumbnails;
6095 $this->title
= $title;
6096 $this->type
= $type;
6097 $this->width
= $width;
6099 if (class_exists('idna_convert'))
6101 $idn = new idna_convert();
6102 $parsed = SimplePie_Misc
::parse_url($link);
6103 $this->link
= SimplePie_Misc
::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6105 $this->handler
= $this->get_handler(); // Needs to load last
6108 public function __toString()
6110 // There is no $this->data here
6111 return md5(serialize($this));
6114 public function get_bitrate()
6116 if ($this->bitrate
!== null)
6118 return $this->bitrate
;
6126 public function get_caption($key = 0)
6128 $captions = $this->get_captions();
6129 if (isset($captions[$key]))
6131 return $captions[$key];
6139 public function get_captions()
6141 if ($this->captions
!== null)
6143 return $this->captions
;
6151 public function get_category($key = 0)
6153 $categories = $this->get_categories();
6154 if (isset($categories[$key]))
6156 return $categories[$key];
6164 public function get_categories()
6166 if ($this->categories
!== null)
6168 return $this->categories
;
6176 public function get_channels()
6178 if ($this->channels
!== null)
6180 return $this->channels
;
6188 public function get_copyright()
6190 if ($this->copyright
!== null)
6192 return $this->copyright
;
6200 public function get_credit($key = 0)
6202 $credits = $this->get_credits();
6203 if (isset($credits[$key]))
6205 return $credits[$key];
6213 public function get_credits()
6215 if ($this->credits
!== null)
6217 return $this->credits
;
6225 public function get_description()
6227 if ($this->description
!== null)
6229 return $this->description
;
6237 public function get_duration($convert = false)
6239 if ($this->duration
!== null)
6243 $time = SimplePie_Misc
::time_hms($this->duration
);
6248 return $this->duration
;
6257 public function get_expression()
6259 if ($this->expression
!== null)
6261 return $this->expression
;
6269 public function get_extension()
6271 if ($this->link
!== null)
6273 $url = SimplePie_Misc
::parse_url($this->link
);
6274 if ($url['path'] !== '')
6276 return pathinfo($url['path'], PATHINFO_EXTENSION
);
6282 public function get_framerate()
6284 if ($this->framerate
!== null)
6286 return $this->framerate
;
6294 public function get_handler()
6296 return $this->get_real_type(true);
6299 public function get_hash($key = 0)
6301 $hashes = $this->get_hashes();
6302 if (isset($hashes[$key]))
6304 return $hashes[$key];
6312 public function get_hashes()
6314 if ($this->hashes
!== null)
6316 return $this->hashes
;
6324 public function get_height()
6326 if ($this->height
!== null)
6328 return $this->height
;
6336 public function get_language()
6338 if ($this->lang
!== null)
6348 public function get_keyword($key = 0)
6350 $keywords = $this->get_keywords();
6351 if (isset($keywords[$key]))
6353 return $keywords[$key];
6361 public function get_keywords()
6363 if ($this->keywords
!== null)
6365 return $this->keywords
;
6373 public function get_length()
6375 if ($this->length
!== null)
6377 return $this->length
;
6385 public function get_link()
6387 if ($this->link
!== null)
6389 return urldecode($this->link
);
6397 public function get_medium()
6399 if ($this->medium
!== null)
6401 return $this->medium
;
6409 public function get_player()
6411 if ($this->player
!== null)
6413 return $this->player
;
6421 public function get_rating($key = 0)
6423 $ratings = $this->get_ratings();
6424 if (isset($ratings[$key]))
6426 return $ratings[$key];
6434 public function get_ratings()
6436 if ($this->ratings
!== null)
6438 return $this->ratings
;
6446 public function get_restriction($key = 0)
6448 $restrictions = $this->get_restrictions();
6449 if (isset($restrictions[$key]))
6451 return $restrictions[$key];
6459 public function get_restrictions()
6461 if ($this->restrictions
!== null)
6463 return $this->restrictions
;
6471 public function get_sampling_rate()
6473 if ($this->samplingrate
!== null)
6475 return $this->samplingrate
;
6483 public function get_size()
6485 $length = $this->get_length();
6486 if ($length !== null)
6488 return round($length/1048576, 2);
6496 public function get_thumbnail($key = 0)
6498 $thumbnails = $this->get_thumbnails();
6499 if (isset($thumbnails[$key]))
6501 return $thumbnails[$key];
6509 public function get_thumbnails()
6511 if ($this->thumbnails
!== null)
6513 return $this->thumbnails
;
6521 public function get_title()
6523 if ($this->title
!== null)
6525 return $this->title
;
6533 public function get_type()
6535 if ($this->type
!== null)
6545 public function get_width()
6547 if ($this->width
!== null)
6549 return $this->width
;
6557 public function native_embed($options='')
6559 return $this->embed($options, true);
6563 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6565 public function embed($options = '', $native = false)
6575 $bgcolor = '#ffffff';
6577 $widescreen = false;
6578 $handler = $this->get_handler();
6579 $type = $this->get_real_type();
6581 // Process options and reassign values as necessary
6582 if (is_array($options))
6588 $options = explode(',', $options);
6589 foreach($options as $option)
6591 $opt = explode(':', $option, 2);
6592 if (isset($opt[0], $opt[1]))
6594 $opt[0] = trim($opt[0]);
6595 $opt[1] = trim($opt[1]);
6611 $altclass = $opt[1];
6631 $mediaplayer = $opt[1];
6635 $widescreen = $opt[1];
6642 $mime = explode('/', $type, 2);
6645 // Process values for 'auto'
6646 if ($width === 'auto')
6648 if ($mime === 'video')
6650 if ($height === 'auto')
6654 elseif ($widescreen)
6656 $width = round((intval($height)/9)*16);
6660 $width = round((intval($height)/3)*4);
6669 if ($height === 'auto')
6671 if ($mime === 'audio')
6675 elseif ($mime === 'video')
6677 if ($width === 'auto')
6688 elseif ($widescreen)
6690 $height = round((intval($width)/16)*9);
6694 $height = round((intval($width)/4)*3);
6702 elseif ($mime === 'audio')
6707 // Set proper placeholder value
6708 if ($mime === 'audio')
6710 $placeholder = $audio;
6712 elseif ($mime === 'video')
6714 $placeholder = $video;
6719 // Make sure the JS library is included
6722 static $javascript_outputted = null;
6723 if (!$javascript_outputted && $this->javascript
)
6725 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript
) . '"></script>';
6726 $javascript_outputted = true;
6731 if ($handler === 'odeo')
6735 $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>';
6739 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
6744 elseif ($handler === 'flash')
6748 $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>";
6752 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
6756 // Flash Media Player file types.
6757 // Preferred handler for MP3 file types.
6758 elseif ($handler === 'fmedia' ||
($handler === 'mp3' && $mediaplayer !== ''))
6763 $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>";
6767 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
6771 // QuickTime 7 file types. Need to test with QuickTime 6.
6772 // Only handle MP3's if the Flash Media Player is not present.
6773 elseif ($handler === 'quicktime' ||
($handler === 'mp3' && $mediaplayer === ''))
6778 if ($placeholder !== '')
6780 $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>";
6784 $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>";
6789 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
6794 elseif ($handler === 'wmedia')
6799 $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>";
6803 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
6808 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
6813 public function get_real_type($find_handler = false)
6815 // If it's Odeo, let's get it out of the way.
6816 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
6821 // Mime-types by handler.
6822 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
6823 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
6824 $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
6825 $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
6826 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
6828 if ($this->get_type() !== null)
6830 $type = strtolower($this->type
);
6837 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
6838 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
6840 switch (strtolower($this->get_extension()))
6845 $type = 'audio/acc';
6852 $type = 'audio/aiff';
6856 $type = 'audio/wav';
6863 $type = 'audio/midi';
6867 $type = 'audio/x-m4a';
6872 $type = 'audio/mp3';
6876 $type = 'audio/wav';
6880 $type = 'audio/x-ms-wax';
6884 $type = 'audio/x-ms-wma';
6890 $type = 'video/3gpp';
6895 $type = 'video/3gpp2';
6899 $type = 'video/x-ms-asf';
6903 $type = 'video/x-flv';
6917 $type = 'video/mpeg';
6921 $type = 'video/x-m4v';
6926 $type = 'video/quicktime';
6931 $type = 'video/mp4';
6935 $type = 'video/sd-video';
6939 $type = 'video/x-ms-wm';
6943 $type = 'video/x-ms-wmv';
6947 $type = 'video/x-ms-wvx';
6952 $type = 'application/futuresplash';
6956 $type = 'application/x-shockwave-flash';
6963 if (in_array($type, $types_flash))
6967 elseif (in_array($type, $types_fmedia))
6971 elseif (in_array($type, $types_quicktime))
6975 elseif (in_array($type, $types_wmedia))
6979 elseif (in_array($type, $types_mp3))
6995 class SimplePie_Caption
7003 // Constructor, used to input the data
7004 public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7006 $this->type
= $type;
7007 $this->lang
= $lang;
7008 $this->startTime
= $startTime;
7009 $this->endTime
= $endTime;
7010 $this->text
= $text;
7013 public function __toString()
7015 // There is no $this->data here
7016 return md5(serialize($this));
7019 public function get_endtime()
7021 if ($this->endTime
!== null)
7023 return $this->endTime
;
7031 public function get_language()
7033 if ($this->lang
!== null)
7043 public function get_starttime()
7045 if ($this->startTime
!== null)
7047 return $this->startTime
;
7055 public function get_text()
7057 if ($this->text
!== null)
7067 public function get_type()
7069 if ($this->type
!== null)
7080 class SimplePie_Credit
7086 // Constructor, used to input the data
7087 public function __construct($role = null, $scheme = null, $name = null)
7089 $this->role
= $role;
7090 $this->scheme
= $scheme;
7091 $this->name
= $name;
7094 public function __toString()
7096 // There is no $this->data here
7097 return md5(serialize($this));
7100 public function get_role()
7102 if ($this->role
!== null)
7112 public function get_scheme()
7114 if ($this->scheme
!== null)
7116 return $this->scheme
;
7124 public function get_name()
7126 if ($this->name
!== null)
7137 class SimplePie_Copyright
7142 // Constructor, used to input the data
7143 public function __construct($url = null, $label = null)
7146 $this->label
= $label;
7149 public function __toString()
7151 // There is no $this->data here
7152 return md5(serialize($this));
7155 public function get_url()
7157 if ($this->url
!== null)
7167 public function get_attribution()
7169 if ($this->label
!== null)
7171 return $this->label
;
7180 class SimplePie_Rating
7185 // Constructor, used to input the data
7186 public function __construct($scheme = null, $value = null)
7188 $this->scheme
= $scheme;
7189 $this->value
= $value;
7192 public function __toString()
7194 // There is no $this->data here
7195 return md5(serialize($this));
7198 public function get_scheme()
7200 if ($this->scheme
!== null)
7202 return $this->scheme
;
7210 public function get_value()
7212 if ($this->value
!== null)
7214 return $this->value
;
7223 class SimplePie_Restriction
7229 // Constructor, used to input the data
7230 public function __construct($relationship = null, $type = null, $value = null)
7232 $this->relationship
= $relationship;
7233 $this->type
= $type;
7234 $this->value
= $value;
7237 public function __toString()
7239 // There is no $this->data here
7240 return md5(serialize($this));
7243 public function get_relationship()
7245 if ($this->relationship
!== null)
7247 return $this->relationship
;
7255 public function get_type()
7257 if ($this->type
!== null)
7267 public function get_value()
7269 if ($this->value
!== null)
7271 return $this->value
;
7281 * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7283 class SimplePie_File
7287 var $success = true;
7288 var $headers = array();
7293 var $method = SIMPLEPIE_FILE_SOURCE_NONE
;
7295 public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7297 if (class_exists('idna_convert'))
7299 $idn = new idna_convert();
7300 $parsed = SimplePie_Misc
::parse_url($url);
7301 $url = SimplePie_Misc
::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7304 $this->useragent
= $useragent;
7305 if (preg_match('/^http(s)?:\/\//i', $url))
7307 if ($useragent === null)
7309 $useragent = ini_get('user_agent');
7310 $this->useragent
= $useragent;
7312 if (!is_array($headers))
7316 if (!$force_fsockopen && function_exists('curl_exec'))
7318 $this->method
= SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL
;
7320 $headers2 = array();
7321 foreach ($headers as $key => $value)
7323 $headers2[] = "$key: $value";
7325 if (version_compare(SimplePie_Misc
::get_curl_version(), '7.10.5', '>='))
7327 curl_setopt($fp, CURLOPT_ENCODING
, '');
7329 curl_setopt($fp, CURLOPT_URL
, $url);
7330 curl_setopt($fp, CURLOPT_HEADER
, 1);
7331 curl_setopt($fp, CURLOPT_RETURNTRANSFER
, 1);
7332 curl_setopt($fp, CURLOPT_TIMEOUT
, $timeout);
7333 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT
, $timeout);
7334 curl_setopt($fp, CURLOPT_REFERER
, $url);
7335 curl_setopt($fp, CURLOPT_USERAGENT
, $useragent);
7336 curl_setopt($fp, CURLOPT_HTTPHEADER
, $headers2);
7337 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc
::get_curl_version(), '7.15.2', '>='))
7339 curl_setopt($fp, CURLOPT_FOLLOWLOCATION
, 1);
7340 curl_setopt($fp, CURLOPT_MAXREDIRS
, $redirects);
7343 $this->headers
= curl_exec($fp);
7344 if (curl_errno($fp) === 23 ||
curl_errno($fp) === 61)
7346 curl_setopt($fp, CURLOPT_ENCODING
, 'none');
7347 $this->headers
= curl_exec($fp);
7349 if (curl_errno($fp))
7351 $this->error
= 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7352 $this->success
= false;
7356 $info = curl_getinfo($fp);
7358 $this->headers
= explode("\r\n\r\n", $this->headers
, $info['redirect_count'] +
1);
7359 $this->headers
= array_pop($this->headers
);
7360 $parser = new SimplePie_HTTP_Parser($this->headers
);
7361 if ($parser->parse())
7363 $this->headers
= $parser->headers
;
7364 $this->body
= $parser->body
;
7365 $this->status_code
= $parser->status_code
;
7366 if ((in_array($this->status_code
, array(300, 301, 302, 303, 307)) ||
$this->status_code
> 307 && $this->status_code
< 400) && isset($this->headers
['location']) && $this->redirects
< $redirects)
7369 $location = SimplePie_Misc
::absolutize_url($this->headers
['location'], $url);
7370 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7377 $this->method
= SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN
;
7378 $url_parts = parse_url($url);
7379 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
7381 $url_parts['host'] = "ssl://$url_parts[host]";
7382 $url_parts['port'] = 443;
7384 if (!isset($url_parts['port']))
7386 $url_parts['port'] = 80;
7388 $fp = @fsockopen
($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7391 $this->error
= 'fsockopen error: ' . $errstr;
7392 $this->success
= false;
7396 stream_set_timeout($fp, $timeout);
7397 if (isset($url_parts['path']))
7399 if (isset($url_parts['query']))
7401 $get = "$url_parts[path]?$url_parts[query]";
7405 $get = $url_parts['path'];
7412 $out = "GET $get HTTP/1.0\r\n";
7413 $out .= "Host: $url_parts[host]\r\n";
7414 $out .= "User-Agent: $useragent\r\n";
7415 if (extension_loaded('zlib'))
7417 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7420 if (isset($url_parts['user']) && isset($url_parts['pass']))
7422 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
7424 foreach ($headers as $key => $value)
7426 $out .= "$key: $value\r\n";
7428 $out .= "Connection: Close\r\n\r\n";
7431 $info = stream_get_meta_data($fp);
7433 $this->headers
= '';
7434 while (!$info['eof'] && !$info['timed_out'])
7436 $this->headers
.= fread($fp, 1160);
7437 $info = stream_get_meta_data($fp);
7439 if (!$info['timed_out'])
7441 $parser = new SimplePie_HTTP_Parser($this->headers
);
7442 if ($parser->parse())
7444 $this->headers
= $parser->headers
;
7445 $this->body
= $parser->body
;
7446 $this->status_code
= $parser->status_code
;
7447 if ((in_array($this->status_code
, array(300, 301, 302, 303, 307)) ||
$this->status_code
> 307 && $this->status_code
< 400) && isset($this->headers
['location']) && $this->redirects
< $redirects)
7450 $location = SimplePie_Misc
::absolutize_url($this->headers
['location'], $url);
7451 return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7453 if (isset($this->headers
['content-encoding']))
7455 // Hey, we act dumb elsewhere, so let's do that here too
7456 switch (strtolower(trim($this->headers
['content-encoding'], "\x09\x0A\x0D\x20")))
7460 $decoder = new SimplePie_gzdecode($this->body
);
7461 if (!$decoder->parse())
7463 $this->error
= 'Unable to decode HTTP "gzip" stream';
7464 $this->success
= false;
7468 $this->body
= $decoder->data
;
7473 if (($body = gzuncompress($this->body
)) === false)
7475 if (($body = gzinflate($this->body
)) === false)
7477 $this->error
= 'Unable to decode HTTP "deflate" stream';
7478 $this->success
= false;
7481 $this->body
= $body;
7485 $this->error
= 'Unknown content coding';
7486 $this->success
= false;
7493 $this->error
= 'fsocket timed out';
7494 $this->success
= false;
7502 $this->method
= SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS
;
7503 if (!$this->body
= file_get_contents($url))
7505 $this->error
= 'file_get_contents could not read the file';
7506 $this->success
= false;
7513 * HTTP Response Parser
7515 * @package SimplePie
7517 class SimplePie_HTTP_Parser
7525 var $http_version = 0.0;
7533 var $status_code = 0;
7544 * Key/value pairs of the headers
7549 var $headers = array();
7552 * Body of the response
7560 * Current state of the state machine
7565 var $state = 'http_version';
7576 * Input data length (to avoid calling strlen() everytime this is needed)
7581 var $data_length = 0;
7584 * Current position of the pointer
7592 * Name of the hedaer currently being parsed
7600 * Value of the hedaer currently being parsed
7608 * Create an instance of the class with the input data
7611 * @param string $data Input data
7613 public function __construct($data)
7615 $this->data
= $data;
7616 $this->data_length
= strlen($this->data
);
7620 * Parse the input data
7623 * @return bool true on success, false on failure
7625 public function parse()
7627 while ($this->state
&& $this->state
!== 'emit' && $this->has_data())
7629 $state = $this->state
;
7633 if ($this->state
=== 'emit' ||
$this->state
=== 'body')
7639 $this->http_version
= '';
7640 $this->status_code
= '';
7642 $this->headers
= array();
7649 * Check whether there is data beyond the pointer
7652 * @return bool true if there is further data, false if not
7654 public function has_data()
7656 return (bool) ($this->position
< $this->data_length
);
7660 * See if the next character is LWS
7663 * @return bool true if the next character is LWS, false if not
7665 public function is_linear_whitespace()
7667 return (bool) ($this->data
[$this->position
] === "\x09"
7668 ||
$this->data
[$this->position
] === "\x20"
7669 ||
($this->data
[$this->position
] === "\x0A"
7670 && isset($this->data
[$this->position +
1])
7671 && ($this->data
[$this->position +
1] === "\x09" ||
$this->data
[$this->position +
1] === "\x20")));
7675 * Parse the HTTP version
7679 public function http_version()
7681 if (strpos($this->data
, "\x0A") !== false && strtoupper(substr($this->data
, 0, 5)) === 'HTTP/')
7683 $len = strspn($this->data
, '0123456789.', 5);
7684 $this->http_version
= substr($this->data
, 5, $len);
7685 $this->position +
= 5 +
$len;
7686 if (substr_count($this->http_version
, '.') <= 1)
7688 $this->http_version
= (float) $this->http_version
;
7689 $this->position +
= strspn($this->data
, "\x09\x20", $this->position
);
7690 $this->state
= 'status';
7694 $this->state
= false;
7699 $this->state
= false;
7704 * Parse the status code
7708 public function status()
7710 if ($len = strspn($this->data
, '0123456789', $this->position
))
7712 $this->status_code
= (int) substr($this->data
, $this->position
, $len);
7713 $this->position +
= $len;
7714 $this->state
= 'reason';
7718 $this->state
= false;
7723 * Parse the reason phrase
7727 public function reason()
7729 $len = strcspn($this->data
, "\x0A", $this->position
);
7730 $this->reason
= trim(substr($this->data
, $this->position
, $len), "\x09\x0D\x20");
7731 $this->position +
= $len +
1;
7732 $this->state
= 'new_line';
7736 * Deal with a new line, shifting data around as needed
7740 public function new_line()
7742 $this->value
= trim($this->value
, "\x0D\x20");
7743 if ($this->name
!== '' && $this->value
!== '')
7745 $this->name
= strtolower($this->name
);
7746 if (isset($this->headers
[$this->name
]))
7748 $this->headers
[$this->name
] .= ', ' . $this->value
;
7752 $this->headers
[$this->name
] = $this->value
;
7757 if (substr($this->data
[$this->position
], 0, 2) === "\x0D\x0A")
7759 $this->position +
= 2;
7760 $this->state
= 'body';
7762 elseif ($this->data
[$this->position
] === "\x0A")
7765 $this->state
= 'body';
7769 $this->state
= 'name';
7774 * Parse a header name
7778 public function name()
7780 $len = strcspn($this->data
, "\x0A:", $this->position
);
7781 if (isset($this->data
[$this->position +
$len]))
7783 if ($this->data
[$this->position +
$len] === "\x0A")
7785 $this->position +
= $len;
7786 $this->state
= 'new_line';
7790 $this->name
= substr($this->data
, $this->position
, $len);
7791 $this->position +
= $len +
1;
7792 $this->state
= 'value';
7797 $this->state
= false;
7802 * Parse LWS, replacing consecutive LWS characters with a single space
7806 public function linear_whitespace()
7810 if (substr($this->data
, $this->position
, 2) === "\x0D\x0A")
7812 $this->position +
= 2;
7814 elseif ($this->data
[$this->position
] === "\x0A")
7818 $this->position +
= strspn($this->data
, "\x09\x20", $this->position
);
7819 } while ($this->has_data() && $this->is_linear_whitespace());
7820 $this->value
.= "\x20";
7824 * See what state to move to while within non-quoted header values
7828 public function value()
7830 if ($this->is_linear_whitespace())
7832 $this->linear_whitespace();
7836 switch ($this->data
[$this->position
])
7840 $this->state
= 'quote';
7845 $this->state
= 'new_line';
7849 $this->state
= 'value_char';
7856 * Parse a header value while outside quotes
7860 public function value_char()
7862 $len = strcspn($this->data
, "\x09\x20\x0A\"", $this->position
);
7863 $this->value
.= substr($this->data
, $this->position
, $len);
7864 $this->position +
= $len;
7865 $this->state
= 'value';
7869 * See what state to move to while within quoted header values
7873 public function quote()
7875 if ($this->is_linear_whitespace())
7877 $this->linear_whitespace();
7881 switch ($this->data
[$this->position
])
7885 $this->state
= 'value';
7890 $this->state
= 'new_line';
7895 $this->state
= 'quote_escaped';
7899 $this->state
= 'quote_char';
7906 * Parse a header value while within quotes
7910 public function quote_char()
7912 $len = strcspn($this->data
, "\x09\x20\x0A\"\\", $this->position
);
7913 $this->value
.= substr($this->data
, $this->position
, $len);
7914 $this->position +
= $len;
7915 $this->state
= 'value';
7919 * Parse an escaped character within quotes
7923 public function quote_escaped()
7925 $this->value
.= $this->data
[$this->position
];
7927 $this->state
= 'quote';
7935 public function body()
7937 $this->body
= substr($this->data
, $this->position
);
7938 $this->state
= 'emit';
7945 * @package SimplePie
7947 class SimplePie_gzdecode
7953 * @see gzdecode::$data
7955 var $compressed_data;
7958 * Size of compressed data
7962 var $compressed_size;
7965 * Minimum size of a valid gzip string
7969 var $min_compressed_size = 18;
7972 * Current position of pointer
7989 * @see gzdecode::$compressed_data
8018 * @see gzdecode::$extra_field
8019 * @see gzdecode::$SI2
8027 * @see gzdecode::$extra_field
8028 * @see gzdecode::$SI1
8033 * Extra field content
8036 * @see gzdecode::$SI1
8037 * @see gzdecode::$SI2
8049 * Human readable comment
8056 * Don't allow anything to be set
8060 public function __set($name, $value)
8062 trigger_error("Cannot write property $name", E_USER_ERROR
);
8066 * Set the compressed string and related properties
8070 public function __construct($data)
8072 $this->compressed_data
= $data;
8073 $this->compressed_size
= strlen($data);
8077 * Decode the GZIP stream
8081 public function parse()
8083 if ($this->compressed_size
>= $this->min_compressed_size
)
8085 // Check ID1, ID2, and CM
8086 if (substr($this->compressed_data
, 0, 3) !== "\x1F\x8B\x08")
8091 // Get the FLG (FLaGs)
8092 $this->flags
= ord($this->compressed_data
[3]);
8094 // FLG bits above (1 << 4) are reserved
8095 if ($this->flags
> 0x1F)
8100 // Advance the pointer after the above
8101 $this->position +
= 4;
8104 $mtime = substr($this->compressed_data
, $this->position
, 4);
8105 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8106 if (current(unpack('S', "\x00\x01")) === 1)
8108 $mtime = strrev($mtime);
8110 $this->MTIME
= current(unpack('l', $mtime));
8111 $this->position +
= 4;
8113 // Get the XFL (eXtra FLags)
8114 $this->XFL
= ord($this->compressed_data
[$this->position++
]);
8116 // Get the OS (Operating System)
8117 $this->OS
= ord($this->compressed_data
[$this->position++
]);
8120 if ($this->flags
& 4)
8122 // Read subfield IDs
8123 $this->SI1
= $this->compressed_data
[$this->position++
];
8124 $this->SI2
= $this->compressed_data
[$this->position++
];
8126 // SI2 set to zero is reserved for future use
8127 if ($this->SI2
=== "\x00")
8132 // Get the length of the extra field
8133 $len = current(unpack('v', substr($this->compressed_data
, $this->position
, 2)));
8136 // Check the length of the string is still valid
8137 $this->min_compressed_size +
= $len +
4;
8138 if ($this->compressed_size
>= $this->min_compressed_size
)
8140 // Set the extra field to the given data
8141 $this->extra_field
= substr($this->compressed_data
, $this->position
, $len);
8142 $this->position +
= $len;
8151 if ($this->flags
& 8)
8153 // Get the length of the filename
8154 $len = strcspn($this->compressed_data
, "\x00", $this->position
);
8156 // Check the length of the string is still valid
8157 $this->min_compressed_size +
= $len +
1;
8158 if ($this->compressed_size
>= $this->min_compressed_size
)
8160 // Set the original filename to the given string
8161 $this->filename
= substr($this->compressed_data
, $this->position
, $len);
8162 $this->position +
= $len +
1;
8170 // Parse the FCOMMENT
8171 if ($this->flags
& 16)
8173 // Get the length of the comment
8174 $len = strcspn($this->compressed_data
, "\x00", $this->position
);
8176 // Check the length of the string is still valid
8177 $this->min_compressed_size +
= $len +
1;
8178 if ($this->compressed_size
>= $this->min_compressed_size
)
8180 // Set the original comment to the given string
8181 $this->comment
= substr($this->compressed_data
, $this->position
, $len);
8182 $this->position +
= $len +
1;
8191 if ($this->flags
& 2)
8193 // Check the length of the string is still valid
8194 $this->min_compressed_size +
= $len +
2;
8195 if ($this->compressed_size
>= $this->min_compressed_size
)
8198 $crc = current(unpack('v', substr($this->compressed_data
, $this->position
, 2)));
8200 // Check the CRC matches
8201 if ((crc32(substr($this->compressed_data
, 0, $this->position
)) & 0xFFFF) === $crc)
8203 $this->position +
= 2;
8216 // Decompress the actual data
8217 if (($this->data
= gzinflate(substr($this->compressed_data
, $this->position
, -8))) === false)
8223 $this->position
= $this->compressed_size
- 8;
8226 // Check CRC of data
8227 $crc = current(unpack('V', substr($this->compressed_data
, $this->position
, 4)));
8228 $this->position +
= 4;
8229 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8234 // Check ISIZE of data
8235 $isize = current(unpack('V', substr($this->compressed_data
, $this->position
, 4)));
8236 $this->position +
= 4;
8237 if (sprintf('%u', strlen($this->data
) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8242 // Wow, against all odds, we've actually got a valid gzip string
8252 class SimplePie_Cache
8255 * Don't call the constructor. Please.
8259 private function __construct()
8261 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR
);
8265 * Create a new SimplePie_Cache object
8270 public static function create($location, $filename, $extension)
8272 $location_iri = new SimplePie_IRI($location);
8273 switch ($location_iri->get_scheme())
8276 if (extension_loaded('mysql'))
8278 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
8283 return new SimplePie_Cache_File($location, $filename, $extension);
8288 class SimplePie_Cache_File
8295 public function __construct($location, $filename, $extension)
8297 $this->location
= $location;
8298 $this->filename
= $filename;
8299 $this->extension
= $extension;
8300 $this->name
= "$this->location/$this->filename.$this->extension";
8303 public function save($data)
8305 if (file_exists($this->name
) && is_writeable($this->name
) ||
file_exists($this->location
) && is_writeable($this->location
))
8307 if (is_a($data, 'SimplePie'))
8309 $data = $data->data
;
8312 $data = serialize($data);
8313 return (bool) file_put_contents($this->name
, $data);
8318 public function load()
8320 if (file_exists($this->name
) && is_readable($this->name
))
8322 return unserialize(file_get_contents($this->name
));
8327 public function mtime()
8329 if (file_exists($this->name
))
8331 return filemtime($this->name
);
8336 public function touch()
8338 if (file_exists($this->name
))
8340 return touch($this->name
);
8345 public function unlink()
8347 if (file_exists($this->name
))
8349 return unlink($this->name
);
8355 class SimplePie_Cache_DB
8357 public function prepare_simplepie_object_for_cache($data)
8359 $items = $data->get_items();
8360 $items_by_id = array();
8364 foreach ($items as $item)
8366 $items_by_id[$item->get_id()] = $item;
8369 if (count($items_by_id) !== count($items))
8371 $items_by_id = array();
8372 foreach ($items as $item)
8374 $items_by_id[$item->get_id(true)] = $item;
8378 if (isset($data->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]))
8380 $channel =& $data->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0];
8382 elseif (isset($data->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]))
8384 $channel =& $data->data
['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0];
8386 elseif (isset($data->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]))
8388 $channel =& $data->data
['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0];
8390 elseif (isset($data->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['channel'][0]))
8392 $channel =& $data->data
['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['channel'][0];
8399 if ($channel !== null)
8401 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['entry']))
8403 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['entry']);
8405 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['entry']))
8407 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['entry']);
8409 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['item']))
8411 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10
]['item']);
8413 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['item']))
8415 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090
]['item']);
8417 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['item']))
8419 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['item']);
8422 if (isset($data->data
['items']))
8424 unset($data->data
['items']);
8426 if (isset($data->data
['ordered_items']))
8428 unset($data->data
['ordered_items']);
8431 return array(serialize($data->data
), $items_by_id);
8435 class SimplePie_Cache_MySQL
extends SimplePie_Cache_DB
8441 public function __construct($mysql_location, $name, $extension)
8443 $host = $mysql_location->get_host();
8444 if (stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
8446 $server = ':' . substr($host, 5, -1);
8451 if ($mysql_location->get_port() !== null)
8453 $server .= ':' . $mysql_location->get_port();
8457 if (strpos($mysql_location->get_userinfo(), ':') !== false)
8459 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
8463 $username = $mysql_location->get_userinfo();
8467 if ($this->mysql
= mysql_connect($server, $username, $password))
8469 $this->id
= $name . $extension;
8470 $this->options
= SimplePie_Misc
::parse_str($mysql_location->get_query());
8471 if (!isset($this->options
['prefix'][0]))
8473 $this->options
['prefix'][0] = '';
8476 if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
8477 && mysql_query('SET NAMES utf8')
8478 && ($query = mysql_unbuffered_query('SHOW TABLES')))
8481 while ($row = mysql_fetch_row($query))
8486 if (!in_array($this->options
['prefix'][0] . 'cache_data', $db))
8488 if (!mysql_query('CREATE TABLE `' . $this->options
['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
8490 $this->mysql
= null;
8494 if (!in_array($this->options
['prefix'][0] . 'items', $db))
8496 if (!mysql_query('CREATE TABLE `' . $this->options
['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
8498 $this->mysql
= null;
8504 $this->mysql
= null;
8509 public function save($data)
8513 $feed_id = "'" . mysql_real_escape_string($this->id
) . "'";
8515 if (is_a($data, 'SimplePie'))
8517 $data = clone $data;
8519 $prepared = $this->prepare_simplepie_object_for_cache($data);
8521 if ($query = mysql_query('SELECT `id` FROM `' . $this->options
['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql
))
8523 if (mysql_num_rows($query))
8525 $items = count($prepared[1]);
8528 $sql = 'UPDATE `' . $this->options
['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8532 $sql = 'UPDATE `' . $this->options
['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8535 if (!mysql_query($sql, $this->mysql
))
8540 elseif (!mysql_query('INSERT INTO `' . $this->options
['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql
))
8545 $ids = array_keys($prepared[1]);
8548 foreach ($ids as $id)
8550 $database_ids[] = mysql_real_escape_string($id);
8553 if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options
['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql
))
8555 $existing_ids = array();
8556 while ($row = mysql_fetch_row($query))
8558 $existing_ids[] = $row[0];
8561 $new_ids = array_diff($ids, $existing_ids);
8563 foreach ($new_ids as $new_id)
8565 if (!($date = $prepared[1][$new_id]->get_date('U')))
8570 if (!mysql_query('INSERT INTO `' . $this->options
['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data
)) . '\', ' . $date . ')', $this->mysql
))
8584 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options
['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql
))
8586 if (mysql_num_rows($query))
8588 if (mysql_query('UPDATE `' . $this->options
['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql
))
8593 elseif (mysql_query('INSERT INTO `' . $this->options
['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id
) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql
))
8602 public function load()
8604 if ($this->mysql
&& ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options
['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id
) . "'", $this->mysql
)) && ($row = mysql_fetch_row($query)))
8606 $data = unserialize($row[1]);
8608 if (isset($this->options
['items'][0]))
8610 $items = (int) $this->options
['items'][0];
8614 $items = (int) $row[0];
8619 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0]))
8621 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['feed'][0];
8623 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0]))
8625 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03
]['feed'][0];
8627 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0]))
8629 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF
]['RDF'][0];
8631 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0]))
8633 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20
]['rss'][0];
8642 $sql = 'SELECT `data` FROM `' . $this->options
['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id
) . '\' ORDER BY `posted` DESC';
8645 $sql .= ' LIMIT ' . $items;
8648 if ($query = mysql_unbuffered_query($sql, $this->mysql
))
8650 while ($row = mysql_fetch_row($query))
8652 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10
]['entry'][] = unserialize($row[0]);
8666 public function mtime()
8668 if ($this->mysql
&& ($query = mysql_query('SELECT `mtime` FROM `' . $this->options
['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id
) . "'", $this->mysql
)) && ($row = mysql_fetch_row($query)))
8678 public function touch()
8680 if ($this->mysql
&& ($query = mysql_query('UPDATE `' . $this->options
['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id
) . "'", $this->mysql
)) && mysql_affected_rows($this->mysql
))
8690 public function unlink()
8692 if ($this->mysql
&& ($query = mysql_query('DELETE FROM `' . $this->options
['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id
) . "'", $this->mysql
)) && ($query2 = mysql_query('DELETE FROM `' . $this->options
['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id
) . "'", $this->mysql
)))
8703 class SimplePie_Misc
8705 public static function time_hms($seconds)
8709 $hours = floor($seconds / 3600);
8710 $remainder = $seconds %
3600;
8713 $time .= $hours.':';
8716 $minutes = floor($remainder / 60);
8717 $seconds = $remainder %
60;
8718 if ($minutes < 10 && $hours > 0)
8720 $minutes = '0' . $minutes;
8724 $seconds = '0' . $seconds;
8727 $time .= $minutes.':';
8733 public static function absolutize_url($relative, $base)
8735 $iri = SimplePie_IRI
::absolutize(new SimplePie_IRI($base), $relative);
8736 return $iri->get_iri();
8739 public static function remove_dot_segments($input)
8742 while (strpos($input, './') !== false ||
strpos($input, '/.') !== false ||
$input === '.' ||
$input === '..')
8744 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
8745 if (strpos($input, '../') === 0)
8747 $input = substr($input, 3);
8749 elseif (strpos($input, './') === 0)
8751 $input = substr($input, 2);
8753 // 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,
8754 elseif (strpos($input, '/./') === 0)
8756 $input = substr_replace($input, '/', 0, 3);
8758 elseif ($input === '/.')
8762 // 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,
8763 elseif (strpos($input, '/../') === 0)
8765 $input = substr_replace($input, '/', 0, 4);
8766 $output = substr_replace($output, '', strrpos($output, '/'));
8768 elseif ($input === '/..')
8771 $output = substr_replace($output, '', strrpos($output, '/'));
8773 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
8774 elseif ($input === '.' ||
$input === '..')
8778 // 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
8779 elseif (($pos = strpos($input, '/', 1)) !== false)
8781 $output .= substr($input, 0, $pos);
8782 $input = substr_replace($input, '', 0, $pos);
8790 return $output . $input;
8793 public static function get_element($realname, $string)
8796 $name = preg_quote($realname, '/');
8797 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE
))
8799 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++
)
8801 $return[$i]['tag'] = $realname;
8802 $return[$i]['full'] = $matches[$i][0][0];
8803 $return[$i]['offset'] = $matches[$i][0][1];
8804 if (strlen($matches[$i][3][0]) <= 2)
8806 $return[$i]['self_closing'] = true;
8810 $return[$i]['self_closing'] = false;
8811 $return[$i]['content'] = $matches[$i][4][0];
8813 $return[$i]['attribs'] = array();
8814 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER
))
8816 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++
)
8818 if (count($attribs[$j]) === 2)
8820 $attribs[$j][2] = $attribs[$j][1];
8822 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc
::entities_decode(end($attribs[$j]), 'UTF-8');
8830 public static function element_implode($element)
8832 $full = "<$element[tag]";
8833 foreach ($element['attribs'] as $key => $value)
8835 $key = strtolower($key);
8836 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
8838 if ($element['self_closing'])
8844 $full .= ">$element[content]</$element[tag]>";
8849 public static function error($message, $level, $file, $line)
8851 if ((ini_get('error_reporting') & $level) > 0)
8856 $note = 'PHP Error';
8858 case E_USER_WARNING
:
8859 $note = 'PHP Warning';
8862 $note = 'PHP Notice';
8865 $note = 'Unknown Error';
8870 if (!function_exists('error_log'))
8875 $log_file = @ini_get
('error_log');
8876 if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable
($log_file))
8883 @error_log
("$note: $message in $file on line $line", 0);
8890 public static function fix_protocol($url, $http = 1)
8892 $url = SimplePie_Misc
::normalize_url($url);
8893 $parsed = SimplePie_Misc
::parse_url($url);
8894 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
8896 return SimplePie_Misc
::fix_protocol(SimplePie_Misc
::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
8899 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
8901 return SimplePie_Misc
::fix_protocol(SimplePie_Misc
::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
8904 if ($http === 2 && $parsed['scheme'] !== '')
8908 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
8910 return substr_replace($url, 'podcast', 0, 4);
8912 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
8914 return substr_replace($url, 'itpc', 0, 4);
8922 public static function parse_url($url)
8924 $iri = new SimplePie_IRI($url);
8926 'scheme' => (string) $iri->get_scheme(),
8927 'authority' => (string) $iri->get_authority(),
8928 'path' => (string) $iri->get_path(),
8929 'query' => (string) $iri->get_query(),
8930 'fragment' => (string) $iri->get_fragment()
8934 public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
8936 $iri = new SimplePie_IRI('');
8937 $iri->set_scheme($scheme);
8938 $iri->set_authority($authority);
8939 $iri->set_path($path);
8940 $iri->set_query($query);
8941 $iri->set_fragment($fragment);
8942 return $iri->get_iri();
8945 public static function normalize_url($url)
8947 $iri = new SimplePie_IRI($url);
8948 return $iri->get_iri();
8951 public static function percent_encoding_normalization($match)
8953 $integer = hexdec($match[1]);
8954 if ($integer >= 0x41 && $integer <= 0x5A ||
$integer >= 0x61 && $integer <= 0x7A ||
$integer >= 0x30 && $integer <= 0x39 ||
$integer === 0x2D ||
$integer === 0x2E ||
$integer === 0x5F ||
$integer === 0x7E)
8956 return chr($integer);
8960 return strtoupper($match[0]);
8965 * Converts a Windows-1252 encoded string to a UTF-8 encoded string
8969 * @param string $string Windows-1252 encoded string
8970 * @return string UTF-8 encoded string
8972 public static function windows_1252_to_utf8($string)
8974 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
8976 return strtr($string, $convert_table);
8979 public static function change_encoding($data, $input, $output)
8981 $input = SimplePie_Misc
::encoding($input);
8982 $output = SimplePie_Misc
::encoding($output);
8984 // We fail to fail on non US-ASCII bytes
8985 if ($input === 'US-ASCII')
8987 static $non_ascii_octects = '';
8988 if (!$non_ascii_octects)
8990 for ($i = 0x80; $i <= 0xFF; $i++
)
8992 $non_ascii_octects .= chr($i);
8995 $data = substr($data, 0, strcspn($data, $non_ascii_octects));
8998 // This is first, as behaviour of this is completely predictable
8999 if ($input === 'windows-1252' && $output === 'UTF-8')
9001 return SimplePie_Misc
::windows_1252_to_utf8($data);
9003 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9004 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding
("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding
($data, $output, $input)))
9008 // This is last, as behaviour of this varies with OS userland and PHP version
9009 elseif (function_exists('iconv') && ($return = @iconv
($input, $output, $data)))
9013 // If we can't do anything, just fail
9021 * Normalize an encoding name
9023 * This is automatically generated by create.php
9025 * To generate it, run `php create.php` on the command line, and copy the
9026 * output to replace this function.
9028 * @param string $charset Character set to standardise
9029 * @return string Standardised name
9031 public static function encoding($charset)
9033 // Normalization from UTS #22
9034 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9036 case 'adobestandardencoding':
9037 case 'csadobestandardencoding':
9038 return 'Adobe-Standard-Encoding';
9040 case 'adobesymbolencoding':
9042 return 'Adobe-Symbol-Encoding';
9046 return 'Amiga-1251';
9048 case 'ansix31101983':
9050 case 'csiso99naplps':
9053 return 'ANSI_X3.110-1983';
9057 case 'csiso89asmo449':
9067 return 'Big5-HKSCS';
9078 case 'csiso4unitedkingdom':
9086 case 'csiso47bsviewdata':
9088 return 'BS_viewdata';
9096 case 'csaz243419851':
9097 case 'csiso121canadian1':
9100 return 'CSA_Z243.4-1985-1';
9103 case 'csaz243419852':
9104 case 'csiso122canadian2':
9107 return 'CSA_Z243.4-1985-2';
9109 case 'csaz24341985gr':
9110 case 'csiso123csaz24341985gr':
9112 return 'CSA_Z243.4-1985-gr';
9114 case 'csiso139csn369103':
9117 return 'CSN_369103';
9124 case 'csiso21german':
9135 case 'csiso646danish':
9141 case 'csibmebcdicatde':
9143 return 'EBCDIC-AT-DE';
9145 case 'csebcdicatdea':
9147 return 'EBCDIC-AT-DE-A';
9149 case 'csebcdiccafr':
9151 return 'EBCDIC-CA-FR';
9153 case 'csebcdicdkno':
9155 return 'EBCDIC-DK-NO';
9157 case 'csebcdicdknoa':
9159 return 'EBCDIC-DK-NO-A';
9167 return 'EBCDIC-ES-A';
9171 return 'EBCDIC-ES-S';
9173 case 'csebcdicfise':
9175 return 'EBCDIC-FI-SE';
9177 case 'csebcdicfisea':
9179 return 'EBCDIC-FI-SE-A';
9201 case 'csiso111ecmacyrillic':
9202 case 'ecmacyrillic':
9205 return 'ECMA-cyrillic';
9207 case 'csiso17spanish':
9213 case 'csiso85spanish2':
9219 case 'cseucpkdfmtjapanese':
9221 case 'extendedunixcodepackedformatforjapanese':
9224 case 'cseucfixwidjapanese':
9225 case 'extendedunixcodefixedwidthforjapanese':
9226 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9234 case 'csiso58gb231280':
9244 case 'csiso57gb1988':
9248 return 'GB_1988-80';
9250 case 'csiso153gost1976874':
9254 return 'GOST_19768-74';
9257 case 'csiso150greekccitt':
9260 return 'greek-ccitt';
9262 case 'csiso88greek7':
9267 case 'csiso18greek7old':
9270 return 'greek7-old';
9274 return 'HP-DeskTop';
9286 return 'HP-Pi-font';
9295 return 'HZ-GB-2312';
9297 case 'csibmsymbols':
9299 return 'IBM-Symbols';
9376 case 'ebcdicjpkana':
9406 case 'cspc8codepage437':
9418 case 'cspc775baltic':
9424 case 'cspc850multilingual':
9455 case 'pcmultilingual850euro':
9473 case 'cspc862latinhebrew':
9515 case 'ebcdiccproece':
9528 case 'ebcdiccyrillic':
9562 case 'ebcdiclatin9euro':
9576 case 'ebcdicus37euro':
9582 case 'ebcdicde273euro':
9588 case 'ebcdicdk277euro':
9589 case 'ebcdicno277euro':
9595 case 'ebcdicfi278euro':
9596 case 'ebcdicse278euro':
9602 case 'ebcdicit280euro':
9608 case 'ebcdices284euro':
9614 case 'ebcdicgb285euro':
9620 case 'ebcdicfr297euro':
9626 case 'ebcdicinternational500euro':
9632 case 'ebcdicis871euro':
9636 case 'csiso143iecp271':
9646 case 'csiso50inis8':
9651 case 'csiso51iniscyrillic':
9652 case 'iniscyrillic':
9654 return 'INIS-cyrillic';
9661 return 'ISO-2022-CN';
9663 case 'iso2022cnext':
9664 return 'ISO-2022-CN-EXT';
9668 return 'ISO-2022-JP';
9670 case 'csiso2022jp2':
9672 return 'ISO-2022-JP-2';
9676 return 'ISO-2022-KR';
9678 case 'cswindows30latin1':
9679 case 'iso88591windows30latin1':
9680 return 'ISO-8859-1-Windows-3.0-Latin-1';
9682 case 'cswindows31latin1':
9683 case 'iso88591windows31latin1':
9684 return 'ISO-8859-1-Windows-3.1-Latin-1';
9688 case 'iso885921987':
9692 return 'ISO-8859-2';
9694 case 'cswindows31latin2':
9695 case 'iso88592windowslatin2':
9696 return 'ISO-8859-2-Windows-Latin-2';
9700 case 'iso885931988':
9704 return 'ISO-8859-3';
9708 case 'iso885941988':
9712 return 'ISO-8859-4';
9714 case 'csisolatincyrillic':
9717 case 'iso885951988':
9719 return 'ISO-8859-5';
9723 case 'csisolatinarabic':
9726 case 'iso885961987':
9728 return 'ISO-8859-6';
9732 return 'ISO-8859-6-E';
9736 return 'ISO-8859-6-I';
9738 case 'csisolatingreek':
9744 case 'iso885971987':
9746 return 'ISO-8859-7';
9748 case 'csisolatinhebrew':
9751 case 'iso885981988':
9753 return 'ISO-8859-8';
9757 return 'ISO-8859-8-E';
9761 return 'ISO-8859-8-I';
9763 case 'cswindows31latin5':
9764 case 'iso88599windowslatin5':
9765 return 'ISO-8859-9-Windows-Latin-5';
9769 case 'iso8859101992':
9773 return 'ISO-8859-10';
9776 return 'ISO-8859-13';
9779 case 'iso8859141998':
9784 return 'ISO-8859-14';
9788 return 'ISO-8859-15';
9791 case 'iso8859162001':
9795 return 'ISO-8859-16';
9798 return 'ISO-10646-J-1';
9801 case 'iso10646ucs2':
9802 return 'ISO-10646-UCS-2';
9805 case 'iso10646ucs4':
9806 return 'ISO-10646-UCS-4';
9808 case 'csunicodeascii':
9809 case 'iso10646ucsbasic':
9810 return 'ISO-10646-UCS-Basic';
9812 case 'csunicodelatin1':
9814 case 'iso10646unicodelatin1':
9815 return 'ISO-10646-Unicode-Latin1';
9817 case 'csiso10646utf1':
9818 case 'iso10646utf1':
9819 return 'ISO-10646-UTF-1';
9824 return 'ISO-11548-1';
9830 case 'csunicodeibm1261':
9831 case 'isounicodeibm1261':
9832 return 'ISO-Unicode-IBM-1261';
9834 case 'csunicodeibm1264':
9835 case 'isounicodeibm1264':
9836 return 'ISO-Unicode-IBM-1264';
9838 case 'csunicodeibm1265':
9839 case 'isounicodeibm1265':
9840 return 'ISO-Unicode-IBM-1265';
9842 case 'csunicodeibm1268':
9843 case 'isounicodeibm1268':
9844 return 'ISO-Unicode-IBM-1268';
9846 case 'csunicodeibm1276':
9847 case 'isounicodeibm1276':
9848 return 'ISO-Unicode-IBM-1276';
9850 case 'csiso646basic1983':
9851 case 'iso646basic1983':
9853 return 'ISO_646.basic:1983';
9855 case 'csiso2intlrefversion':
9857 case 'iso646irv1983':
9859 return 'ISO_646.irv:1983';
9865 return 'ISO_2033-1983';
9867 case 'csiso5427cyrillic':
9872 case 'iso5427cyrillic1981':
9875 return 'ISO_5427:1981';
9877 case 'csiso5428greek':
9880 return 'ISO_5428:1980';
9882 case 'csiso6937add':
9885 return 'ISO_6937-2-25';
9887 case 'csisotextcomm':
9890 return 'ISO_6937-2-add';
9892 case 'csiso8859supp':
9896 return 'ISO_8859-supp';
9898 case 'csiso10367box':
9901 return 'ISO_10367-box';
9903 case 'csiso15italian':
9909 case 'csiso13jisc6220jp':
9911 case 'jisc62201969':
9912 case 'jisc62201969jp':
9915 return 'JIS_C6220-1969-jp';
9917 case 'csiso14jisc6220ro':
9920 case 'jisc62201969ro':
9922 return 'JIS_C6220-1969-ro';
9924 case 'csiso42jisc62261978':
9926 case 'jisc62261978':
9927 return 'JIS_C6226-1978';
9929 case 'csiso87jisx208':
9931 case 'jisc62261983':
9934 return 'JIS_C6226-1983';
9936 case 'csiso91jisc62291984a':
9938 case 'jisc62291984a':
9940 return 'JIS_C6229-1984-a';
9942 case 'csiso92jisc62991984b':
9943 case 'iso646jpocrb':
9945 case 'jisc62291984b':
9947 return 'JIS_C6229-1984-b';
9949 case 'csiso93jis62291984badd':
9951 case 'jisc62291984badd':
9953 return 'JIS_C6229-1984-b-add';
9955 case 'csiso94jis62291984hand':
9957 case 'jisc62291984hand':
9959 return 'JIS_C6229-1984-hand';
9961 case 'csiso95jis62291984handadd':
9963 case 'jisc62291984handadd':
9964 case 'jpocrhandadd':
9965 return 'JIS_C6229-1984-hand-add';
9967 case 'csiso96jisc62291984kana':
9969 case 'jisc62291984kana':
9970 return 'JIS_C6229-1984-kana';
9972 case 'csjisencoding':
9974 return 'JIS_Encoding';
9976 case 'cshalfwidthkatakana':
9981 case 'csiso159jisx2121990':
9985 return 'JIS_X0212-1990';
9987 case 'csiso141jusib1002':
9993 return 'JUS_I.B1.002';
9995 case 'csiso147macedonian':
9997 case 'jusib1003mac':
9999 return 'JUS_I.B1.003-mac';
10001 case 'csiso146serbian':
10003 case 'jusib1003serb':
10005 return 'JUS_I.B1.003-serb';
10007 case 'koi7switched':
10008 return 'KOI7-switched';
10025 case 'strk10482002':
10028 case 'csiso19latingreek':
10031 return 'latin-greek';
10033 case 'csiso27latingreek1':
10035 case 'latingreek1':
10036 return 'Latin-greek-1';
10038 case 'csiso158lap':
10042 return 'latin-lap';
10044 case 'csmacintosh':
10047 return 'macintosh';
10049 case 'csmicrosoftpublishing':
10050 case 'microsoftpublishing':
10051 return 'Microsoft-Publishing';
10061 case 'csiso86hungarian':
10066 return 'MSZ_7795.3';
10071 return 'NATS-DANO';
10073 case 'csnatsdanoadd':
10075 case 'natsdanoadd':
10076 return 'NATS-DANO-ADD';
10081 return 'NATS-SEFI';
10083 case 'csnatssefiadd':
10085 case 'natssefiadd':
10086 return 'NATS-SEFI-ADD';
10088 case 'csiso151cuba':
10093 return 'NC_NC00-10:81';
10095 case 'csiso69french':
10100 return 'NF_Z_62-010';
10102 case 'csiso25french':
10105 case 'nfz620101973':
10106 return 'NF_Z_62-010_(1973)';
10108 case 'csiso60danishnorwegian':
10109 case 'csiso60norwegian1':
10114 return 'NS_4551-1';
10116 case 'csiso61norwegian2':
10121 return 'NS_4551-2';
10123 case 'osdebcdicdf3irv':
10124 return 'OSD_EBCDIC_DF03_IRV';
10126 case 'osdebcdicdf41':
10127 return 'OSD_EBCDIC_DF04_1';
10129 case 'osdebcdicdf415':
10130 return 'OSD_EBCDIC_DF04_15';
10132 case 'cspc8danishnorwegian':
10133 case 'pc8danishnorwegian':
10134 return 'PC8-Danish-Norwegian';
10136 case 'cspc8turkish':
10138 return 'PC8-Turkish';
10140 case 'csiso16portuguese':
10146 case 'csiso84portuguese2':
10154 case 'cyrillicasian':
10162 case 'csiso10swedish':
10169 return 'SEN_850200_B';
10171 case 'csiso11swedishfornames':
10176 return 'SEN_850200_C';
10178 case 'csiso102t617bit':
10181 return 'T.61-7bit';
10183 case 'csiso103t618bit':
10187 return 'T.61-8bit';
10189 case 'csiso128t101g2':
10198 case 'csunicode11':
10200 return 'UNICODE-1-1';
10202 case 'csunicode11utf7':
10203 case 'unicode11utf7':
10204 return 'UNICODE-1-1-UTF-7';
10206 case 'csunknown8bit':
10207 case 'unknown8bit':
10208 return 'UNKNOWN-8BIT';
10210 case 'ansix341968':
10211 case 'ansix341986':
10216 case 'iso646irv1991':
10251 case 'csventurainternational':
10252 case 'venturainternational':
10253 return 'Ventura-International';
10255 case 'csventuramath':
10256 case 'venturamath':
10257 return 'Ventura-Math';
10259 case 'csventuraus':
10261 return 'Ventura-US';
10263 case 'csiso70videotexsupp1':
10265 case 'videotexsuppl':
10266 return 'videotex-suppl';
10277 case 'cswindows31j':
10281 return 'Windows-31J';
10285 return 'windows-874';
10288 case 'csksc56011987':
10293 case 'ksc56011987':
10294 case 'ksc56011989':
10296 return 'windows-949';
10298 case 'windows1250':
10299 return 'windows-1250';
10301 case 'windows1251':
10302 return 'windows-1251';
10305 case 'csisolatin1':
10308 case 'iso885911987':
10312 case 'windows1252':
10313 return 'windows-1252';
10315 case 'windows1253':
10316 return 'windows-1253';
10318 case 'csisolatin5':
10320 case 'iso885991989':
10324 case 'windows1254':
10325 return 'windows-1254';
10327 case 'windows1255':
10328 return 'windows-1255';
10330 case 'windows1256':
10331 return 'windows-1256';
10333 case 'windows1257':
10334 return 'windows-1257';
10336 case 'windows1258':
10337 return 'windows-1258';
10344 public static function get_curl_version()
10346 if (is_array($curl = curl_version()))
10348 $curl = $curl['version'];
10350 elseif (substr($curl, 0, 5) === 'curl/')
10352 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10354 elseif (substr($curl, 0, 8) === 'libcurl/')
10356 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10365 public static function is_subclass_of($class1, $class2)
10367 if (func_num_args() !== 2)
10369 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING
);
10371 elseif (version_compare(PHP_VERSION
, '5.0.3', '>=') ||
is_object($class1))
10373 return is_subclass_of($class1, $class2);
10375 elseif (is_string($class1) && is_string($class2))
10377 if (class_exists($class1))
10379 if (class_exists($class2))
10381 $class2 = strtolower($class2);
10382 while ($class1 = strtolower(get_parent_class($class1)))
10384 if ($class1 === $class2)
10393 trigger_error('Unknown class passed as parameter', E_USER_WARNNG
);
10400 * Strip HTML comments
10403 * @param string $data Data to strip comments from
10404 * @return string Comment stripped string
10406 public static function strip_comments($data)
10409 while (($start = strpos($data, '<!--')) !== false)
10411 $output .= substr($data, 0, $start);
10412 if (($end = strpos($data, '-->', $start)) !== false)
10414 $data = substr_replace($data, '', 0, $end +
3);
10421 return $output . $data;
10424 public static function parse_date($dt)
10426 $parser = SimplePie_Parse_Date
::get();
10427 return $parser->parse($dt);
10431 * Decode HTML entities
10435 * @param string $data Input data
10436 * @return string Output data
10438 public static function entities_decode($data)
10440 $decoder = new SimplePie_Decode_HTML_Entities($data);
10441 return $decoder->parse();
10445 * Remove RFC822 comments
10448 * @param string $data Data to strip comments from
10449 * @return string Comment stripped string
10451 public static function uncomment_rfc822($string)
10453 $string = (string) $string;
10455 $length = strlen($string);
10460 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10462 $output .= substr($string, $position, $pos - $position);
10463 $position = $pos +
1;
10464 if ($string[$pos - 1] !== '\\')
10467 while ($depth && $position < $length)
10469 $position +
= strcspn($string, '()', $position);
10470 if ($string[$position - 1] === '\\')
10475 elseif (isset($string[$position]))
10477 switch ($string[$position])
10500 $output .= substr($string, $position);
10505 public static function parse_mime($mime)
10507 if (($pos = strpos($mime, ';')) === false)
10509 return trim($mime);
10513 return trim(substr($mime, 0, $pos));
10517 public static function htmlspecialchars_decode($string, $quote_style)
10519 if (function_exists('htmlspecialchars_decode'))
10521 return htmlspecialchars_decode($string, $quote_style);
10525 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS
, $quote_style)));
10529 public static function atom_03_construct_type($attribs)
10531 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
10533 $mode = SIMPLEPIE_CONSTRUCT_BASE64
;
10537 $mode = SIMPLEPIE_CONSTRUCT_NONE
;
10539 if (isset($attribs['']['type']))
10541 switch (strtolower(trim($attribs['']['type'])))
10545 return SIMPLEPIE_CONSTRUCT_TEXT |
$mode;
10549 return SIMPLEPIE_CONSTRUCT_HTML |
$mode;
10552 case 'application/xhtml+xml':
10553 return SIMPLEPIE_CONSTRUCT_XHTML |
$mode;
10556 return SIMPLEPIE_CONSTRUCT_NONE |
$mode;
10561 return SIMPLEPIE_CONSTRUCT_TEXT |
$mode;
10565 public static function atom_10_construct_type($attribs)
10567 if (isset($attribs['']['type']))
10569 switch (strtolower(trim($attribs['']['type'])))
10572 return SIMPLEPIE_CONSTRUCT_TEXT
;
10575 return SIMPLEPIE_CONSTRUCT_HTML
;
10578 return SIMPLEPIE_CONSTRUCT_XHTML
;
10581 return SIMPLEPIE_CONSTRUCT_NONE
;
10584 return SIMPLEPIE_CONSTRUCT_TEXT
;
10587 public static function atom_10_content_construct_type($attribs)
10589 if (isset($attribs['']['type']))
10591 $type = strtolower(trim($attribs['']['type']));
10595 return SIMPLEPIE_CONSTRUCT_TEXT
;
10598 return SIMPLEPIE_CONSTRUCT_HTML
;
10601 return SIMPLEPIE_CONSTRUCT_XHTML
;
10603 if (in_array(substr($type, -4), array('+xml', '/xml')) ||
substr($type, 0, 5) === 'text/')
10605 return SIMPLEPIE_CONSTRUCT_NONE
;
10609 return SIMPLEPIE_CONSTRUCT_BASE64
;
10614 return SIMPLEPIE_CONSTRUCT_TEXT
;
10618 public static function is_isegment_nz_nc($string)
10620 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);
10623 public static function space_seperated_tokens($string)
10625 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
10626 $string_length = strlen($string);
10628 $position = strspn($string, $space_characters);
10631 while ($position < $string_length)
10633 $len = strcspn($string, $space_characters, $position);
10634 $tokens[] = substr($string, $position, $len);
10636 $position +
= strspn($string, $space_characters, $position);
10642 public static function array_unique($array)
10644 if (version_compare(PHP_VERSION
, '5.2', '>='))
10646 return array_unique($array);
10650 $array = (array) $array;
10651 $new_array = array();
10652 $new_array_strings = array();
10653 foreach ($array as $key => $value)
10655 if (is_object($value))
10657 if (method_exists($value, '__toString'))
10659 $cmp = $value->__toString();
10663 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR
);
10666 elseif (is_array($value))
10668 $cmp = (string) reset($value);
10672 $cmp = (string) $value;
10674 if (!in_array($cmp, $new_array_strings))
10676 $new_array[$key] = $value;
10677 $new_array_strings[] = $cmp;
10685 * Converts a unicode codepoint to a UTF-8 character
10689 * @param int $codepoint Unicode codepoint
10690 * @return string UTF-8 character
10692 public static function codepoint_to_utf8($codepoint)
10694 $codepoint = (int) $codepoint;
10695 if ($codepoint < 0)
10699 else if ($codepoint <= 0x7f)
10701 return chr($codepoint);
10703 else if ($codepoint <= 0x7ff)
10705 return chr(0xc0 |
($codepoint >> 6)) . chr(0x80 |
($codepoint & 0x3f));
10707 else if ($codepoint <= 0xffff)
10709 return chr(0xe0 |
($codepoint >> 12)) . chr(0x80 |
(($codepoint >> 6) & 0x3f)) . chr(0x80 |
($codepoint & 0x3f));
10711 else if ($codepoint <= 0x10ffff)
10713 return chr(0xf0 |
($codepoint >> 18)) . chr(0x80 |
(($codepoint >> 12) & 0x3f)) . chr(0x80 |
(($codepoint >> 6) & 0x3f)) . chr(0x80 |
($codepoint & 0x3f));
10717 // U+FFFD REPLACEMENT CHARACTER
10718 return "\xEF\xBF\xBD";
10723 * Similar to parse_str()
10725 * Returns an associative array of name/value pairs, where the value is an
10726 * array of values that have used the same name
10730 * @param string $str The input string.
10733 public static function parse_str($str)
10736 $str = explode('&', $str);
10738 foreach ($str as $section)
10740 if (strpos($section, '=') !== false)
10742 list($name, $value) = explode('=', $section, 2);
10743 $return[urldecode($name)][] = urldecode($value);
10747 $return[urldecode($section)][] = null;
10755 * Detect XML encoding, as per XML 1.0 Appendix F.1
10757 * @todo Add support for EBCDIC
10758 * @param string $data XML data
10759 * @return array Possible encodings
10761 public static function xml_encoding($data)
10763 // UTF-32 Big Endian BOM
10764 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
10766 $encoding[] = 'UTF-32BE';
10768 // UTF-32 Little Endian BOM
10769 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
10771 $encoding[] = 'UTF-32LE';
10773 // UTF-16 Big Endian BOM
10774 elseif (substr($data, 0, 2) === "\xFE\xFF")
10776 $encoding[] = 'UTF-16BE';
10778 // UTF-16 Little Endian BOM
10779 elseif (substr($data, 0, 2) === "\xFF\xFE")
10781 $encoding[] = 'UTF-16LE';
10784 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
10786 $encoding[] = 'UTF-8';
10788 // UTF-32 Big Endian Without BOM
10789 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
10791 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
10793 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
10794 if ($parser->parse())
10796 $encoding[] = $parser->encoding
;
10799 $encoding[] = 'UTF-32BE';
10801 // UTF-32 Little Endian Without BOM
10802 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
10804 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
10806 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
10807 if ($parser->parse())
10809 $encoding[] = $parser->encoding
;
10812 $encoding[] = 'UTF-32LE';
10814 // UTF-16 Big Endian Without BOM
10815 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
10817 if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
10819 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
10820 if ($parser->parse())
10822 $encoding[] = $parser->encoding
;
10825 $encoding[] = 'UTF-16BE';
10827 // UTF-16 Little Endian Without BOM
10828 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
10830 if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
10832 $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc
::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
10833 if ($parser->parse())
10835 $encoding[] = $parser->encoding
;
10838 $encoding[] = 'UTF-16LE';
10840 // US-ASCII (or superset)
10841 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
10843 if ($pos = strpos($data, "\x3F\x3E"))
10845 $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
10846 if ($parser->parse())
10848 $encoding[] = $parser->encoding
;
10851 $encoding[] = 'UTF-8';
10853 // Fallback to UTF-8
10856 $encoding[] = 'UTF-8';
10861 public static function output_javascript()
10863 if (function_exists('ob_gzhandler'))
10865 ob_start('ob_gzhandler');
10867 header('Content-type: text/javascript; charset: UTF-8');
10868 header('Cache-Control: must-revalidate');
10869 header('Expires: ' . gmdate('D, d M Y H:i:s', time() +
604800) . ' GMT'); // 7 days
10871 function embed_odeo(link
) {
10872 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>');
10875 function embed_quicktime(type
, bgcolor
, width
, height
, link
, placeholder
, loop
) {
10876 if (placeholder
!= '') {
10877 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>');
10880 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>');
10884 function embed_flash(bgcolor
, width
, height
, link
, loop
, type
) {
10885 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>');
10888 function embed_flv(width
, height
, link
, placeholder
, loop
, player
) {
10889 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>');
10892 function embed_wmedia(width
, height
, link
) {
10893 document
.writeln('<embed type="application/x-mplayer2" src="'+link+
'" autosize="1" width="'+width+
'" height="'+height+
'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
10900 * Decode HTML Entities
10902 * This implements HTML5 as of revision 967 (2007-06-28)
10904 * @package SimplePie
10906 class SimplePie_Decode_HTML_Entities
10909 * Data to be parsed
10917 * Currently consumed bytes
10922 var $consumed = '';
10925 * Position of the current byte being parsed
10933 * Create an instance of the class with the input data
10936 * @param string $data Input data
10938 public function __construct($data)
10940 $this->data
= $data;
10944 * Parse the input data
10947 * @return string Output data
10949 public function parse()
10951 while (($this->position
= strpos($this->data
, '&', $this->position
)) !== false)
10955 $this->consumed
= '';
10957 return $this->data
;
10961 * Consume the next byte
10964 * @return mixed The next byte, or false, if there is no more data
10966 public function consume()
10968 if (isset($this->data
[$this->position
]))
10970 $this->consumed
.= $this->data
[$this->position
];
10971 return $this->data
[$this->position++
];
10980 * Consume a range of characters
10983 * @param string $chars Characters to consume
10984 * @return mixed A series of characters that match the range, or false
10986 public function consume_range($chars)
10988 if ($len = strspn($this->data
, $chars, $this->position
))
10990 $data = substr($this->data
, $this->position
, $len);
10991 $this->consumed
.= $data;
10992 $this->position +
= $len;
11002 * Unconsume one byte
11006 public function unconsume()
11008 $this->consumed
= substr($this->consumed
, 0, -1);
11017 public function entity()
11019 switch ($this->consume())
11033 switch ($this->consume())
11037 $range = '0123456789ABCDEFabcdef';
11042 $range = '0123456789';
11044 $this->unconsume();
11048 if ($codepoint = $this->consume_range($range))
11050 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");
11054 $codepoint = hexdec($codepoint);
11058 $codepoint = intval($codepoint);
11061 if (isset($windows_1252_specials[$codepoint]))
11063 $replacement = $windows_1252_specials[$codepoint];
11067 $replacement = SimplePie_Misc
::codepoint_to_utf8($codepoint);
11070 if (!in_array($this->consume(), array(';', false), true))
11072 $this->unconsume();
11075 $consumed_length = strlen($this->consumed
);
11076 $this->data
= substr_replace($this->data
, $replacement, $this->position
- $consumed_length, $consumed_length);
11077 $this->position +
= strlen($replacement) - $consumed_length;
11082 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");
11084 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++
)
11086 $consumed = substr($this->consumed
, 1);
11087 if (isset($entities[$consumed]))
11089 $match = $consumed;
11093 if ($match !== null)
11095 $this->data
= substr_replace($this->data
, $entities[$match], $this->position
- strlen($consumed) - 1, strlen($match) +
1);
11096 $this->position +
= strlen($entities[$match]) - strlen($consumed) - 1;
11104 * IRI parser/serialiser
11106 * @package SimplePie
11108 class SimplePie_IRI
11167 * Whether the object represents a valid IRI
11172 var $valid = array();
11175 * Return the entire IRI when you try and read the object as a string
11180 public function __toString()
11182 return $this->get_iri();
11186 * Create a new IRI object, from a specified string
11189 * @param string $iri
11190 * @return SimplePie_IRI
11192 public function __construct($iri)
11194 $iri = (string) $iri;
11197 $parsed = $this->parse_iri($iri);
11198 $this->set_scheme($parsed['scheme']);
11199 $this->set_authority($parsed['authority']);
11200 $this->set_path($parsed['path']);
11201 $this->set_query($parsed['query']);
11202 $this->set_fragment($parsed['fragment']);
11207 * Create a new IRI object by resolving a relative IRI
11211 * @param SimplePie_IRI $base Base IRI
11212 * @param string $relative Relative IRI
11213 * @return SimplePie_IRI
11215 public static function absolutize($base, $relative)
11217 $relative = (string) $relative;
11218 if ($relative !== '')
11220 $relative = new SimplePie_IRI($relative);
11221 if ($relative->get_scheme() !== null)
11223 $target = $relative;
11225 elseif ($base->get_iri() !== null)
11227 if ($relative->get_authority() !== null)
11229 $target = $relative;
11230 $target->set_scheme($base->get_scheme());
11234 $target = new SimplePie_IRI('');
11235 $target->set_scheme($base->get_scheme());
11236 $target->set_userinfo($base->get_userinfo());
11237 $target->set_host($base->get_host());
11238 $target->set_port($base->get_port());
11239 if ($relative->get_path() !== null)
11241 if (strpos($relative->get_path(), '/') === 0)
11243 $target->set_path($relative->get_path());
11245 elseif (($base->get_userinfo() !== null ||
$base->get_host() !== null ||
$base->get_port() !== null) && $base->get_path() === null)
11247 $target->set_path('/' . $relative->get_path());
11249 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11251 $target->set_path(substr($base->get_path(), 0, $last_segment +
1) . $relative->get_path());
11255 $target->set_path($relative->get_path());
11257 $target->set_query($relative->get_query());
11261 $target->set_path($base->get_path());
11262 if ($relative->get_query() !== null)
11264 $target->set_query($relative->get_query());
11266 elseif ($base->get_query() !== null)
11268 $target->set_query($base->get_query());
11272 $target->set_fragment($relative->get_fragment());
11276 // No base URL, just return the relative URL
11277 $target = $relative;
11288 * Parse an IRI into scheme/authority/path/query/fragment segments
11291 * @param string $iri
11294 public function parse_iri($iri)
11296 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11297 for ($i = count($match); $i <= 9; $i++
)
11301 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11305 * Remove dot segments from a path
11308 * @param string $input
11311 public function remove_dot_segments($input)
11314 while (strpos($input, './') !== false ||
strpos($input, '/.') !== false ||
$input === '.' ||
$input === '..')
11316 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11317 if (strpos($input, '../') === 0)
11319 $input = substr($input, 3);
11321 elseif (strpos($input, './') === 0)
11323 $input = substr($input, 2);
11325 // 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,
11326 elseif (strpos($input, '/./') === 0)
11328 $input = substr_replace($input, '/', 0, 3);
11330 elseif ($input === '/.')
11334 // 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,
11335 elseif (strpos($input, '/../') === 0)
11337 $input = substr_replace($input, '/', 0, 4);
11338 $output = substr_replace($output, '', strrpos($output, '/'));
11340 elseif ($input === '/..')
11343 $output = substr_replace($output, '', strrpos($output, '/'));
11345 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11346 elseif ($input === '.' ||
$input === '..')
11350 // 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
11351 elseif (($pos = strpos($input, '/', 1)) !== false)
11353 $output .= substr($input, 0, $pos);
11354 $input = substr_replace($input, '', 0, $pos);
11362 return $output . $input;
11366 * Replace invalid character with percent encoding
11369 * @param string $string Input string
11370 * @param string $valid_chars Valid characters
11371 * @param int $case Normalise case
11374 public function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE
)
11377 if ($case & SIMPLEPIE_LOWERCASE
)
11379 $string = strtolower($string);
11381 elseif ($case & SIMPLEPIE_UPPERCASE
)
11383 $string = strtoupper($string);
11386 // Store position and string length (to avoid constantly recalculating this)
11388 $strlen = strlen($string);
11390 // Loop as long as we have invalid characters, advancing the position to the next invalid character
11391 while (($position +
= strspn($string, $valid_chars, $position)) < $strlen)
11393 // If we have a % character
11394 if ($string[$position] === '%')
11396 // If we have a pct-encoded section
11397 if ($position +
2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position +
1, 2) === 2)
11399 // Get the the represented character
11400 $chr = chr(hexdec(substr($string, $position +
1, 2)));
11402 // If the character is valid, replace the pct-encoded with the actual character while normalising case
11403 if (strpos($valid_chars, $chr) !== false)
11405 if ($case & SIMPLEPIE_LOWERCASE
)
11407 $chr = strtolower($chr);
11409 elseif ($case & SIMPLEPIE_UPPERCASE
)
11411 $chr = strtoupper($chr);
11413 $string = substr_replace($string, $chr, $position, 3);
11418 // Otherwise just normalise the pct-encoded to uppercase
11421 $string = substr_replace($string, strtoupper(substr($string, $position +
1, 2)), $position +
1, 2);
11425 // If we don't have a pct-encoded section, just replace the % with its own esccaped form
11428 $string = substr_replace($string, '%25', $position, 1);
11433 // If we have an invalid character, change into its pct-encoded form
11436 $replacement = sprintf("%%%02X", ord($string[$position]));
11437 $string = str_replace($string[$position], $replacement, $string);
11438 $strlen = strlen($string);
11445 * Check if the object represents a valid IRI
11450 public function is_valid()
11452 return array_sum($this->valid
) === count($this->valid
);
11456 * Set the scheme. Returns true on success, false on failure (if there are
11457 * any invalid characters).
11460 * @param string $scheme
11463 public function set_scheme($scheme)
11465 if ($scheme === null ||
$scheme === '')
11467 $this->scheme
= null;
11471 $len = strlen($scheme);
11475 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
11477 $this->scheme
= null;
11478 $this->valid
[__FUNCTION__
] = false;
11483 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
11485 $this->scheme
= null;
11486 $this->valid
[__FUNCTION__
] = false;
11490 $this->scheme
= strtolower($scheme);
11492 $this->valid
[__FUNCTION__
] = true;
11497 * Set the authority. Returns true on success, false on failure (if there are
11498 * any invalid characters).
11501 * @param string $authority
11504 public function set_authority($authority)
11506 if (($userinfo_end = strrpos($authority, '@')) !== false)
11508 $userinfo = substr($authority, 0, $userinfo_end);
11509 $authority = substr($authority, $userinfo_end +
1);
11516 if (($port_start = strpos($authority, ':')) !== false)
11518 $port = substr($authority, $port_start +
1);
11519 $authority = substr($authority, 0, $port_start);
11526 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
11530 * Set the userinfo.
11533 * @param string $userinfo
11536 public function set_userinfo($userinfo)
11538 if ($userinfo === null ||
$userinfo === '')
11540 $this->userinfo
= null;
11544 $this->userinfo
= $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
11546 $this->valid
[__FUNCTION__
] = true;
11551 * Set the host. Returns true on success, false on failure (if there are
11552 * any invalid characters).
11555 * @param string $host
11558 public function set_host($host)
11560 if ($host === null ||
$host === '')
11562 $this->host
= null;
11563 $this->valid
[__FUNCTION__
] = true;
11566 elseif ($host[0] === '[' && substr($host, -1) === ']')
11568 if (Net_IPv6
::checkIPv6(substr($host, 1, -1)))
11570 $this->host
= $host;
11571 $this->valid
[__FUNCTION__
] = true;
11576 $this->host
= null;
11577 $this->valid
[__FUNCTION__
] = false;
11583 $this->host
= $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE
);
11584 $this->valid
[__FUNCTION__
] = true;
11590 * Set the port. Returns true on success, false on failure (if there are
11591 * any invalid characters).
11594 * @param string $port
11597 public function set_port($port)
11599 if ($port === null ||
$port === '')
11601 $this->port
= null;
11602 $this->valid
[__FUNCTION__
] = true;
11605 elseif (strspn($port, '0123456789') === strlen($port))
11607 $this->port
= (int) $port;
11608 $this->valid
[__FUNCTION__
] = true;
11613 $this->port
= null;
11614 $this->valid
[__FUNCTION__
] = false;
11623 * @param string $path
11626 public function set_path($path)
11628 if ($path === null ||
$path === '')
11630 $this->path
= null;
11631 $this->valid
[__FUNCTION__
] = true;
11634 elseif (substr($path, 0, 2) === '//' && $this->userinfo
=== null && $this->host
=== null && $this->port
=== null)
11636 $this->path
= null;
11637 $this->valid
[__FUNCTION__
] = false;
11642 $this->path
= $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
11643 if ($this->scheme
!== null)
11645 $this->path
= $this->remove_dot_segments($this->path
);
11647 $this->valid
[__FUNCTION__
] = true;
11656 * @param string $query
11659 public function set_query($query)
11661 if ($query === null ||
$query === '')
11663 $this->query
= null;
11667 $this->query
= $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
11669 $this->valid
[__FUNCTION__
] = true;
11674 * Set the fragment.
11677 * @param string $fragment
11680 public function set_fragment($fragment)
11682 if ($fragment === null ||
$fragment === '')
11684 $this->fragment
= null;
11688 $this->fragment
= $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
11690 $this->valid
[__FUNCTION__
] = true;
11695 * Get the complete IRI
11700 public function get_iri()
11703 if ($this->scheme
!== null)
11705 $iri .= $this->scheme
. ':';
11707 if (($authority = $this->get_authority()) !== null)
11709 $iri .= '//' . $authority;
11711 if ($this->path
!== null)
11713 $iri .= $this->path
;
11715 if ($this->query
!== null)
11717 $iri .= '?' . $this->query
;
11719 if ($this->fragment
!== null)
11721 $iri .= '#' . $this->fragment
;
11740 public function get_scheme()
11742 return $this->scheme
;
11746 * Get the complete authority
11751 public function get_authority()
11754 if ($this->userinfo
!== null)
11756 $authority .= $this->userinfo
. '@';
11758 if ($this->host
!== null)
11760 $authority .= $this->host
;
11762 if ($this->port
!== null)
11764 $authority .= ':' . $this->port
;
11767 if ($authority !== '')
11778 * Get the user information
11783 public function get_userinfo()
11785 return $this->userinfo
;
11794 public function get_host()
11796 return $this->host
;
11805 public function get_port()
11807 return $this->port
;
11816 public function get_path()
11818 return $this->path
;
11827 public function get_query()
11829 return $this->query
;
11838 public function get_fragment()
11840 return $this->fragment
;
11845 * Class to validate and to work with IPv6 addresses.
11847 * @package SimplePie
11848 * @copyright 2003-2005 The PHP Group
11849 * @license http://www.opensource.org/licenses/bsd-license.php
11850 * @link http://pear.php.net/package/Net_IPv6
11851 * @author Alexander Merz <alexander.merz@web.de>
11852 * @author elfrink at introweb dot nl
11853 * @author Josh Peck <jmp at joshpeck dot org>
11854 * @author Geoffrey Sneddon <geoffers@gmail.com>
11856 class SimplePie_Net_IPv6
11859 * Removes a possible existing netmask specification of an IP address.
11861 * @param string $ip the (compressed) IP as Hex representation
11862 * @return string the IP the without netmask
11867 public static function removeNetmaskSpec($ip)
11869 if (strpos($ip, '/') !== false)
11871 list($addr, $nm) = explode('/', $ip);
11881 * Uncompresses an IPv6 address
11883 * RFC 2373 allows you to compress zeros in an address to '::'. This
11884 * function expects an valid IPv6 address and expands the '::' to
11885 * the required zeros.
11887 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
11888 * ::1 -> 0:0:0:0:0:0:0:1
11892 * @param string $ip a valid IPv6-address (hex format)
11893 * @return string the uncompressed IPv6-address (hex format)
11895 public static function Uncompress($ip)
11897 $uip = SimplePie_Net_IPv6
::removeNetmaskSpec($ip);
11900 if (strpos($ip, '::') !== false)
11902 list($ip1, $ip2) = explode('::', $ip);
11910 if (($pos = substr_count($ip1, ':')) > 0)
11926 if (($pos = substr_count($ip2, ':')) > 0)
11935 if (strstr($ip2, '.'))
11940 if ($c1 === -1 && $c2 === -1)
11942 $uip = '0:0:0:0:0:0:0:0';
11945 else if ($c1 === -1)
11947 $fill = str_repeat('0:', 7 - $c2);
11948 $uip = str_replace('::', $fill, $uip);
11951 else if ($c2 === -1)
11953 $fill = str_repeat(':0', 7 - $c1);
11954 $uip = str_replace('::', $fill, $uip);
11959 $fill = str_repeat(':0:', 6 - $c2 - $c1);
11960 $uip = str_replace('::', $fill, $uip);
11961 $uip = str_replace('::', ':', $uip);
11968 * Splits an IPv6 address into the IPv6 and a possible IPv4 part
11970 * RFC 2373 allows you to note the last two parts of an IPv6 address as
11971 * an IPv4 compatible address
11973 * Example: 0:0:0:0:0:0:13.1.68.3
11974 * 0:0:0:0:0:FFFF:129.144.52.38
11978 * @param string $ip a valid IPv6-address (hex format)
11979 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
11981 public static function SplitV64($ip)
11983 $ip = SimplePie_Net_IPv6
::Uncompress($ip);
11984 if (strstr($ip, '.'))
11986 $pos = strrpos($ip, ':');
11988 $ipPart = explode('_', $ip);
11993 return array($ip, '');
11998 * Checks an IPv6 address
12000 * Checks if the given IP is IPv6-compatible
12004 * @param string $ip a valid IPv6-address
12005 * @return bool true if $ip is an IPv6 address
12007 public static function checkIPv6($ip)
12009 $ipPart = SimplePie_Net_IPv6
::SplitV64($ip);
12011 if (!empty($ipPart[0]))
12013 $ipv6 = explode(':', $ipPart[0]);
12014 for ($i = 0; $i < count($ipv6); $i++
)
12016 $dec = hexdec($ipv6[$i]);
12017 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12018 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12027 elseif ($count === 6 && !empty($ipPart[1]))
12029 $ipv4 = explode('.', $ipPart[1]);
12031 foreach ($ipv4 as $ipv4_part)
12033 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12059 * @package SimplePie
12061 class SimplePie_Parse_Date
12066 * @access protected
12072 * List of days, calendar day name => ordinal day number in the week
12074 * @access protected
12137 'keskiviikko' => 3,
12161 * List of months, calendar month name => calendar month number
12163 * @access protected
12166 var $month = array(
12177 // No long form of May
12306 * List of timezones, abbreviation => offset from UTC
12308 * @access protected
12311 var $timezone = array(
12514 * Cached PCRE for SimplePie_Parse_Date::$day
12516 * @access protected
12522 * Cached PCRE for SimplePie_Parse_Date::$month
12524 * @access protected
12530 * Array of user-added callback methods
12535 var $built_in = array();
12538 * Array of user-added callback methods
12543 var $user = array();
12546 * Create new SimplePie_Parse_Date object, and set self::day_pcre,
12547 * self::month_pcre, and self::built_in
12551 public function __construct()
12553 $this->day_pcre
= '(' . implode(array_keys($this->day
), '|') . ')';
12554 $this->month_pcre
= '(' . implode(array_keys($this->month
), '|') . ')';
12557 if (!isset($cache[get_class($this)]))
12559 $all_methods = get_class_methods($this);
12561 foreach ($all_methods as $method)
12563 if (strtolower(substr($method, 0, 5)) === 'date_')
12565 $cache[get_class($this)][] = $method;
12570 foreach ($cache[get_class($this)] as $method)
12572 $this->built_in
[] = $method;
12581 public static function get()
12586 $object = new SimplePie_Parse_Date
;
12596 * @param string $date Date to parse
12597 * @return int Timestamp corresponding to date string, or false on failure
12599 public function parse($date)
12601 foreach ($this->user
as $method)
12603 if (($returned = call_user_func($method, $date)) !== false)
12609 foreach ($this->built_in
as $method)
12611 if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
12621 * Add a callback method to parse a date
12625 * @param callback $callback
12627 public function add_callback($callback)
12629 if (is_callable($callback))
12631 $this->user
[] = $callback;
12635 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING
);
12640 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
12641 * well as allowing any of upper or lower case "T", horizontal tabs, or
12642 * spaces to be used as the time seperator (including more than one))
12644 * @access protected
12645 * @return int Timestamp
12647 public function date_w3cdtf($date)
12652 $year = '([0-9]{4})';
12653 $month = $day = $hour = $minute = $second = '([0-9]{2})';
12654 $decimal = '([0-9]*)';
12655 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
12656 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
12658 if (preg_match($pcre, $date, $match))
12661 Capturing subpatterns:
12668 7: Decimal fraction of a second
12672 11: Timezone minutes
12675 // Fill in empty matches
12676 for ($i = count($match); $i <= 3; $i++
)
12681 for ($i = count($match); $i <= 7; $i++
)
12686 // Numeric timezone
12687 if (isset($match[9]) && $match[9] !== '')
12689 $timezone = $match[10] * 3600;
12690 $timezone +
= $match[11] * 60;
12691 if ($match[9] === '-')
12693 $timezone = 0 - $timezone;
12701 // Convert the number of seconds to an integer, taking decimals into account
12702 $second = round($match[6] +
$match[7] / pow(10, strlen($match[7])));
12704 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
12713 * Remove RFC822 comments
12715 * @access protected
12716 * @param string $data Data to strip comments from
12717 * @return string Comment stripped string
12719 public function remove_rfc2822_comments($string)
12721 $string = (string) $string;
12723 $length = strlen($string);
12728 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
12730 $output .= substr($string, $position, $pos - $position);
12731 $position = $pos +
1;
12732 if ($string[$pos - 1] !== '\\')
12735 while ($depth && $position < $length)
12737 $position +
= strcspn($string, '()', $position);
12738 if ($string[$position - 1] === '\\')
12743 elseif (isset($string[$position]))
12745 switch ($string[$position])
12768 $output .= substr($string, $position);
12774 * Parse RFC2822's date format
12776 * @access protected
12777 * @return int Timestamp
12779 public function date_rfc2822($date)
12784 $wsp = '[\x09\x20]';
12785 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
12786 $optional_fws = $fws . '?';
12787 $day_name = $this->day_pcre
;
12788 $month = $this->month_pcre
;
12789 $day = '([0-9]{1,2})';
12790 $hour = $minute = $second = '([0-9]{2})';
12791 $year = '([0-9]{2,4})';
12792 $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
12793 $character_zone = '([A-Z]{1,5})';
12794 $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
12795 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
12797 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
12800 Capturing subpatterns:
12810 10: Timezone minutes
12811 11: Alphabetic timezone
12814 // Find the month number
12815 $month = $this->month
[strtolower($match[3])];
12817 // Numeric timezone
12818 if ($match[8] !== '')
12820 $timezone = $match[9] * 3600;
12821 $timezone +
= $match[10] * 60;
12822 if ($match[8] === '-')
12824 $timezone = 0 - $timezone;
12827 // Character timezone
12828 elseif (isset($this->timezone
[strtoupper($match[11])]))
12830 $timezone = $this->timezone
[strtoupper($match[11])];
12832 // Assume everything else to be -0000
12838 // Deal with 2/3 digit years
12839 if ($match[4] < 50)
12843 elseif ($match[4] < 1000)
12848 // Second is optional, if it is empty set it to zero
12849 if ($match[7] !== '')
12851 $second = $match[7];
12858 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
12867 * Parse RFC850's date format
12869 * @access protected
12870 * @return int Timestamp
12872 public function date_rfc850($date)
12877 $space = '[\x09\x20]+';
12878 $day_name = $this->day_pcre
;
12879 $month = $this->month_pcre
;
12880 $day = '([0-9]{1,2})';
12881 $year = $hour = $minute = $second = '([0-9]{2})';
12882 $zone = '([A-Z]{1,5})';
12883 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
12885 if (preg_match($pcre, $date, $match))
12888 Capturing subpatterns:
12900 $month = $this->month
[strtolower($match[3])];
12902 // Character timezone
12903 if (isset($this->timezone
[strtoupper($match[8])]))
12905 $timezone = $this->timezone
[strtoupper($match[8])];
12907 // Assume everything else to be -0000
12913 // Deal with 2 digit year
12914 if ($match[4] < 50)
12923 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
12932 * Parse C99's asctime()'s date format
12934 * @access protected
12935 * @return int Timestamp
12937 public function date_asctime($date)
12942 $space = '[\x09\x20]+';
12943 $wday_name = $this->day_pcre
;
12944 $mon_name = $this->month_pcre
;
12945 $day = '([0-9]{1,2})';
12946 $hour = $sec = $min = '([0-9]{2})';
12947 $year = '([0-9]{4})';
12948 $terminator = '\x0A?\x00?';
12949 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
12951 if (preg_match($pcre, $date, $match))
12954 Capturing subpatterns:
12964 $month = $this->month
[strtolower($match[2])];
12965 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
12974 * Parse dates using strtotime()
12976 * @access protected
12977 * @return int Timestamp
12979 public function date_strtotime($date)
12981 $strtotime = strtotime($date);
12982 if ($strtotime === -1 ||
$strtotime === false)
12994 * Content-type sniffing
12996 * @package SimplePie
12998 class SimplePie_Content_Type_Sniffer
13003 * @var SimplePie_File
13009 * Create an instance of the class with the input file
13012 * @param SimplePie_Content_Type_Sniffer $file Input file
13014 public function __construct($file)
13016 $this->file
= $file;
13020 * Get the Content-Type of the specified file
13023 * @return string Actual Content-Type
13025 public function get_type()
13027 if (isset($this->file
->headers
['content-type']))
13029 if (!isset($this->file
->headers
['content-encoding'])
13030 && ($this->file
->headers
['content-type'] === 'text/plain'
13031 ||
$this->file
->headers
['content-type'] === 'text/plain; charset=ISO-8859-1'
13032 ||
$this->file
->headers
['content-type'] === 'text/plain; charset=iso-8859-1'))
13034 return $this->text_or_binary();
13037 if (($pos = strpos($this->file
->headers
['content-type'], ';')) !== false)
13039 $official = substr($this->file
->headers
['content-type'], 0, $pos);
13043 $official = $this->file
->headers
['content-type'];
13045 $official = strtolower($official);
13047 if ($official === 'unknown/unknown'
13048 ||
$official === 'application/unknown')
13050 return $this->unknown();
13052 elseif (substr($official, -4) === '+xml'
13053 ||
$official === 'text/xml'
13054 ||
$official === 'application/xml')
13058 elseif (substr($official, 0, 6) === 'image/')
13060 if ($return = $this->image())
13069 elseif ($official === 'text/html')
13071 return $this->feed_or_html();
13080 return $this->unknown();
13085 * Sniff text or binary
13088 * @return string Actual Content-Type
13090 public function text_or_binary()
13092 if (substr($this->file
->body
, 0, 2) === "\xFE\xFF"
13093 ||
substr($this->file
->body
, 0, 2) === "\xFF\xFE"
13094 ||
substr($this->file
->body
, 0, 4) === "\x00\x00\xFE\xFF"
13095 ||
substr($this->file
->body
, 0, 3) === "\xEF\xBB\xBF")
13097 return 'text/plain';
13099 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file
->body
))
13101 return 'application/octect-stream';
13105 return 'text/plain';
13113 * @return string Actual Content-Type
13115 public function unknown()
13117 $ws = strspn($this->file
->body
, "\x09\x0A\x0B\x0C\x0D\x20");
13118 if (strtolower(substr($this->file
->body
, $ws, 14)) === '<!doctype html'
13119 ||
strtolower(substr($this->file
->body
, $ws, 5)) === '<html'
13120 ||
strtolower(substr($this->file
->body
, $ws, 7)) === '<script')
13122 return 'text/html';
13124 elseif (substr($this->file
->body
, 0, 5) === '%PDF-')
13126 return 'application/pdf';
13128 elseif (substr($this->file
->body
, 0, 11) === '%!PS-Adobe-')
13130 return 'application/postscript';
13132 elseif (substr($this->file
->body
, 0, 6) === 'GIF87a'
13133 ||
substr($this->file
->body
, 0, 6) === 'GIF89a')
13135 return 'image/gif';
13137 elseif (substr($this->file
->body
, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13139 return 'image/png';
13141 elseif (substr($this->file
->body
, 0, 3) === "\xFF\xD8\xFF")
13143 return 'image/jpeg';
13145 elseif (substr($this->file
->body
, 0, 2) === "\x42\x4D")
13147 return 'image/bmp';
13151 return $this->text_or_binary();
13159 * @return string Actual Content-Type
13161 public function image()
13163 if (substr($this->file
->body
, 0, 6) === 'GIF87a'
13164 ||
substr($this->file
->body
, 0, 6) === 'GIF89a')
13166 return 'image/gif';
13168 elseif (substr($this->file
->body
, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13170 return 'image/png';
13172 elseif (substr($this->file
->body
, 0, 3) === "\xFF\xD8\xFF")
13174 return 'image/jpeg';
13176 elseif (substr($this->file
->body
, 0, 2) === "\x42\x4D")
13178 return 'image/bmp';
13190 * @return string Actual Content-Type
13192 public function feed_or_html()
13194 $len = strlen($this->file
->body
);
13195 $pos = strspn($this->file
->body
, "\x09\x0A\x0D\x20");
13197 while ($pos < $len)
13199 switch ($this->file
->body
[$pos])
13205 $pos +
= strspn($this->file
->body
, "\x09\x0A\x0D\x20", $pos);
13213 return 'text/html';
13216 if (substr($this->file
->body
, $pos, 3) === '!--')
13219 if ($pos < $len && ($pos = strpos($this->file
->body
, '-->', $pos)) !== false)
13225 return 'text/html';
13228 elseif (substr($this->file
->body
, $pos, 1) === '!')
13230 if ($pos < $len && ($pos = strpos($this->file
->body
, '>', $pos)) !== false)
13236 return 'text/html';
13239 elseif (substr($this->file
->body
, $pos, 1) === '?')
13241 if ($pos < $len && ($pos = strpos($this->file
->body
, '?>', $pos)) !== false)
13247 return 'text/html';
13250 elseif (substr($this->file
->body
, $pos, 3) === 'rss'
13251 ||
substr($this->file
->body
, $pos, 7) === 'rdf:RDF')
13253 return 'application/rss+xml';
13255 elseif (substr($this->file
->body
, $pos, 4) === 'feed')
13257 return 'application/atom+xml';
13261 return 'text/html';
13265 return 'text/html';
13270 * Parses the XML Declaration
13272 * @package SimplePie
13274 class SimplePie_XML_Declaration_Parser
13282 var $version = '1.0';
13290 var $encoding = 'UTF-8';
13298 var $standalone = false;
13301 * Current state of the state machine
13306 var $state = 'before_version_name';
13317 * Input data length (to avoid calling strlen() everytime this is needed)
13322 var $data_length = 0;
13325 * Current position of the pointer
13333 * Create an instance of the class with the input data
13336 * @param string $data Input data
13338 public function __construct($data)
13340 $this->data
= $data;
13341 $this->data_length
= strlen($this->data
);
13345 * Parse the input data
13348 * @return bool true on success, false on failure
13350 public function parse()
13352 while ($this->state
&& $this->state
!== 'emit' && $this->has_data())
13354 $state = $this->state
;
13358 if ($this->state
=== 'emit')
13364 $this->version
= '';
13365 $this->encoding
= '';
13366 $this->standalone
= '';
13372 * Check whether there is data beyond the pointer
13375 * @return bool true if there is further data, false if not
13377 public function has_data()
13379 return (bool) ($this->position
< $this->data_length
);
13383 * Advance past any whitespace
13385 * @return int Number of whitespace characters passed
13387 public function skip_whitespace()
13389 $whitespace = strspn($this->data
, "\x09\x0A\x0D\x20", $this->position
);
13390 $this->position +
= $whitespace;
13391 return $whitespace;
13397 public function get_value()
13399 $quote = substr($this->data
, $this->position
, 1);
13400 if ($quote === '"' ||
$quote === "'")
13403 $len = strcspn($this->data
, $quote, $this->position
);
13404 if ($this->has_data())
13406 $value = substr($this->data
, $this->position
, $len);
13407 $this->position +
= $len +
1;
13414 public function before_version_name()
13416 if ($this->skip_whitespace())
13418 $this->state
= 'version_name';
13422 $this->state
= false;
13426 public function version_name()
13428 if (substr($this->data
, $this->position
, 7) === 'version')
13430 $this->position +
= 7;
13431 $this->skip_whitespace();
13432 $this->state
= 'version_equals';
13436 $this->state
= false;
13440 public function version_equals()
13442 if (substr($this->data
, $this->position
, 1) === '=')
13445 $this->skip_whitespace();
13446 $this->state
= 'version_value';
13450 $this->state
= false;
13454 public function version_value()
13456 if ($this->version
= $this->get_value())
13458 $this->skip_whitespace();
13459 if ($this->has_data())
13461 $this->state
= 'encoding_name';
13465 $this->state
= 'emit';
13470 $this->state
= false;
13474 public function encoding_name()
13476 if (substr($this->data
, $this->position
, 8) === 'encoding')
13478 $this->position +
= 8;
13479 $this->skip_whitespace();
13480 $this->state
= 'encoding_equals';
13484 $this->state
= 'standalone_name';
13488 public function encoding_equals()
13490 if (substr($this->data
, $this->position
, 1) === '=')
13493 $this->skip_whitespace();
13494 $this->state
= 'encoding_value';
13498 $this->state
= false;
13502 public function encoding_value()
13504 if ($this->encoding
= $this->get_value())
13506 $this->skip_whitespace();
13507 if ($this->has_data())
13509 $this->state
= 'standalone_name';
13513 $this->state
= 'emit';
13518 $this->state
= false;
13522 public function standalone_name()
13524 if (substr($this->data
, $this->position
, 10) === 'standalone')
13526 $this->position +
= 10;
13527 $this->skip_whitespace();
13528 $this->state
= 'standalone_equals';
13532 $this->state
= false;
13536 public function standalone_equals()
13538 if (substr($this->data
, $this->position
, 1) === '=')
13541 $this->skip_whitespace();
13542 $this->state
= 'standalone_value';
13546 $this->state
= false;
13550 public function standalone_value()
13552 if ($standalone = $this->get_value())
13554 switch ($standalone)
13557 $this->standalone
= true;
13561 $this->standalone
= false;
13565 $this->state
= false;
13569 $this->skip_whitespace();
13570 if ($this->has_data())
13572 $this->state
= false;
13576 $this->state
= 'emit';
13581 $this->state
= false;
13586 class SimplePie_Locator
13591 var $local = array();
13592 var $elsewhere = array();
13593 var $file_class = 'SimplePie_File';
13594 var $cached_entities = array();
13597 var $base_location = 0;
13598 var $checked_feeds = 0;
13599 var $max_checked_feeds = 10;
13600 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
13602 public function __construct(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
13604 $this->file
=& $file;
13605 $this->file_class
= $file_class;
13606 $this->useragent
= $useragent;
13607 $this->timeout
= $timeout;
13608 $this->max_checked_feeds
= $max_checked_feeds;
13609 $this->content_type_sniffer_class
= $content_type_sniffer_class;
13612 public function find($type = SIMPLEPIE_LOCATOR_ALL
, &$working)
13614 if ($this->is_feed($this->file
))
13616 return $this->file
;
13619 if ($this->file
->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
)
13621 $sniffer = new $this->content_type_sniffer_class($this->file
);
13622 if ($sniffer->get_type() !== 'text/html')
13628 if ($type & ~SIMPLEPIE_LOCATOR_NONE
)
13633 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY
&& $working = $this->autodiscovery())
13635 return $working[0];
13638 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY
) && $this->get_links())
13640 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
&& $working = $this->extension($this->local
))
13645 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY
&& $working = $this->body($this->local
))
13650 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
&& $working = $this->extension($this->elsewhere
))
13655 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY
&& $working = $this->body($this->elsewhere
))
13663 public function is_feed(&$file)
13665 if ($file->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
)
13667 $sniffer = new $this->content_type_sniffer_class($file);
13668 $sniffed = $sniffer->get_type();
13669 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
13678 elseif ($file->method
& SIMPLEPIE_FILE_SOURCE_LOCAL
)
13688 public function get_base()
13690 $this->http_base
= $this->file
->url
;
13691 $this->base
= $this->http_base
;
13692 $elements = SimplePie_Misc
::get_element('base', $this->file
->body
);
13693 foreach ($elements as $element)
13695 if ($element['attribs']['href']['data'] !== '')
13697 $this->base
= SimplePie_Misc
::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base
);
13698 $this->base_location
= $element['offset'];
13704 public function autodiscovery()
13706 $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
));
13709 foreach ($links as $link)
13711 if ($this->checked_feeds
=== $this->max_checked_feeds
)
13715 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
13717 $rel = array_unique(SimplePie_Misc
::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
13719 if ($this->base_location
< $link['offset'])
13721 $href = SimplePie_Misc
::absolutize_url(trim($link['attribs']['href']['data']), $this->base
);
13725 $href = SimplePie_Misc
::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base
);
13728 if (!in_array($href, $done) && in_array('feed', $rel) ||
(in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc
::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
13730 $this->checked_feeds++
;
13731 $feed = new $this->file_class($href, $this->timeout
, 5, null, $this->useragent
);
13732 if ($feed->success
&& ($feed->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
=== 0 ||
($feed->status_code
=== 200 ||
$feed->status_code
> 206 && $feed->status_code
< 300)) && $this->is_feed($feed))
13734 $feeds[$href] = $feed;
13741 if (!empty($feeds))
13743 return array_values($feeds);
13750 public function get_links()
13752 $links = SimplePie_Misc
::get_element('a', $this->file
->body
);
13753 foreach ($links as $link)
13755 if (isset($link['attribs']['href']['data']))
13757 $href = trim($link['attribs']['href']['data']);
13758 $parsed = SimplePie_Misc
::parse_url($href);
13759 if ($parsed['scheme'] === '' ||
preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
13761 if ($this->base_location
< $link['offset'])
13763 $href = SimplePie_Misc
::absolutize_url(trim($link['attribs']['href']['data']), $this->base
);
13767 $href = SimplePie_Misc
::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base
);
13770 $current = SimplePie_Misc
::parse_url($this->file
->url
);
13772 if ($parsed['authority'] === '' ||
$parsed['authority'] === $current['authority'])
13774 $this->local
[] = $href;
13778 $this->elsewhere
[] = $href;
13783 $this->local
= array_unique($this->local
);
13784 $this->elsewhere
= array_unique($this->elsewhere
);
13785 if (!empty($this->local
) ||
!empty($this->elsewhere
))
13792 public function extension(&$array)
13794 foreach ($array as $key => $value)
13796 if ($this->checked_feeds
=== $this->max_checked_feeds
)
13800 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
13802 $this->checked_feeds++
;
13803 $feed = new $this->file_class($value, $this->timeout
, 5, null, $this->useragent
);
13804 if ($feed->success
&& ($feed->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
=== 0 ||
($feed->status_code
=== 200 ||
$feed->status_code
> 206 && $feed->status_code
< 300)) && $this->is_feed($feed))
13810 unset($array[$key]);
13817 public function body(&$array)
13819 foreach ($array as $key => $value)
13821 if ($this->checked_feeds
=== $this->max_checked_feeds
)
13825 if (preg_match('/(rss|rdf|atom|xml)/i', $value))
13827 $this->checked_feeds++
;
13828 $feed = new $this->file_class($value, $this->timeout
, 5, null, $this->useragent
);
13829 if ($feed->success
&& ($feed->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
=== 0 ||
($feed->status_code
=== 200 ||
$feed->status_code
> 206 && $feed->status_code
< 300)) && $this->is_feed($feed))
13835 unset($array[$key]);
13843 class SimplePie_Parser
13848 var $current_column;
13850 var $separator = ' ';
13851 var $namespace = array('');
13852 var $element = array('');
13853 var $xml_base = array('');
13854 var $xml_base_explicit = array(false);
13855 var $xml_lang = array('');
13856 var $data = array();
13857 var $datas = array(array());
13858 var $current_xhtml_construct = -1;
13861 public function parse(&$data, $encoding)
13863 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
13864 if (strtoupper($encoding) === 'US-ASCII')
13866 $this->encoding
= 'UTF-8';
13870 $this->encoding
= $encoding;
13874 // UTF-32 Big Endian BOM
13875 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
13877 $data = substr($data, 4);
13879 // UTF-32 Little Endian BOM
13880 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
13882 $data = substr($data, 4);
13884 // UTF-16 Big Endian BOM
13885 elseif (substr($data, 0, 2) === "\xFE\xFF")
13887 $data = substr($data, 2);
13889 // UTF-16 Little Endian BOM
13890 elseif (substr($data, 0, 2) === "\xFF\xFE")
13892 $data = substr($data, 2);
13895 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
13897 $data = substr($data, 3);
13900 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
13902 $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
13903 if ($declaration->parse())
13905 $data = substr($data, $pos +
2);
13906 $data = '<?xml version="' . $declaration->version
. '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone
) ?
'yes' : 'no') . '"?>' . $data;
13910 $this->error_string
= 'SimplePie bug! Please report this!';
13917 static $xml_is_sane = null;
13918 if ($xml_is_sane === null)
13920 $parser_check = xml_parser_create();
13921 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
13922 xml_parser_free($parser_check);
13923 $xml_is_sane = isset($values[0]['value']);
13926 // Create the parser
13929 $xml = xml_parser_create_ns($this->encoding
, $this->separator
);
13930 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE
, 1);
13931 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING
, 0);
13932 xml_set_object($xml, $this);
13933 xml_set_character_data_handler($xml, 'cdata');
13934 xml_set_element_handler($xml, 'tag_open', 'tag_close');
13937 if (!xml_parse($xml, $data, true))
13939 $this->error_code
= xml_get_error_code($xml);
13940 $this->error_string
= xml_error_string($this->error_code
);
13943 $this->current_line
= xml_get_current_line_number($xml);
13944 $this->current_column
= xml_get_current_column_number($xml);
13945 $this->current_byte
= xml_get_current_byte_index($xml);
13946 xml_parser_free($xml);
13951 libxml_clear_errors();
13952 $xml = new XMLReader();
13954 while (@$xml->read())
13956 switch ($xml->nodeType
)
13959 case constant('XMLReader::END_ELEMENT'):
13960 if ($xml->namespaceURI
!== '')
13962 $tagName = $xml->namespaceURI
. $this->separator
. $xml->localName
;
13966 $tagName = $xml->localName
;
13968 $this->tag_close(null, $tagName);
13970 case constant('XMLReader::ELEMENT'):
13971 $empty = $xml->isEmptyElement
;
13972 if ($xml->namespaceURI
!== '')
13974 $tagName = $xml->namespaceURI
. $this->separator
. $xml->localName
;
13978 $tagName = $xml->localName
;
13980 $attributes = array();
13981 while ($xml->moveToNextAttribute())
13983 if ($xml->namespaceURI
!== '')
13985 $attrName = $xml->namespaceURI
. $this->separator
. $xml->localName
;
13989 $attrName = $xml->localName
;
13991 $attributes[$attrName] = $xml->value
;
13993 $this->tag_open(null, $tagName, $attributes);
13996 $this->tag_close(null, $tagName);
13999 case constant('XMLReader::TEXT'):
14001 case constant('XMLReader::CDATA'):
14002 $this->cdata(null, $xml->value
);
14006 if ($error = libxml_get_last_error())
14008 $this->error_code
= $error->code
;
14009 $this->error_string
= $error->message
;
14010 $this->current_line
= $error->line
;
14011 $this->current_column
= $error->column
;
14021 public function get_error_code()
14023 return $this->error_code
;
14026 public function get_error_string()
14028 return $this->error_string
;
14031 public function get_current_line()
14033 return $this->current_line
;
14036 public function get_current_column()
14038 return $this->current_column
;
14041 public function get_current_byte()
14043 return $this->current_byte
;
14046 public function get_data()
14048 return $this->data
;
14051 public function tag_open($parser, $tag, $attributes)
14053 list($this->namespace[], $this->element
[]) = $this->split_ns($tag);
14055 $attribs = array();
14056 foreach ($attributes as $name => $value)
14058 list($attrib_namespace, $attribute) = $this->split_ns($name);
14059 $attribs[$attrib_namespace][$attribute] = $value;
14062 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML
]['base']))
14064 $this->xml_base
[] = SimplePie_Misc
::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML
]['base'], end($this->xml_base
));
14065 $this->xml_base_explicit
[] = true;
14069 $this->xml_base
[] = end($this->xml_base
);
14070 $this->xml_base_explicit
[] = end($this->xml_base_explicit
);
14073 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML
]['lang']))
14075 $this->xml_lang
[] = $attribs[SIMPLEPIE_NAMESPACE_XML
]['lang'];
14079 $this->xml_lang
[] = end($this->xml_lang
);
14082 if ($this->current_xhtml_construct
>= 0)
14084 $this->current_xhtml_construct++
;
14085 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML
)
14087 $this->data
['data'] .= '<' . end($this->element
);
14088 if (isset($attribs['']))
14090 foreach ($attribs[''] as $name => $value)
14092 $this->data
['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT
, $this->encoding
) . '"';
14095 $this->data
['data'] .= '>';
14100 $this->datas
[] =& $this->data
;
14101 $this->data
=& $this->data
['child'][end($this->namespace)][end($this->element
)][];
14102 $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
));
14103 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')
14104 ||
(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'))
14106 $this->current_xhtml_construct
= 0;
14111 public function cdata($parser, $cdata)
14113 if ($this->current_xhtml_construct
>= 0)
14115 $this->data
['data'] .= htmlspecialchars($cdata, ENT_QUOTES
, $this->encoding
);
14119 $this->data
['data'] .= $cdata;
14123 public function tag_close($parser, $tag)
14125 if ($this->current_xhtml_construct
>= 0)
14127 $this->current_xhtml_construct
--;
14128 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')))
14130 $this->data
['data'] .= '</' . end($this->element
) . '>';
14133 if ($this->current_xhtml_construct
=== -1)
14135 $this->data
=& $this->datas
[count($this->datas
) - 1];
14136 array_pop($this->datas
);
14139 array_pop($this->element
);
14140 array_pop($this->namespace);
14141 array_pop($this->xml_base
);
14142 array_pop($this->xml_base_explicit
);
14143 array_pop($this->xml_lang
);
14146 public function split_ns($string)
14148 static $cache = array();
14149 if (!isset($cache[$string]))
14151 if ($pos = strpos($string, $this->separator
))
14153 static $separator_length;
14154 if (!$separator_length)
14156 $separator_length = strlen($this->separator
);
14158 $namespace = substr($string, 0, $pos);
14159 $local_name = substr($string, $pos +
$separator_length);
14160 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES
)
14162 $namespace = SIMPLEPIE_NAMESPACE_ITUNES
;
14165 // Normalize the Media RSS namespaces
14166 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
14167 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
14168 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
14169 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
14170 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5
)
14172 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS
;
14174 $cache[$string] = array($namespace, $local_name);
14178 $cache[$string] = array('', $string);
14181 return $cache[$string];
14186 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
14188 class SimplePie_Sanitize
14194 var $remove_div = true;
14195 var $image_handler = '';
14196 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14197 var $encode_instead_of_strip = false;
14198 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14199 var $strip_comments = false;
14200 var $output_encoding = 'UTF-8';
14201 var $enable_cache = true;
14202 var $cache_location = './cache';
14203 var $cache_name_function = 'md5';
14204 var $cache_class = 'SimplePie_Cache';
14205 var $file_class = 'SimplePie_File';
14207 var $useragent = '';
14208 var $force_fsockopen = false;
14210 var $replace_url_attributes = array(
14213 'blockquote' => 'cite',
14215 'form' => 'action',
14216 'img' => array('longdesc', 'src'),
14222 public function remove_div($enable = true)
14224 $this->remove_div
= (bool) $enable;
14227 public function set_image_handler($page = false)
14231 $this->image_handler
= (string) $page;
14235 $this->image_handler
= false;
14239 public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
14241 if (isset($enable_cache))
14243 $this->enable_cache
= (bool) $enable_cache;
14246 if ($cache_location)
14248 $this->cache_location
= (string) $cache_location;
14251 if ($cache_name_function)
14253 $this->cache_name_function
= (string) $cache_name_function;
14258 $this->cache_class
= (string) $cache_class;
14262 public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
14266 $this->file_class
= (string) $file_class;
14271 $this->timeout
= (string) $timeout;
14276 $this->useragent
= (string) $useragent;
14279 if ($force_fsockopen)
14281 $this->force_fsockopen
= (string) $force_fsockopen;
14285 public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
14289 if (is_array($tags))
14291 $this->strip_htmltags
= $tags;
14295 $this->strip_htmltags
= explode(',', $tags);
14300 $this->strip_htmltags
= false;
14304 public function encode_instead_of_strip($encode = false)
14306 $this->encode_instead_of_strip
= (bool) $encode;
14309 public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
14313 if (is_array($attribs))
14315 $this->strip_attributes
= $attribs;
14319 $this->strip_attributes
= explode(',', $attribs);
14324 $this->strip_attributes
= false;
14328 public function strip_comments($strip = false)
14330 $this->strip_comments
= (bool) $strip;
14333 public function set_output_encoding($encoding = 'UTF-8')
14335 $this->output_encoding
= (string) $encoding;
14339 * Set element/attribute key/value pairs of HTML attributes
14340 * containing URLs that need to be resolved relative to the feed
14344 * @param array $element_attribute Element/attribute key/value pairs
14346 public 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'))
14348 $this->replace_url_attributes
= (array) $element_attribute;
14351 public function sanitize($data, $type, $base = '')
14353 $data = trim($data);
14354 if ($data !== '' ||
$type & SIMPLEPIE_CONSTRUCT_IRI
)
14356 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML
)
14358 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. '>)/', $data))
14360 $type |
= SIMPLEPIE_CONSTRUCT_HTML
;
14364 $type |
= SIMPLEPIE_CONSTRUCT_TEXT
;
14368 if ($type & SIMPLEPIE_CONSTRUCT_BASE64
)
14370 $data = base64_decode($data);
14373 if ($type & SIMPLEPIE_CONSTRUCT_XHTML
)
14375 if ($this->remove_div
)
14377 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE
. '>/', '', $data);
14378 $data = preg_replace('/<\/div>$/', '', $data);
14382 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE
. '>/', '<div>', $data);
14386 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML
))
14389 if ($this->strip_comments
)
14391 $data = SimplePie_Misc
::strip_comments($data);
14394 // Strip out HTML tags and attributes that might cause various security problems.
14395 // Based on recommendations by Mark Pilgrim at:
14396 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
14397 if ($this->strip_htmltags
)
14399 foreach ($this->strip_htmltags
as $tag)
14401 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. '>|(\/)?>)/siU';
14402 while (preg_match($pcre, $data))
14404 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
14409 if ($this->strip_attributes
)
14411 foreach ($this->strip_attributes
as $attrib)
14413 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE
. '>/', '\1\2\3>', $data);
14417 // Replace relative URLs
14418 $this->base
= $base;
14419 foreach ($this->replace_url_attributes
as $element => $attributes)
14421 $data = $this->replace_urls($data, $element, $attributes);
14424 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
14425 if (isset($this->image_handler
) && ((string) $this->image_handler
) !== '' && $this->enable_cache
)
14427 $images = SimplePie_Misc
::get_element('img', $data);
14428 foreach ($images as $img)
14430 if (isset($img['attribs']['src']['data']))
14432 $image_url = call_user_func($this->cache_name_function
, $img['attribs']['src']['data']);
14433 $cache = call_user_func(array($this->cache_class
, 'create'), $this->cache_location
, $image_url, 'spi');
14435 if ($cache->load())
14437 $img['attribs']['src']['data'] = $this->image_handler
. $image_url;
14438 $data = str_replace($img['full'], SimplePie_Misc
::element_implode($img), $data);
14442 $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout
, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent
, $this->force_fsockopen
);
14443 $headers = $file->headers
;
14445 if ($file->success
&& ($file->method
& SIMPLEPIE_FILE_SOURCE_REMOTE
=== 0 ||
($file->status_code
=== 200 ||
$file->status_code
> 206 && $file->status_code
< 300)))
14447 if ($cache->save(array('headers' => $file->headers
, 'body' => $file->body
)))
14449 $img['attribs']['src']['data'] = $this->image_handler
. $image_url;
14450 $data = str_replace($img['full'], SimplePie_Misc
::element_implode($img), $data);
14454 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING
);
14462 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
14463 $data = trim($data);
14466 if ($type & SIMPLEPIE_CONSTRUCT_IRI
)
14468 $data = SimplePie_Misc
::absolutize_url($data, $base);
14471 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI
))
14473 $data = htmlspecialchars($data, ENT_COMPAT
, 'UTF-8');
14476 if ($this->output_encoding
!== 'UTF-8')
14478 $data = SimplePie_Misc
::change_encoding($data, 'UTF-8', $this->output_encoding
);
14484 public function replace_urls($data, $tag, $attributes)
14486 if (!is_array($this->strip_htmltags
) ||
!in_array($tag, $this->strip_htmltags
))
14488 $elements = SimplePie_Misc
::get_element($tag, $data);
14489 foreach ($elements as $element)
14491 if (is_array($attributes))
14493 foreach ($attributes as $attribute)
14495 if (isset($element['attribs'][$attribute]['data']))
14497 $element['attribs'][$attribute]['data'] = SimplePie_Misc
::absolutize_url($element['attribs'][$attribute]['data'], $this->base
);
14498 $new_element = SimplePie_Misc
::element_implode($element);
14499 $data = str_replace($element['full'], $new_element, $data);
14500 $element['full'] = $new_element;
14504 elseif (isset($element['attribs'][$attributes]['data']))
14506 $element['attribs'][$attributes]['data'] = SimplePie_Misc
::absolutize_url($element['attribs'][$attributes]['data'], $this->base
);
14507 $data = str_replace($element['full'], SimplePie_Misc
::element_implode($element), $data);
14514 public function do_strip_htmltags($match)
14516 if ($this->encode_instead_of_strip
)
14518 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
14520 $match[1] = htmlspecialchars($match[1], ENT_COMPAT
, 'UTF-8');
14521 $match[2] = htmlspecialchars($match[2], ENT_COMPAT
, 'UTF-8');
14522 return "<$match[1]$match[2]>$match[3]</$match[1]>";
14526 return htmlspecialchars($match[0], ENT_COMPAT
, 'UTF-8');
14529 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))