2 if ( ! class_exists( 'SimplePie' ) ) :
4 // Load classes we will need.
5 require ABSPATH . WPINC . '/SimplePie/Misc.php';
6 require ABSPATH . WPINC . '/SimplePie/Cache.php';
7 require ABSPATH . WPINC . '/SimplePie/File.php';
8 require ABSPATH . WPINC . '/SimplePie/Sanitize.php';
9 require ABSPATH . WPINC . '/SimplePie/Registry.php';
10 require ABSPATH . WPINC . '/SimplePie/IRI.php';
11 require ABSPATH . WPINC . '/SimplePie/Locator.php';
12 require ABSPATH . WPINC . '/SimplePie/Content/Type/Sniffer.php';
13 require ABSPATH . WPINC . '/SimplePie/XML/Declaration/Parser.php';
14 require ABSPATH . WPINC . '/SimplePie/Parser.php';
15 require ABSPATH . WPINC . '/SimplePie/Item.php';
16 require ABSPATH . WPINC . '/SimplePie/Parse/Date.php';
17 require ABSPATH . WPINC . '/SimplePie/Author.php';
20 * WordPress autoloader for SimplePie.
24 function wp_simplepie_autoload( $class ) {
25 if ( 0 !== strpos( $class, 'SimplePie_' ) )
28 $file = ABSPATH . WPINC . '/' . str_replace( '_', '/', $class ) . '.php';
32 if ( function_exists( 'spl_autoload_register' ) ) {
34 * We autoload classes we may not need.
36 * If SPL is disabled, we load all of SimplePie manually.
38 * Core.php is not loaded manually, because SimplePie_Core (a deprecated class)
39 * was never included in WordPress core.
41 spl_autoload_register( 'wp_simplepie_autoload' );
43 require ABSPATH . WPINC . '/SimplePie/Cache/Base.php';
44 require ABSPATH . WPINC . '/SimplePie/Cache/DB.php';
45 require ABSPATH . WPINC . '/SimplePie/Cache/File.php';
46 require ABSPATH . WPINC . '/SimplePie/Cache/Memcache.php';
47 require ABSPATH . WPINC . '/SimplePie/Cache/MySQL.php';
48 require ABSPATH . WPINC . '/SimplePie/Caption.php';
49 require ABSPATH . WPINC . '/SimplePie/Category.php';
50 require ABSPATH . WPINC . '/SimplePie/Copyright.php';
51 require ABSPATH . WPINC . '/SimplePie/Credit.php';
52 require ABSPATH . WPINC . '/SimplePie/Decode/HTML/Entities.php';
53 require ABSPATH . WPINC . '/SimplePie/Enclosure.php';
54 require ABSPATH . WPINC . '/SimplePie/gzdecode.php';
55 require ABSPATH . WPINC . '/SimplePie/HTTP/Parser.php';
56 require ABSPATH . WPINC . '/SimplePie/Net/IPv6.php';
57 require ABSPATH . WPINC . '/SimplePie/Rating.php';
58 require ABSPATH . WPINC . '/SimplePie/Restriction.php';
59 require ABSPATH . WPINC . '/SimplePie/Source.php';
65 * A PHP-Based RSS and Atom Feed Framework.
66 * Takes the hard work out of managing a complete RSS/Atom solution.
68 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
69 * All rights reserved.
71 * Redistribution and use in source and binary forms, with or without modification, are
72 * permitted provided that the following conditions are met:
74 * * Redistributions of source code must retain the above copyright notice, this list of
75 * conditions and the following disclaimer.
77 * * Redistributions in binary form must reproduce the above copyright notice, this list
78 * of conditions and the following disclaimer in the documentation and/or other materials
79 * provided with the distribution.
81 * * Neither the name of the SimplePie Team nor the names of its contributors may be used
82 * to endorse or promote products derived from this software without specific prior
85 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
86 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
87 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
88 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
89 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
90 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
91 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
92 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
93 * POSSIBILITY OF SUCH DAMAGE.
97 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
99 * @author Geoffrey Sneddon
101 * @link http://simplepie.org/ SimplePie
102 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
108 define('SIMPLEPIE_NAME', 'SimplePie');
113 define('SIMPLEPIE_VERSION', '1.3.1');
117 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
119 define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build()));
122 * SimplePie Website URL
124 define('SIMPLEPIE_URL', 'http://simplepie.org');
127 * SimplePie Useragent
128 * @see SimplePie::set_useragent()
130 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
135 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
139 * @see SimplePie::set_autodiscovery_level()
141 define('SIMPLEPIE_LOCATOR_NONE', 0);
144 * Feed Link Element Autodiscovery
145 * @see SimplePie::set_autodiscovery_level()
147 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
150 * Local Feed Extension Autodiscovery
151 * @see SimplePie::set_autodiscovery_level()
153 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
156 * Local Feed Body Autodiscovery
157 * @see SimplePie::set_autodiscovery_level()
159 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
162 * Remote Feed Extension Autodiscovery
163 * @see SimplePie::set_autodiscovery_level()
165 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
168 * Remote Feed Body Autodiscovery
169 * @see SimplePie::set_autodiscovery_level()
171 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
174 * All Feed Autodiscovery
175 * @see SimplePie::set_autodiscovery_level()
177 define('SIMPLEPIE_LOCATOR_ALL', 31);
182 define('SIMPLEPIE_TYPE_NONE', 0);
187 define('SIMPLEPIE_TYPE_RSS_090', 1);
190 * RSS 0.91 (Netscape)
192 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
195 * RSS 0.91 (Userland)
197 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
200 * RSS 0.91 (both Netscape and Userland)
202 define('SIMPLEPIE_TYPE_RSS_091', 6);
207 define('SIMPLEPIE_TYPE_RSS_092', 8);
212 define('SIMPLEPIE_TYPE_RSS_093', 16);
217 define('SIMPLEPIE_TYPE_RSS_094', 32);
222 define('SIMPLEPIE_TYPE_RSS_10', 64);
227 define('SIMPLEPIE_TYPE_RSS_20', 128);
232 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
235 * Non-RDF-based RSS (truly intended as syndication format)
237 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
242 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
247 define('SIMPLEPIE_TYPE_ATOM_03', 256);
252 define('SIMPLEPIE_TYPE_ATOM_10', 512);
257 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
262 define('SIMPLEPIE_TYPE_ALL', 1023);
267 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
272 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
277 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
282 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
285 * base64-encoded construct
287 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
292 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
295 * A construct that might be HTML
297 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
302 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
307 define('SIMPLEPIE_SAME_CASE', 1);
310 * Change to lowercase
312 define('SIMPLEPIE_LOWERCASE', 2);
315 * Change to uppercase
317 define('SIMPLEPIE_UPPERCASE', 4);
320 * PCRE for HTML attributes
322 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]*');
325 * PCRE for XML attributes
327 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
332 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
337 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
342 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
347 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
352 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
357 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
360 * RSS 1.0 Content Module Namespace
362 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
366 * (Stupid, I know, but I'm certain it will confuse people less with support.)
368 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
373 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
378 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
381 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
383 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
388 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
391 * Media RSS Namespace
393 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
396 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
398 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
401 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
403 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
406 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
408 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
411 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
413 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
416 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
418 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
421 * iTunes RSS Namespace
423 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
428 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
431 * IANA Link Relations Registry
433 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
438 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
443 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
448 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
451 * fsockopen() file source
453 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
458 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
461 * file_get_contents() file source
463 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
476 * @var array Raw data
479 public $data = array();
482 * @var mixed Error string
488 * @var object Instance of SimplePie_Sanitize (or other class)
489 * @see SimplePie::set_sanitize_class()
495 * @var string SimplePie Useragent
496 * @see SimplePie::set_useragent()
499 public $useragent = SIMPLEPIE_USERAGENT;
502 * @var string Feed URL
503 * @see SimplePie::set_feed_url()
509 * @var object Instance of SimplePie_File to use as a feed
510 * @see SimplePie::set_file()
516 * @var string Raw feed data
517 * @see SimplePie::set_raw_data()
523 * @var int Timeout for fetching remote files
524 * @see SimplePie::set_timeout()
527 public $timeout = 10;
530 * @var bool Forces fsockopen() to be used for remote files instead
531 * of cURL, even if a new enough version is installed
532 * @see SimplePie::force_fsockopen()
535 public $force_fsockopen = false;
538 * @var bool Force the given data/URL to be treated as a feed no matter what
540 * @see SimplePie::force_feed()
543 public $force_feed = false;
546 * @var bool Enable/Disable Caching
547 * @see SimplePie::enable_cache()
550 public $cache = true;
553 * @var int Cache duration (in seconds)
554 * @see SimplePie::set_cache_duration()
557 public $cache_duration = 3600;
560 * @var int Auto-discovery cache duration (in seconds)
561 * @see SimplePie::set_autodiscovery_cache_duration()
564 public $autodiscovery_cache_duration = 604800; // 7 Days.
567 * @var string Cache location (relative to executing script)
568 * @see SimplePie::set_cache_location()
571 public $cache_location = './cache';
574 * @var string Function that creates the cache filename
575 * @see SimplePie::set_cache_name_function()
578 public $cache_name_function = 'md5';
581 * @var bool Reorder feed by date descending
582 * @see SimplePie::enable_order_by_date()
585 public $order_by_date = true;
588 * @var mixed Force input encoding to be set to the follow value
589 * (false, or anything type-cast to false, disables this feature)
590 * @see SimplePie::set_input_encoding()
593 public $input_encoding = false;
596 * @var int Feed Autodiscovery Level
597 * @see SimplePie::set_autodiscovery_level()
600 public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
603 * Class registry object
605 * @var SimplePie_Registry
610 * @var int Maximum number of feeds to check with autodiscovery
611 * @see SimplePie::set_max_checked_feeds()
614 public $max_checked_feeds = 10;
617 * @var array All the feeds found during the autodiscovery process
618 * @see SimplePie::get_all_discovered_feeds()
621 public $all_discovered_feeds = array();
624 * @var string Web-accessible path to the handler_image.php file.
625 * @see SimplePie::set_image_handler()
628 public $image_handler = '';
631 * @var array Stores the URLs when multiple feeds are being initialized.
632 * @see SimplePie::set_feed_url()
635 public $multifeed_url = array();
638 * @var array Stores SimplePie objects when multiple feeds initialized.
641 public $multifeed_objects = array();
644 * @var array Stores the get_object_vars() array for use with multifeeds.
645 * @see SimplePie::set_feed_url()
648 public $config_settings = null;
651 * @var integer Stores the number of items to return per-feed with multifeeds.
652 * @see SimplePie::set_item_limit()
655 public $item_limit = 0;
658 * @var array Stores the default attributes to be stripped by strip_attributes().
659 * @see SimplePie::strip_attributes()
662 public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
665 * @var array Stores the default tags to be stripped by strip_htmltags().
666 * @see SimplePie::strip_htmltags()
669 public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
672 * The SimplePie class contains feed level data and options
674 * To use SimplePie, create the SimplePie object with no parameters. You can
675 * then set configuration options using the provided methods. After setting
676 * them, you must initialise the feed using $feed->init(). At that point the
677 * object's methods and properties will be available to you.
679 * Previously, it was possible to pass in the feed URL along with cache
680 * options directly into the constructor. This has been removed as of 1.3 as
681 * it caused a lot of confusion.
683 * @since 1.0 Preview Release
685 public function __construct()
687 if (version_compare(PHP_VERSION, '5.2', '<'))
689 trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
693 // Other objects, instances created here so we can set options on them
694 $this->sanitize = new SimplePie_Sanitize();
695 $this->registry = new SimplePie_Registry();
697 if (func_num_args() > 0)
699 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
700 trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.', $level);
702 $args = func_get_args();
703 switch (count($args)) {
705 $this->set_cache_duration($args[2]);
707 $this->set_cache_location($args[1]);
709 $this->set_feed_url($args[0]);
716 * Used for converting object to a string
718 public function __toString()
720 return md5(serialize($this->data));
724 * Remove items that link back to this before destroying this object
726 public function __destruct()
728 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
730 if (!empty($this->data['items']))
732 foreach ($this->data['items'] as $item)
736 unset($item, $this->data['items']);
738 if (!empty($this->data['ordered_items']))
740 foreach ($this->data['ordered_items'] as $item)
744 unset($item, $this->data['ordered_items']);
750 * Force the given data/URL to be treated as a feed
752 * This tells SimplePie to ignore the content-type provided by the server.
753 * Be careful when using this option, as it will also disable autodiscovery.
756 * @param bool $enable Force the given data/URL to be treated as a feed
758 public function force_feed($enable = false)
760 $this->force_feed = (bool) $enable;
764 * Set the URL of the feed you want to parse
766 * This allows you to enter the URL of the feed you want to parse, or the
767 * website you want to try to use auto-discovery on. This takes priority
768 * over any set raw data.
770 * You can set multiple feeds to mash together by passing an array instead
771 * of a string for the $url. Remember that with each additional feed comes
772 * additional processing and resources.
774 * @since 1.0 Preview Release
775 * @see set_raw_data()
776 * @param string|array $url This is the URL (or array of URLs) that you want to parse.
778 public function set_feed_url($url)
780 $this->multifeed_url = array();
783 foreach ($url as $value)
785 $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
790 $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
795 * Set an instance of {@see SimplePie_File} to use as a feed
797 * @param SimplePie_File &$file
798 * @return bool True on success, false on failure
800 public function set_file(&$file)
802 if ($file instanceof SimplePie_File)
804 $this->feed_url = $file->url;
805 $this->file =& $file;
812 * Set the raw XML data to parse
814 * Allows you to use a string of RSS/Atom data instead of a remote feed.
816 * If you have a feed available as a string in PHP, you can tell SimplePie
817 * to parse that data string instead of a remote feed. Any set feed URL
821 * @param string $data RSS or Atom data as a string.
822 * @see set_feed_url()
824 public function set_raw_data($data)
826 $this->raw_data = $data;
830 * Set the the default timeout for fetching remote feeds
832 * This allows you to change the maximum time the feed's server to respond
833 * and send the feed back.
836 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
838 public function set_timeout($timeout = 10)
840 $this->timeout = (int) $timeout;
844 * Force SimplePie to use fsockopen() instead of cURL
847 * @param bool $enable Force fsockopen() to be used
849 public function force_fsockopen($enable = false)
851 $this->force_fsockopen = (bool) $enable;
855 * Enable/disable caching in SimplePie.
857 * This option allows you to disable caching all-together in SimplePie.
858 * However, disabling the cache can lead to longer load times.
860 * @since 1.0 Preview Release
861 * @param bool $enable Enable caching
863 public function enable_cache($enable = true)
865 $this->cache = (bool) $enable;
869 * Set the length of time (in seconds) that the contents of a feed will be
872 * @param int $seconds The feed content cache duration
874 public function set_cache_duration($seconds = 3600)
876 $this->cache_duration = (int) $seconds;
880 * Set the length of time (in seconds) that the autodiscovered feed URL will
883 * @param int $seconds The autodiscovered feed URL cache duration.
885 public function set_autodiscovery_cache_duration($seconds = 604800)
887 $this->autodiscovery_cache_duration = (int) $seconds;
891 * Set the file system location where the cached files should be stored
893 * @param string $location The file system location.
895 public function set_cache_location($location = './cache')
897 $this->cache_location = (string) $location;
901 * Set whether feed items should be sorted into reverse chronological order
903 * @param bool $enable Sort as reverse chronological order.
905 public function enable_order_by_date($enable = true)
907 $this->order_by_date = (bool) $enable;
911 * Set the character encoding used to parse the feed
913 * This overrides the encoding reported by the feed, however it will fall
914 * back to the normal encoding detection if the override fails
916 * @param string $encoding Character encoding
918 public function set_input_encoding($encoding = false)
922 $this->input_encoding = (string) $encoding;
926 $this->input_encoding = false;
931 * Set how much feed autodiscovery to do
933 * @see SIMPLEPIE_LOCATOR_NONE
934 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
935 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
936 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
937 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
938 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
939 * @see SIMPLEPIE_LOCATOR_ALL
940 * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
942 public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
944 $this->autodiscovery = (int) $level;
948 * Get the class registry
950 * Use this to override SimplePie's default classes
951 * @see SimplePie_Registry
952 * @return SimplePie_Registry
954 public function &get_registry()
956 return $this->registry;
960 * Useful when you are overloading or extending SimplePie's default classes.
962 * @deprecated Use {@see get_registry()} instead
963 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
964 * @param string $class Name of custom class
965 * @return boolean True on success, false otherwise
968 * Set which class SimplePie uses for caching
970 public function set_cache_class($class = 'SimplePie_Cache')
972 return $this->registry->register('Cache', $class, true);
976 * Set which class SimplePie uses for auto-discovery
978 public function set_locator_class($class = 'SimplePie_Locator')
980 return $this->registry->register('Locator', $class, true);
984 * Set which class SimplePie uses for XML parsing
986 public function set_parser_class($class = 'SimplePie_Parser')
988 return $this->registry->register('Parser', $class, true);
992 * Set which class SimplePie uses for remote file fetching
994 public function set_file_class($class = 'SimplePie_File')
996 return $this->registry->register('File', $class, true);
1000 * Set which class SimplePie uses for data sanitization
1002 public function set_sanitize_class($class = 'SimplePie_Sanitize')
1004 return $this->registry->register('Sanitize', $class, true);
1008 * Set which class SimplePie uses for handling feed items
1010 public function set_item_class($class = 'SimplePie_Item')
1012 return $this->registry->register('Item', $class, true);
1016 * Set which class SimplePie uses for handling author data
1018 public function set_author_class($class = 'SimplePie_Author')
1020 return $this->registry->register('Author', $class, true);
1024 * Set which class SimplePie uses for handling category data
1026 public function set_category_class($class = 'SimplePie_Category')
1028 return $this->registry->register('Category', $class, true);
1032 * Set which class SimplePie uses for feed enclosures
1034 public function set_enclosure_class($class = 'SimplePie_Enclosure')
1036 return $this->registry->register('Enclosure', $class, true);
1040 * Set which class SimplePie uses for `<media:text>` captions
1042 public function set_caption_class($class = 'SimplePie_Caption')
1044 return $this->registry->register('Caption', $class, true);
1048 * Set which class SimplePie uses for `<media:copyright>`
1050 public function set_copyright_class($class = 'SimplePie_Copyright')
1052 return $this->registry->register('Copyright', $class, true);
1056 * Set which class SimplePie uses for `<media:credit>`
1058 public function set_credit_class($class = 'SimplePie_Credit')
1060 return $this->registry->register('Credit', $class, true);
1064 * Set which class SimplePie uses for `<media:rating>`
1066 public function set_rating_class($class = 'SimplePie_Rating')
1068 return $this->registry->register('Rating', $class, true);
1072 * Set which class SimplePie uses for `<media:restriction>`
1074 public function set_restriction_class($class = 'SimplePie_Restriction')
1076 return $this->registry->register('Restriction', $class, true);
1080 * Set which class SimplePie uses for content-type sniffing
1082 public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1084 return $this->registry->register('Content_Type_Sniffer', $class, true);
1088 * Set which class SimplePie uses item sources
1090 public function set_source_class($class = 'SimplePie_Source')
1092 return $this->registry->register('Source', $class, true);
1097 * Set the user agent string
1099 * @param string $ua New user agent string.
1101 public function set_useragent($ua = SIMPLEPIE_USERAGENT)
1103 $this->useragent = (string) $ua;
1107 * Set callback function to create cache filename with
1109 * @param mixed $function Callback function
1111 public function set_cache_name_function($function = 'md5')
1113 if (is_callable($function))
1115 $this->cache_name_function = $function;
1120 * Set options to make SP as fast as possible
1122 * Forgoes a substantial amount of data sanitization in favor of speed. This
1123 * turns SimplePie into a dumb parser of feeds.
1125 * @param bool $set Whether to set them or not
1127 public function set_stupidly_fast($set = false)
1131 $this->enable_order_by_date(false);
1132 $this->remove_div(false);
1133 $this->strip_comments(false);
1134 $this->strip_htmltags(false);
1135 $this->strip_attributes(false);
1136 $this->set_image_handler(false);
1141 * Set maximum number of feeds to check with autodiscovery
1143 * @param int $max Maximum number of feeds to check
1145 public function set_max_checked_feeds($max = 10)
1147 $this->max_checked_feeds = (int) $max;
1150 public function remove_div($enable = true)
1152 $this->sanitize->remove_div($enable);
1155 public function strip_htmltags($tags = '', $encode = null)
1159 $tags = $this->strip_htmltags;
1161 $this->sanitize->strip_htmltags($tags);
1162 if ($encode !== null)
1164 $this->sanitize->encode_instead_of_strip($tags);
1168 public function encode_instead_of_strip($enable = true)
1170 $this->sanitize->encode_instead_of_strip($enable);
1173 public function strip_attributes($attribs = '')
1175 if ($attribs === '')
1177 $attribs = $this->strip_attributes;
1179 $this->sanitize->strip_attributes($attribs);
1183 * Set the output encoding
1185 * Allows you to override SimplePie's output to match that of your webpage.
1186 * This is useful for times when your webpages are not being served as
1187 * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
1188 * is similar to {@see set_input_encoding()}.
1190 * It should be noted, however, that not all character encodings can support
1191 * all characters. If your page is being served as ISO-8859-1 and you try
1192 * to display a Japanese feed, you'll likely see garbled characters.
1193 * Because of this, it is highly recommended to ensure that your webpages
1194 * are served as UTF-8.
1196 * The number of supported character encodings depends on whether your web
1197 * host supports {@link http://php.net/mbstring mbstring},
1198 * {@link http://php.net/iconv iconv}, or both. See
1199 * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
1202 * @param string $encoding
1204 public function set_output_encoding($encoding = 'UTF-8')
1206 $this->sanitize->set_output_encoding($encoding);
1209 public function strip_comments($strip = false)
1211 $this->sanitize->strip_comments($strip);
1215 * Set element/attribute key/value pairs of HTML attributes
1216 * containing URLs that need to be resolved relative to the feed
1218 * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
1219 * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
1223 * @param array|null $element_attribute Element/attribute key/value pairs, null for default
1225 public function set_url_replacements($element_attribute = null)
1227 $this->sanitize->set_url_replacements($element_attribute);
1231 * Set the handler to enable the display of cached images.
1233 * @param str $page Web-accessible path to the handler_image.php file.
1234 * @param str $qs The query string that the value should be passed to.
1236 public function set_image_handler($page = false, $qs = 'i')
1238 if ($page !== false)
1240 $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1244 $this->image_handler = '';
1249 * Set the limit for items returned per-feed with multifeeds
1251 * @param integer $limit The maximum number of items to return.
1253 public function set_item_limit($limit = 0)
1255 $this->item_limit = (int) $limit;
1259 * Initialize the feed object
1261 * This is what makes everything happen. Period. This is where all of the
1262 * configuration options get processed, feeds are fetched, cached, and
1263 * parsed, and all of that other good stuff.
1265 * @return boolean True if successful, false otherwise
1267 public function init()
1269 // Check absolute bare minimum requirements.
1270 if (!extension_loaded('xml') || !extension_loaded('pcre'))
1274 // 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.
1275 elseif (!extension_loaded('xmlreader'))
1277 static $xml_is_sane = null;
1278 if ($xml_is_sane === null)
1280 $parser_check = xml_parser_create();
1281 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
1282 xml_parser_free($parser_check);
1283 $xml_is_sane = isset($values[0]['value']);
1291 if (method_exists($this->sanitize, 'set_registry'))
1293 $this->sanitize->set_registry($this->registry);
1296 // Pass whatever was set with config options over to the sanitizer.
1297 // Pass the classes in for legacy support; new classes should use the registry instead
1298 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
1299 $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
1301 if (!empty($this->multifeed_url))
1305 $this->multifeed_objects = array();
1306 $this->error = array();
1307 foreach ($this->multifeed_url as $url)
1309 $this->multifeed_objects[$i] = clone $this;
1310 $this->multifeed_objects[$i]->set_feed_url($url);
1311 $single_success = $this->multifeed_objects[$i]->init();
1312 $success |= $single_success;
1313 if (!$single_success)
1315 $this->error[$i] = $this->multifeed_objects[$i]->error();
1319 return (bool) $success;
1321 elseif ($this->feed_url === null && $this->raw_data === null)
1326 $this->error = null;
1327 $this->data = array();
1328 $this->multifeed_objects = array();
1331 if ($this->feed_url !== null)
1333 $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
1335 // Decide whether to enable caching
1336 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1338 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
1341 // Fetch the data via SimplePie_File into $this->raw_data
1342 if (($fetched = $this->fetch_data($cache)) === true)
1346 elseif ($fetched === false) {
1350 list($headers, $sniffed) = $fetched;
1353 // Set up array of possible encodings
1354 $encodings = array();
1356 // First check to see if input has been overridden.
1357 if ($this->input_encoding !== false)
1359 $encodings[] = $this->input_encoding;
1362 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1363 $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1365 // RFC 3023 (only applies to sniffed content)
1366 if (isset($sniffed))
1368 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1370 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1372 $encodings[] = strtoupper($charset[1]);
1374 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1375 $encodings[] = 'UTF-8';
1377 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1379 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1381 $encodings[] = $charset[1];
1383 $encodings[] = 'US-ASCII';
1385 // Text MIME-type default
1386 elseif (substr($sniffed, 0, 5) === 'text/')
1388 $encodings[] = 'US-ASCII';
1392 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1393 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1394 $encodings[] = 'UTF-8';
1395 $encodings[] = 'ISO-8859-1';
1397 // There's no point in trying an encoding twice
1398 $encodings = array_unique($encodings);
1400 // Loop through each possible encoding, till we return something, or run out of possibilities
1401 foreach ($encodings as $encoding)
1403 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1404 if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
1406 // Create new parser
1407 $parser = $this->registry->create('Parser');
1409 // If it's parsed fine
1410 if ($parser->parse($utf8_data, 'UTF-8'))
1412 $this->data = $parser->get_data();
1413 if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
1415 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1416 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1420 if (isset($headers))
1422 $this->data['headers'] = $headers;
1424 $this->data['build'] = SIMPLEPIE_BUILD;
1426 // Cache the file if caching is enabled
1427 if ($cache && !$cache->save($this))
1429 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);
1438 // We have an error, just set SimplePie_Misc::error to it and quit
1439 $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());
1443 $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.';
1446 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1452 * Fetch the data via SimplePie_File
1454 * If the data is already cached, attempt to fetch it from there instead
1455 * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache
1456 * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
1458 protected function fetch_data(&$cache)
1460 // If it's enabled, use the cache
1464 $this->data = $cache->load();
1465 if (!empty($this->data))
1467 // If the cache is for an outdated build of SimplePie
1468 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1471 $this->data = array();
1473 // If we've hit a collision just rerun it with caching disabled
1474 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1477 $this->data = array();
1479 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1480 elseif (isset($this->data['feed_url']))
1482 // If the autodiscovery cache is still valid use it.
1483 if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1485 // Do not need to do feed autodiscovery yet.
1486 if ($this->data['feed_url'] !== $this->data['url'])
1488 $this->set_feed_url($this->data['feed_url']);
1489 return $this->init();
1493 $this->data = array();
1496 // Check if the cache has been updated
1497 elseif ($cache->mtime() + $this->cache_duration < time())
1499 // If we have last-modified and/or etag set
1500 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1503 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
1505 if (isset($this->data['headers']['last-modified']))
1507 $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1509 if (isset($this->data['headers']['etag']))
1511 $headers['if-none-match'] = $this->data['headers']['etag'];
1514 $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
1518 if ($file->status_code === 304)
1530 // If the cache is still valid, just return true
1533 $this->raw_data = false;
1537 // If the cache is empty, delete it
1541 $this->data = array();
1544 // 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.
1547 if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
1549 $file =& $this->file;
1554 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
1556 $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
1559 // If the file connection has an error, set SimplePie::error to that and quit
1560 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1562 $this->error = $file->error;
1563 return !empty($this->data);
1566 if (!$this->force_feed)
1568 // Check if the supplied URL is a feed, if it isn't, look for it.
1569 $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
1571 if (!$locate->is_feed($file))
1573 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1577 if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
1579 $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.";
1580 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1584 catch (SimplePie_Exception $e)
1586 // This is usually because DOMDocument doesn't exist
1587 $this->error = $e->getMessage();
1588 $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
1593 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1594 if (!$cache->save($this))
1596 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);
1598 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
1600 $this->feed_url = $file->url;
1605 $this->raw_data = $file->body;
1607 $headers = $file->headers;
1608 $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
1609 $sniffed = $sniffer->get_type();
1611 return array($headers, $sniffed);
1615 * Get the error message for the occurred error.
1617 * @return string|array Error message, or array of messages for multifeeds
1619 public function error()
1621 return $this->error;
1627 * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
1628 * the data instead of printing it.
1630 * @return string|boolean Raw XML data, false if the cache is used
1632 public function get_raw_data()
1634 return $this->raw_data;
1638 * Get the character encoding used for output
1640 * @since Preview Release
1643 public function get_encoding()
1645 return $this->sanitize->output_encoding;
1649 * Send the content-type header with correct encoding
1651 * This method ensures that the SimplePie-enabled page is being served with
1652 * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
1653 * and character encoding HTTP headers (character encoding determined by the
1654 * {@see set_output_encoding} config option).
1656 * This won't work properly if any content or whitespace has already been
1657 * sent to the browser, because it relies on PHP's
1658 * {@link http://php.net/header header()} function, and these are the
1659 * circumstances under which the function works.
1661 * Because it's setting these settings for the entire page (as is the nature
1662 * of HTTP headers), this should only be used once per page (again, at the
1665 * @param string $mime MIME type to serve the page as
1667 public function handle_content_type($mime = 'text/html')
1669 if (!headers_sent())
1671 $header = "Content-type: $mime;";
1672 if ($this->get_encoding())
1674 $header .= ' charset=' . $this->get_encoding();
1678 $header .= ' charset=UTF-8';
1685 * Get the type of the feed
1687 * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against
1688 * using {@link http://php.net/language.operators.bitwise bitwise operators}
1690 * @since 0.8 (usage changed to using constants in 1.0)
1691 * @see SIMPLEPIE_TYPE_NONE Unknown.
1692 * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90.
1693 * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
1694 * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
1695 * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91.
1696 * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92.
1697 * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93.
1698 * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94.
1699 * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0.
1700 * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x.
1701 * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS.
1702 * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
1703 * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS.
1704 * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3.
1705 * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0.
1706 * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom.
1707 * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type.
1708 * @return int SIMPLEPIE_TYPE_* constant
1710 public function get_type()
1712 if (!isset($this->data['type']))
1714 $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1715 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1717 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1719 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1721 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1723 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1725 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1726 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1727 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1728 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1730 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1732 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1733 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1734 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1735 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1737 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1740 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1742 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1743 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1745 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1748 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1749 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1751 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1754 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1758 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1765 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1769 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1773 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1777 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1784 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1787 return $this->data['type'];
1791 * Get the URL for the feed
1793 * May or may not be different from the URL passed to {@see set_feed_url()},
1794 * depending on whether auto-discovery was used.
1796 * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
1797 * @todo If we have a perm redirect we should return the new URL
1798 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1799 * @todo Also, |atom:link|@rel=self
1800 * @return string|null
1802 public function subscribe_url()
1804 if ($this->feed_url !== null)
1806 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1815 * Get data for an feed-level element
1817 * This method allows you to get access to ANY element/attribute that is a
1818 * sub-element of the opening feed tag.
1820 * The return value is an indexed array of elements matching the given
1821 * namespace and tag name. Each element has `attribs`, `data` and `child`
1822 * subkeys. For `attribs` and `child`, these contain namespace subkeys.
1823 * `attribs` then has one level of associative name => value data (where
1824 * `value` is a string) after the namespace. `child` has tag-indexed keys
1825 * after the namespace, each member of which is an indexed array matching
1830 * // This is probably a bad example because we already support
1831 * // <media:content> natively, but it shows you how to parse through
1833 * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
1834 * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
1835 * $file = $content[0]['attribs']['']['url'];
1840 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1841 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1842 * @param string $tag Tag name
1845 public function get_feed_tags($namespace, $tag)
1847 $type = $this->get_type();
1848 if ($type & SIMPLEPIE_TYPE_ATOM_10)
1850 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
1852 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
1855 if ($type & SIMPLEPIE_TYPE_ATOM_03)
1857 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
1859 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
1862 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
1864 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
1866 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
1869 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1871 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
1873 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
1880 * Get data for an channel-level element
1882 * This method allows you to get access to ANY element/attribute in the
1883 * channel/header section of the feed.
1885 * See {@see SimplePie::get_feed_tags()} for a description of the return value
1888 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1889 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1890 * @param string $tag Tag name
1893 public function get_channel_tags($namespace, $tag)
1895 $type = $this->get_type();
1896 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
1898 if ($return = $this->get_feed_tags($namespace, $tag))
1903 if ($type & SIMPLEPIE_TYPE_RSS_10)
1905 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
1907 if (isset($channel[0]['child'][$namespace][$tag]))
1909 return $channel[0]['child'][$namespace][$tag];
1913 if ($type & SIMPLEPIE_TYPE_RSS_090)
1915 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
1917 if (isset($channel[0]['child'][$namespace][$tag]))
1919 return $channel[0]['child'][$namespace][$tag];
1923 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1925 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
1927 if (isset($channel[0]['child'][$namespace][$tag]))
1929 return $channel[0]['child'][$namespace][$tag];
1937 * Get data for an channel-level element
1939 * This method allows you to get access to ANY element/attribute in the
1940 * image/logo section of the feed.
1942 * See {@see SimplePie::get_feed_tags()} for a description of the return value
1945 * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1946 * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1947 * @param string $tag Tag name
1950 public function get_image_tags($namespace, $tag)
1952 $type = $this->get_type();
1953 if ($type & SIMPLEPIE_TYPE_RSS_10)
1955 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
1957 if (isset($image[0]['child'][$namespace][$tag]))
1959 return $image[0]['child'][$namespace][$tag];
1963 if ($type & SIMPLEPIE_TYPE_RSS_090)
1965 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
1967 if (isset($image[0]['child'][$namespace][$tag]))
1969 return $image[0]['child'][$namespace][$tag];
1973 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1975 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
1977 if (isset($image[0]['child'][$namespace][$tag]))
1979 return $image[0]['child'][$namespace][$tag];
1987 * Get the base URL value from the feed
1989 * Uses `<xml:base>` if available, otherwise uses the first link in the
1990 * feed, or failing that, the URL of the feed itself.
1993 * @see subscribe_url
1995 * @param array $element
1998 public function get_base($element = array())
2000 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2002 return $element['xml_base'];
2004 elseif ($this->get_link() !== null)
2006 return $this->get_link();
2010 return $this->subscribe_url();
2015 * Sanitize feed data
2018 * @see SimplePie_Sanitize::sanitize()
2019 * @param string $data Data to sanitize
2020 * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
2021 * @param string $base Base URL to resolve URLs against
2022 * @return string Sanitized data
2024 public function sanitize($data, $type, $base = '')
2026 return $this->sanitize->sanitize($data, $type, $base);
2030 * Get the title of the feed
2032 * Uses `<atom:title>`, `<title>` or `<dc:title>`
2034 * @since 1.0 (previously called `get_feed_title` since 0.8)
2035 * @return string|null
2037 public function get_title()
2039 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2041 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2043 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2045 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2047 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2049 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2051 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2053 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2055 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2057 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2059 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2061 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2063 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2065 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2074 * Get a category for the feed
2077 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
2078 * @return SimplePie_Category|null
2080 public function get_category($key = 0)
2082 $categories = $this->get_categories();
2083 if (isset($categories[$key]))
2085 return $categories[$key];
2094 * Get all categories for the feed
2096 * Uses `<atom:category>`, `<category>` or `<dc:subject>`
2099 * @return array|null List of {@see SimplePie_Category} objects
2101 public function get_categories()
2103 $categories = array();
2105 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2110 if (isset($category['attribs']['']['term']))
2112 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2114 if (isset($category['attribs']['']['scheme']))
2116 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2118 if (isset($category['attribs']['']['label']))
2120 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2122 $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
2124 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2126 // This is really the label, but keep this as the term also for BC.
2127 // Label will also work on retrieving because that falls back to term.
2128 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2129 if (isset($category['attribs']['']['domain']))
2131 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2137 $categories[] = $this->registry->create('Category', array($term, $scheme, null));
2139 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2141 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2143 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2145 $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2148 if (!empty($categories))
2150 return array_unique($categories);
2159 * Get an author for the feed
2162 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
2163 * @return SimplePie_Author|null
2165 public function get_author($key = 0)
2167 $authors = $this->get_authors();
2168 if (isset($authors[$key]))
2170 return $authors[$key];
2179 * Get all authors for the feed
2181 * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
2184 * @return array|null List of {@see SimplePie_Author} objects
2186 public function get_authors()
2189 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2194 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2196 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2198 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2200 $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]));
2202 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2204 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2206 if ($name !== null || $email !== null || $uri !== null)
2208 $authors[] = $this->registry->create('Author', array($name, $uri, $email));
2211 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2216 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2218 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2220 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2222 $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]));
2224 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2226 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2228 if ($name !== null || $email !== null || $url !== null)
2230 $authors[] = $this->registry->create('Author', array($name, $url, $email));
2233 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2235 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2237 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2239 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2241 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2243 $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2246 if (!empty($authors))
2248 return array_unique($authors);
2257 * Get a contributor for the feed
2260 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
2261 * @return SimplePie_Author|null
2263 public function get_contributor($key = 0)
2265 $contributors = $this->get_contributors();
2266 if (isset($contributors[$key]))
2268 return $contributors[$key];
2277 * Get all contributors for the feed
2279 * Uses `<atom:contributor>`
2282 * @return array|null List of {@see SimplePie_Author} objects
2284 public function get_contributors()
2286 $contributors = array();
2287 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2292 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2294 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2296 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2298 $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]));
2300 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2302 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2304 if ($name !== null || $email !== null || $uri !== null)
2306 $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
2309 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2314 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2316 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2318 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2320 $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]));
2322 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2324 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2326 if ($name !== null || $email !== null || $url !== null)
2328 $contributors[] = $this->registry->create('Author', array($name, $url, $email));
2332 if (!empty($contributors))
2334 return array_unique($contributors);
2343 * Get a single link for the feed
2345 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2346 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
2347 * @param string $rel The relationship of the link to return
2348 * @return string|null Link URL
2350 public function get_link($key = 0, $rel = 'alternate')
2352 $links = $this->get_links($rel);
2353 if (isset($links[$key]))
2355 return $links[$key];
2364 * Get the permalink for the item
2366 * Returns the first link available with a relationship of "alternate".
2367 * Identical to {@see get_link()} with key 0
2370 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2371 * @internal Added for parity between the parent-level and the item/entry-level.
2372 * @return string|null Link URL
2374 public function get_permalink()
2376 return $this->get_link(0);
2380 * Get all links for the feed
2382 * Uses `<atom:link>` or `<link>`
2385 * @param string $rel The relationship of links to return
2386 * @return array|null Links found for the feed (strings)
2388 public function get_links($rel = 'alternate')
2390 if (!isset($this->data['links']))
2392 $this->data['links'] = array();
2393 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2395 foreach ($links as $link)
2397 if (isset($link['attribs']['']['href']))
2399 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2400 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2404 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2406 foreach ($links as $link)
2408 if (isset($link['attribs']['']['href']))
2410 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2411 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2416 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2418 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2420 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2422 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2424 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2426 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2429 $keys = array_keys($this->data['links']);
2430 foreach ($keys as $key)
2432 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
2434 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2436 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2437 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2441 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2444 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2446 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2448 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2452 if (isset($this->data['links'][$rel]))
2454 return $this->data['links'][$rel];
2462 public function get_all_discovered_feeds()
2464 return $this->all_discovered_feeds;
2468 * Get the content for the item
2470 * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
2471 * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
2473 * @since 1.0 (previously called `get_feed_description()` since 0.8)
2474 * @return string|null
2476 public function get_description()
2478 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2480 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2482 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2484 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2486 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2488 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2490 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2492 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2494 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2496 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2498 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2500 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2502 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2504 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2506 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2508 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2510 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2512 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2521 * Get the copyright info for the feed
2523 * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
2525 * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
2526 * @return string|null
2528 public function get_copyright()
2530 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2532 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2534 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2536 return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2538 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2540 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2542 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2544 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2546 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2548 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2557 * Get the language for the feed
2559 * Uses `<language>`, `<dc:language>`, or @xml_lang
2561 * @since 1.0 (previously called `get_feed_language()` since 0.8)
2562 * @return string|null
2564 public function get_language()
2566 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2568 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2570 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2572 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2574 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2576 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2578 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2580 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2582 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2584 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2586 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2588 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2590 elseif (isset($this->data['headers']['content-language']))
2592 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2601 * Get the latitude coordinates for the item
2603 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2605 * Uses `<geo:lat>` or `<georss:point>`
2608 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2609 * @link http://www.georss.org/ GeoRSS
2610 * @return string|null
2612 public function get_latitude()
2615 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2617 return (float) $return[0]['data'];
2619 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))
2621 return (float) $match[1];
2630 * Get the longitude coordinates for the feed
2632 * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2634 * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
2637 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2638 * @link http://www.georss.org/ GeoRSS
2639 * @return string|null
2641 public function get_longitude()
2643 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2645 return (float) $return[0]['data'];
2647 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2649 return (float) $return[0]['data'];
2651 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))
2653 return (float) $match[2];
2662 * Get the feed logo's title
2664 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
2666 * Uses `<image><title>` or `<image><dc:title>`
2668 * @return string|null
2670 public function get_image_title()
2672 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2674 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2676 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2678 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2680 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2682 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2684 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2688 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2699 * Get the feed logo's URL
2701 * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
2702 * have a "feed logo" URL. This points directly to the image itself.
2704 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2705 * `<image><title>` or `<image><dc:title>`
2707 * @return string|null
2709 public function get_image_url()
2711 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2713 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2715 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2717 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2719 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2721 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2723 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2725 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2727 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2729 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2731 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2733 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2743 * Get the feed logo's link
2745 * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
2746 * points to a human-readable page that the image should link to.
2748 * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2749 * `<image><title>` or `<image><dc:title>`
2751 * @return string|null
2753 public function get_image_link()
2755 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2757 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2759 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2761 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2763 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2765 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2774 * Get the feed logo's link
2776 * RSS 2.0 feeds are allowed to have a "feed logo" width.
2778 * Uses `<image><width>` or defaults to 88.0 if no width is specified and
2779 * the feed is an RSS 2.0 feed.
2781 * @return int|float|null
2783 public function get_image_width()
2785 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2787 return round($return[0]['data']);
2789 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2800 * Get the feed logo's height
2802 * RSS 2.0 feeds are allowed to have a "feed logo" height.
2804 * Uses `<image><height>` or defaults to 31.0 if no height is specified and
2805 * the feed is an RSS 2.0 feed.
2807 * @return int|float|null
2809 public function get_image_height()
2811 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2813 return round($return[0]['data']);
2815 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2826 * Get the number of items in the feed
2828 * This is well-suited for {@link http://php.net/for for()} loops with
2831 * @param int $max Maximum value to return. 0 for no limit
2832 * @return int Number of items in the feed
2834 public function get_item_quantity($max = 0)
2837 $qty = count($this->get_items());
2844 return ($qty > $max) ? $max : $qty;
2849 * Get a single item from the feed
2851 * This is better suited for {@link http://php.net/for for()} loops, whereas
2852 * {@see get_items()} is better suited for
2853 * {@link http://php.net/foreach foreach()} loops.
2855 * @see get_item_quantity()
2857 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
2858 * @return SimplePie_Item|null
2860 public function get_item($key = 0)
2862 $items = $this->get_items();
2863 if (isset($items[$key]))
2865 return $items[$key];
2874 * Get all items from the feed
2876 * This is better suited for {@link http://php.net/for for()} loops, whereas
2877 * {@see get_items()} is better suited for
2878 * {@link http://php.net/foreach foreach()} loops.
2880 * @see get_item_quantity
2882 * @param int $start Index to start at
2883 * @param int $end Number of items to return. 0 for all items after `$start`
2884 * @return array|null List of {@see SimplePie_Item} objects
2886 public function get_items($start = 0, $end = 0)
2888 if (!isset($this->data['items']))
2890 if (!empty($this->multifeed_objects))
2892 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2896 $this->data['items'] = array();
2897 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2899 $keys = array_keys($items);
2900 foreach ($keys as $key)
2902 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2905 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2907 $keys = array_keys($items);
2908 foreach ($keys as $key)
2910 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2913 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2915 $keys = array_keys($items);
2916 foreach ($keys as $key)
2918 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2921 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2923 $keys = array_keys($items);
2924 foreach ($keys as $key)
2926 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2929 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2931 $keys = array_keys($items);
2932 foreach ($keys as $key)
2934 $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2940 if (!empty($this->data['items']))
2942 // If we want to order it by date, check if all items have a date, and then sort it
2943 if ($this->order_by_date && empty($this->multifeed_objects))
2945 if (!isset($this->data['ordered_items']))
2948 foreach ($this->data['items'] as $item)
2950 if (!$item->get_date('U'))
2957 $this->data['ordered_items'] = $this->data['items'];
2960 usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
2963 $items = $this->data['ordered_items'];
2967 $items = $this->data['items'];
2970 // Slice the data as desired
2973 return array_slice($items, $start);
2977 return array_slice($items, $start, $end);
2987 * Set the favicon handler
2989 * @deprecated Use your own favicon handling instead
2991 public function set_favicon_handler($page = false, $qs = 'i')
2993 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2994 trigger_error('Favicon handling has been removed, please use your own handling', $level);
2999 * Get the favicon for the current feed
3001 * @deprecated Use your own favicon handling instead
3003 public function get_favicon()
3005 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
3006 trigger_error('Favicon handling has been removed, please use your own handling', $level);
3008 if (($url = $this->get_link()) !== null)
3010 return 'http://g.etfv.co/' . urlencode($url);
3017 * Magic method handler
3019 * @param string $method Method name
3020 * @param array $args Arguments to the method
3023 public function __call($method, $args)
3025 if (strpos($method, 'subscribe_') === 0)
3027 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
3028 trigger_error('subscribe_*() has been deprecated, implement the callback yourself', $level);
3031 if ($method === 'enable_xml_dump')
3033 $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
3034 trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
3038 $class = get_class($this);
3039 $trace = debug_backtrace();
3040 $file = $trace[0]['file'];
3041 $line = $trace[0]['line'];
3042 trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
3046 * Sorting callback for items
3049 * @param SimplePie $a
3050 * @param SimplePie $b
3053 public static function sort_items($a, $b)
3055 return $a->get_date('U') <= $b->get_date('U');
3059 * Merge items from several feeds into one
3061 * If you're merging multiple feeds together, they need to all have dates
3062 * for the items or else SimplePie will refuse to sort them.
3064 * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
3065 * @param array $urls List of SimplePie feed objects to merge
3066 * @param int $start Starting item
3067 * @param int $end Number of items to return
3068 * @param int $limit Maximum number of items per feed
3071 public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3073 if (is_array($urls) && sizeof($urls) > 0)
3076 foreach ($urls as $arg)
3078 if ($arg instanceof SimplePie)
3080 $items = array_merge($items, $arg->get_items(0, $limit));
3084 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3089 foreach ($items as $item)
3091 if (!$item->get_date('U'))
3100 usort($items, array(get_class($urls[0]), 'sort_items'));
3105 return array_slice($items, $start);
3109 return array_slice($items, $start, $end);
3114 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);