wp/wp-includes/class-simplepie.php
changeset 16 a86126ab1dd4
parent 7 cf61fcea0001
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    24 function wp_simplepie_autoload( $class ) {
    24 function wp_simplepie_autoload( $class ) {
    25 	if ( 0 !== strpos( $class, 'SimplePie_' ) )
    25 	if ( 0 !== strpos( $class, 'SimplePie_' ) )
    26 		return;
    26 		return;
    27 
    27 
    28 	$file = ABSPATH . WPINC . '/' . str_replace( '_', '/', $class ) . '.php';
    28 	$file = ABSPATH . WPINC . '/' . str_replace( '_', '/', $class ) . '.php';
    29 	include( $file );
    29 	include $file;
    30 }
    30 }
    31 
    31 
    32 /**
    32 /**
    33  * We autoload classes we may not need.
    33  * We autoload classes we may not need.
    34  */
    34  */
    38  * SimplePie
    38  * SimplePie
    39  *
    39  *
    40  * A PHP-Based RSS and Atom Feed Framework.
    40  * A PHP-Based RSS and Atom Feed Framework.
    41  * Takes the hard work out of managing a complete RSS/Atom solution.
    41  * Takes the hard work out of managing a complete RSS/Atom solution.
    42  *
    42  *
    43  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
    43  * Copyright (c) 2004-2017, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
    44  * All rights reserved.
    44  * All rights reserved.
    45  *
    45  *
    46  * Redistribution and use in source and binary forms, with or without modification, are
    46  * Redistribution and use in source and binary forms, with or without modification, are
    47  * permitted provided that the following conditions are met:
    47  * permitted provided that the following conditions are met:
    48  *
    48  *
    66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    67  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    67  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    68  * POSSIBILITY OF SUCH DAMAGE.
    68  * POSSIBILITY OF SUCH DAMAGE.
    69  *
    69  *
    70  * @package SimplePie
    70  * @package SimplePie
    71  * @version 1.3.1
    71  * @version 1.5.5
    72  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
    72  * @copyright 2004-2017 Ryan Parman, Sam Sneddon, Ryan McCue
    73  * @author Ryan Parman
    73  * @author Ryan Parman
    74  * @author Geoffrey Sneddon
    74  * @author Sam Sneddon
    75  * @author Ryan McCue
    75  * @author Ryan McCue
    76  * @link http://simplepie.org/ SimplePie
    76  * @link http://simplepie.org/ SimplePie
    77  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
    77  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
    78  */
    78  */
    79 
    79 
    83 define('SIMPLEPIE_NAME', 'SimplePie');
    83 define('SIMPLEPIE_NAME', 'SimplePie');
    84 
    84 
    85 /**
    85 /**
    86  * SimplePie Version
    86  * SimplePie Version
    87  */
    87  */
    88 define('SIMPLEPIE_VERSION', '1.3.1');
    88 define('SIMPLEPIE_VERSION', '1.5.5');
    89 
    89 
    90 /**
    90 /**
    91  * SimplePie Build
    91  * SimplePie Build
    92  * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
    92  * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
    93  */
    93  */
   479 	 * @access private
   479 	 * @access private
   480 	 */
   480 	 */
   481 	public $feed_url;
   481 	public $feed_url;
   482 
   482 
   483 	/**
   483 	/**
       
   484 	 * @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently
       
   485 	 * @see SimplePie::subscribe_url()
       
   486 	 * @access private
       
   487 	 */
       
   488 	public $permanent_url = null;
       
   489 
       
   490 	/**
   484 	 * @var object Instance of SimplePie_File to use as a feed
   491 	 * @var object Instance of SimplePie_File to use as a feed
   485 	 * @see SimplePie::set_file()
   492 	 * @see SimplePie::set_file()
   486 	 * @access private
   493 	 * @access private
   487 	 */
   494 	 */
   488 	public $file;
   495 	public $file;
   498 	 * @var int Timeout for fetching remote files
   505 	 * @var int Timeout for fetching remote files
   499 	 * @see SimplePie::set_timeout()
   506 	 * @see SimplePie::set_timeout()
   500 	 * @access private
   507 	 * @access private
   501 	 */
   508 	 */
   502 	public $timeout = 10;
   509 	public $timeout = 10;
       
   510 
       
   511 	/**
       
   512 	 * @var array Custom curl options
       
   513 	 * @see SimplePie::set_curl_options()
       
   514 	 * @access private
       
   515 	 */
       
   516 	public $curl_options = array();
   503 
   517 
   504 	/**
   518 	/**
   505 	 * @var bool Forces fsockopen() to be used for remote files instead
   519 	 * @var bool Forces fsockopen() to be used for remote files instead
   506 	 * of cURL, even if a new enough version is installed
   520 	 * of cURL, even if a new enough version is installed
   507 	 * @see SimplePie::force_fsockopen()
   521 	 * @see SimplePie::force_fsockopen()
   523 	 * @access private
   537 	 * @access private
   524 	 */
   538 	 */
   525 	public $cache = true;
   539 	public $cache = true;
   526 
   540 
   527 	/**
   541 	/**
       
   542 	 * @var bool Force SimplePie to fallback to expired cache, if enabled,
       
   543 	 * when feed is unavailable.
       
   544 	 * @see SimplePie::force_cache_fallback()
       
   545 	 * @access private
       
   546 	 */
       
   547 	public $force_cache_fallback = false;
       
   548 
       
   549 	/**
   528 	 * @var int Cache duration (in seconds)
   550 	 * @var int Cache duration (in seconds)
   529 	 * @see SimplePie::set_cache_duration()
   551 	 * @see SimplePie::set_cache_duration()
   530 	 * @access private
   552 	 * @access private
   531 	 */
   553 	 */
   532 	public $cache_duration = 3600;
   554 	public $cache_duration = 3600;
   628 	 * @access private
   650 	 * @access private
   629 	 */
   651 	 */
   630 	public $item_limit = 0;
   652 	public $item_limit = 0;
   631 
   653 
   632 	/**
   654 	/**
       
   655 	 * @var bool Stores if last-modified and/or etag headers were sent with the
       
   656 	 * request when checking a feed.
       
   657 	 */
       
   658 	public $check_modified = false;
       
   659 
       
   660 	/**
   633 	 * @var array Stores the default attributes to be stripped by strip_attributes().
   661 	 * @var array Stores the default attributes to be stripped by strip_attributes().
   634 	 * @see SimplePie::strip_attributes()
   662 	 * @see SimplePie::strip_attributes()
   635 	 * @access private
   663 	 * @access private
   636 	 */
   664 	 */
   637 	public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
   665 	public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
   638 
   666 
   639 	/**
   667 	/**
       
   668 	 * @var array Stores the default attributes to add to different tags by add_attributes().
       
   669 	 * @see SimplePie::add_attributes()
       
   670 	 * @access private
       
   671 	 */
       
   672 	public $add_attributes = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none'));
       
   673 
       
   674 	/**
   640 	 * @var array Stores the default tags to be stripped by strip_htmltags().
   675 	 * @var array Stores the default tags to be stripped by strip_htmltags().
   641 	 * @see SimplePie::strip_htmltags()
   676 	 * @see SimplePie::strip_htmltags()
   642 	 * @access private
   677 	 * @access private
   643 	 */
   678 	 */
   644 	public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
   679 	public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
       
   680 
       
   681 	/**
       
   682 	 * @var bool Should we throw exceptions, or use the old-style error property?
       
   683 	 * @access private
       
   684 	 */
       
   685 	public $enable_exceptions = false;
   645 
   686 
   646 	/**
   687 	/**
   647 	 * The SimplePie class contains feed level data and options
   688 	 * The SimplePie class contains feed level data and options
   648 	 *
   689 	 *
   649 	 * To use SimplePie, create the SimplePie object with no parameters. You can
   690 	 * To use SimplePie, create the SimplePie object with no parameters. You can
   657 	 *
   698 	 *
   658 	 * @since 1.0 Preview Release
   699 	 * @since 1.0 Preview Release
   659 	 */
   700 	 */
   660 	public function __construct()
   701 	public function __construct()
   661 	{
   702 	{
   662 		if (version_compare(PHP_VERSION, '5.2', '<'))
   703 		if (version_compare(PHP_VERSION, '5.6', '<'))
   663 		{
   704 		{
   664 			trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
   705 			trigger_error('Please upgrade to PHP 5.6 or newer.');
   665 			die();
   706 			die();
   666 		}
   707 		}
   667 
   708 
   668 		// Other objects, instances created here so we can set options on them
   709 		// Other objects, instances created here so we can set options on them
   669 		$this->sanitize = new SimplePie_Sanitize();
   710 		$this->sanitize = new SimplePie_Sanitize();
   670 		$this->registry = new SimplePie_Registry();
   711 		$this->registry = new SimplePie_Registry();
   671 
   712 
   672 		if (func_num_args() > 0)
   713 		if (func_num_args() > 0)
   673 		{
   714 		{
   674 			$level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
   715 			$level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
   675 			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);
   716 			trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_duration() directly.', $level);
   676 
   717 
   677 			$args = func_get_args();
   718 			$args = func_get_args();
   678 			switch (count($args)) {
   719 			switch (count($args)) {
   679 				case 3:
   720 				case 3:
   680 					$this->set_cache_duration($args[2]);
   721 					$this->set_cache_duration($args[2]);
   698 	/**
   739 	/**
   699 	 * Remove items that link back to this before destroying this object
   740 	 * Remove items that link back to this before destroying this object
   700 	 */
   741 	 */
   701 	public function __destruct()
   742 	public function __destruct()
   702 	{
   743 	{
   703 		if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
   744 		if (!gc_enabled())
   704 		{
   745 		{
   705 			if (!empty($this->data['items']))
   746 			if (!empty($this->data['items']))
   706 			{
   747 			{
   707 				foreach ($this->data['items'] as $item)
   748 				foreach ($this->data['items'] as $item)
   708 				{
   749 				{
   761 			}
   802 			}
   762 		}
   803 		}
   763 		else
   804 		else
   764 		{
   805 		{
   765 			$this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
   806 			$this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
       
   807 			$this->permanent_url = $this->feed_url;
   766 		}
   808 		}
   767 	}
   809 	}
   768 
   810 
   769 	/**
   811 	/**
   770 	 * Set an instance of {@see SimplePie_File} to use as a feed
   812 	 * Set an instance of {@see SimplePie_File} to use as a feed
   775 	public function set_file(&$file)
   817 	public function set_file(&$file)
   776 	{
   818 	{
   777 		if ($file instanceof SimplePie_File)
   819 		if ($file instanceof SimplePie_File)
   778 		{
   820 		{
   779 			$this->feed_url = $file->url;
   821 			$this->feed_url = $file->url;
       
   822 			$this->permanent_url = $this->feed_url;
   780 			$this->file =& $file;
   823 			$this->file =& $file;
   781 			return true;
   824 			return true;
   782 		}
   825 		}
   783 		return false;
   826 		return false;
   784 	}
   827 	}
   800 	{
   843 	{
   801 		$this->raw_data = $data;
   844 		$this->raw_data = $data;
   802 	}
   845 	}
   803 
   846 
   804 	/**
   847 	/**
   805 	 * Set the the default timeout for fetching remote feeds
   848 	 * Set the default timeout for fetching remote feeds
   806 	 *
   849 	 *
   807 	 * This allows you to change the maximum time the feed's server to respond
   850 	 * This allows you to change the maximum time the feed's server to respond
   808 	 * and send the feed back.
   851 	 * and send the feed back.
   809 	 *
   852 	 *
   810 	 * @since 1.0 Beta 3
   853 	 * @since 1.0 Beta 3
   814 	{
   857 	{
   815 		$this->timeout = (int) $timeout;
   858 		$this->timeout = (int) $timeout;
   816 	}
   859 	}
   817 
   860 
   818 	/**
   861 	/**
       
   862 	 * Set custom curl options
       
   863 	 *
       
   864 	 * This allows you to change default curl options
       
   865 	 *
       
   866 	 * @since 1.0 Beta 3
       
   867 	 * @param array $curl_options Curl options to add to default settings
       
   868 	 */
       
   869 	public function set_curl_options(array $curl_options = array())
       
   870 	{
       
   871 		$this->curl_options = $curl_options;
       
   872 	}
       
   873 
       
   874 	/**
   819 	 * Force SimplePie to use fsockopen() instead of cURL
   875 	 * Force SimplePie to use fsockopen() instead of cURL
   820 	 *
   876 	 *
   821 	 * @since 1.0 Beta 3
   877 	 * @since 1.0 Beta 3
   822 	 * @param bool $enable Force fsockopen() to be used
   878 	 * @param bool $enable Force fsockopen() to be used
   823 	 */
   879 	 */
   836 	 * @param bool $enable Enable caching
   892 	 * @param bool $enable Enable caching
   837 	 */
   893 	 */
   838 	public function enable_cache($enable = true)
   894 	public function enable_cache($enable = true)
   839 	{
   895 	{
   840 		$this->cache = (bool) $enable;
   896 		$this->cache = (bool) $enable;
       
   897 	}
       
   898 
       
   899 	/**
       
   900 	 * SimplePie to continue to fall back to expired cache, if enabled, when
       
   901 	 * feed is unavailable.
       
   902 	 *
       
   903 	 * This tells SimplePie to ignore any file errors and fall back to cache
       
   904 	 * instead. This only works if caching is enabled and cached content
       
   905 	 * still exists.
       
   906 
       
   907 	 * @param bool $enable Force use of cache on fail.
       
   908 	 */
       
   909 	public function force_cache_fallback($enable = false)
       
   910 	{
       
   911 		$this->force_cache_fallback= (bool) $enable;
   841 	}
   912 	}
   842 
   913 
   843 	/**
   914 	/**
   844 	 * Set the length of time (in seconds) that the contents of a feed will be
   915 	 * Set the length of time (in seconds) that the contents of a feed will be
   845 	 * cached
   916 	 * cached
  1106 			$this->enable_order_by_date(false);
  1177 			$this->enable_order_by_date(false);
  1107 			$this->remove_div(false);
  1178 			$this->remove_div(false);
  1108 			$this->strip_comments(false);
  1179 			$this->strip_comments(false);
  1109 			$this->strip_htmltags(false);
  1180 			$this->strip_htmltags(false);
  1110 			$this->strip_attributes(false);
  1181 			$this->strip_attributes(false);
       
  1182 			$this->add_attributes(false);
  1111 			$this->set_image_handler(false);
  1183 			$this->set_image_handler(false);
  1112 		}
  1184 		}
  1113 	}
  1185 	}
  1114 
  1186 
  1115 	/**
  1187 	/**
  1152 			$attribs = $this->strip_attributes;
  1224 			$attribs = $this->strip_attributes;
  1153 		}
  1225 		}
  1154 		$this->sanitize->strip_attributes($attribs);
  1226 		$this->sanitize->strip_attributes($attribs);
  1155 	}
  1227 	}
  1156 
  1228 
       
  1229 	public function add_attributes($attribs = '')
       
  1230 	{
       
  1231 		if ($attribs === '')
       
  1232 		{
       
  1233 			$attribs = $this->add_attributes;
       
  1234 		}
       
  1235 		$this->sanitize->add_attributes($attribs);
       
  1236 	}
       
  1237 
  1157 	/**
  1238 	/**
  1158 	 * Set the output encoding
  1239 	 * Set the output encoding
  1159 	 *
  1240 	 *
  1160 	 * Allows you to override SimplePie's output to match that of your webpage.
  1241 	 * Allows you to override SimplePie's output to match that of your webpage.
  1161 	 * This is useful for times when your webpages are not being served as
  1242 	 * This is useful for times when your webpages are not being served as
  1162 	 * UTF-8.  This setting will be obeyed by {@see handle_content_type()}, and
  1243 	 * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
  1163 	 * is similar to {@see set_input_encoding()}.
  1244 	 * is similar to {@see set_input_encoding()}.
  1164 	 *
  1245 	 *
  1165 	 * It should be noted, however, that not all character encodings can support
  1246 	 * It should be noted, however, that not all character encodings can support
  1166 	 * all characters.  If your page is being served as ISO-8859-1 and you try
  1247 	 * all characters. If your page is being served as ISO-8859-1 and you try
  1167 	 * to display a Japanese feed, you'll likely see garbled characters.
  1248 	 * to display a Japanese feed, you'll likely see garbled characters.
  1168 	 * Because of this, it is highly recommended to ensure that your webpages
  1249 	 * Because of this, it is highly recommended to ensure that your webpages
  1169 	 * are served as UTF-8.
  1250 	 * are served as UTF-8.
  1170 	 *
  1251 	 *
  1171 	 * The number of supported character encodings depends on whether your web
  1252 	 * The number of supported character encodings depends on whether your web
  1203 	}
  1284 	}
  1204 
  1285 
  1205 	/**
  1286 	/**
  1206 	 * Set the handler to enable the display of cached images.
  1287 	 * Set the handler to enable the display of cached images.
  1207 	 *
  1288 	 *
  1208 	 * @param str $page Web-accessible path to the handler_image.php file.
  1289 	 * @param string $page Web-accessible path to the handler_image.php file.
  1209 	 * @param str $qs The query string that the value should be passed to.
  1290 	 * @param string $qs The query string that the value should be passed to.
  1210 	 */
  1291 	 */
  1211 	public function set_image_handler($page = false, $qs = 'i')
  1292 	public function set_image_handler($page = false, $qs = 'i')
  1212 	{
  1293 	{
  1213 		if ($page !== false)
  1294 		if ($page !== false)
  1214 		{
  1295 		{
  1229 	{
  1310 	{
  1230 		$this->item_limit = (int) $limit;
  1311 		$this->item_limit = (int) $limit;
  1231 	}
  1312 	}
  1232 
  1313 
  1233 	/**
  1314 	/**
       
  1315 	 * Enable throwing exceptions
       
  1316 	 *
       
  1317 	 * @param boolean $enable Should we throw exceptions, or use the old-style error property?
       
  1318 	 */
       
  1319 	public function enable_exceptions($enable = true)
       
  1320 	{
       
  1321 		$this->enable_exceptions = $enable;
       
  1322 	}
       
  1323 
       
  1324 	/**
  1234 	 * Initialize the feed object
  1325 	 * Initialize the feed object
  1235 	 *
  1326 	 *
  1236 	 * This is what makes everything happen.  Period.  This is where all of the
  1327 	 * This is what makes everything happen. Period. This is where all of the
  1237 	 * configuration options get processed, feeds are fetched, cached, and
  1328 	 * configuration options get processed, feeds are fetched, cached, and
  1238 	 * parsed, and all of that other good stuff.
  1329 	 * parsed, and all of that other good stuff.
  1239 	 *
  1330 	 *
  1240 	 * @return boolean True if successful, false otherwise
  1331 	 * @return boolean True if successful, false otherwise
  1241 	 */
  1332 	 */
  1242 	public function init()
  1333 	public function init()
  1243 	{
  1334 	{
  1244 		// Check absolute bare minimum requirements.
  1335 		// Check absolute bare minimum requirements.
  1245 		if (!extension_loaded('xml') || !extension_loaded('pcre'))
  1336 		if (!extension_loaded('xml') || !extension_loaded('pcre'))
  1246 		{
  1337 		{
       
  1338 			$this->error = 'XML or PCRE extensions not loaded!';
  1247 			return false;
  1339 			return false;
  1248 		}
  1340 		}
  1249 		// 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.
  1341 		// 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.
  1250 		elseif (!extension_loaded('xmlreader'))
  1342 		elseif (!extension_loaded('xmlreader'))
  1251 		{
  1343 		{
  1261 			{
  1353 			{
  1262 				return false;
  1354 				return false;
  1263 			}
  1355 			}
  1264 		}
  1356 		}
  1265 
  1357 
       
  1358 		// The default sanitize class gets set in the constructor, check if it has
       
  1359 		// changed.
       
  1360 		if ($this->registry->get_class('Sanitize') !== 'SimplePie_Sanitize') {
       
  1361 			$this->sanitize = $this->registry->create('Sanitize');
       
  1362 		}
  1266 		if (method_exists($this->sanitize, 'set_registry'))
  1363 		if (method_exists($this->sanitize, 'set_registry'))
  1267 		{
  1364 		{
  1268 			$this->sanitize->set_registry($this->registry);
  1365 			$this->sanitize->set_registry($this->registry);
  1269 		}
  1366 		}
  1270 
  1367 
  1271 		// Pass whatever was set with config options over to the sanitizer.
  1368 		// Pass whatever was set with config options over to the sanitizer.
  1272 		// Pass the classes in for legacy support; new classes should use the registry instead
  1369 		// Pass the classes in for legacy support; new classes should use the registry instead
  1273 		$this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
  1370 		$this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
  1274 		$this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
  1371 		$this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen, $this->curl_options);
  1275 
  1372 
  1276 		if (!empty($this->multifeed_url))
  1373 		if (!empty($this->multifeed_url))
  1277 		{
  1374 		{
  1278 			$i = 0;
  1375 			$i = 0;
  1279 			$success = 0;
  1376 			$success = 0;
  1298 			return false;
  1395 			return false;
  1299 		}
  1396 		}
  1300 
  1397 
  1301 		$this->error = null;
  1398 		$this->error = null;
  1302 		$this->data = array();
  1399 		$this->data = array();
       
  1400 		$this->check_modified = false;
  1303 		$this->multifeed_objects = array();
  1401 		$this->multifeed_objects = array();
  1304 		$cache = false;
  1402 		$cache = false;
  1305 
  1403 
  1306 		if ($this->feed_url !== null)
  1404 		if ($this->feed_url !== null)
  1307 		{
  1405 		{
  1308 			$parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
  1406 			$parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
  1309 
  1407 
  1310 			// Decide whether to enable caching
  1408 			// Decide whether to enable caching
  1311 			if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1409 			if ($this->cache && $parsed_feed_url['scheme'] !== '')
  1312 			{
  1410 			{
  1313 				$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
  1411 				$url = $this->feed_url . ($this->force_feed ? '#force_feed' : '');
       
  1412 				$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $url), 'spc'));
  1314 			}
  1413 			}
  1315 
  1414 
  1316 			// Fetch the data via SimplePie_File into $this->raw_data
  1415 			// Fetch the data via SimplePie_File into $this->raw_data
  1317 			if (($fetched = $this->fetch_data($cache)) === true)
  1416 			if (($fetched = $this->fetch_data($cache)) === true)
  1318 			{
  1417 			{
  1323 			}
  1422 			}
  1324 
  1423 
  1325 			list($headers, $sniffed) = $fetched;
  1424 			list($headers, $sniffed) = $fetched;
  1326 		}
  1425 		}
  1327 
  1426 
       
  1427 		// Empty response check
       
  1428 		if(empty($this->raw_data)){
       
  1429 			$this->error = "A feed could not be found at `$this->feed_url`. Empty body.";
       
  1430 			$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
       
  1431 			return false;
       
  1432 		}
       
  1433 
  1328 		// Set up array of possible encodings
  1434 		// Set up array of possible encodings
  1329 		$encodings = array();
  1435 		$encodings = array();
  1330 
  1436 
  1331 		// First check to see if input has been overridden.
  1437 		// First check to see if input has been overridden.
  1332 		if ($this->input_encoding !== false)
  1438 		if ($this->input_encoding !== false)
  1333 		{
  1439 		{
  1334 			$encodings[] = $this->input_encoding;
  1440 			$encodings[] = strtoupper($this->input_encoding);
  1335 		}
  1441 		}
  1336 
  1442 
  1337 		$application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1443 		$application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
  1338 		$text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1444 		$text_types = array('text/xml', 'text/xml-external-parsed-entity');
  1339 
  1445 
  1351 			}
  1457 			}
  1352 			elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1458 			elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
  1353 			{
  1459 			{
  1354 				if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1460 				if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
  1355 				{
  1461 				{
  1356 					$encodings[] = $charset[1];
  1462 					$encodings[] = strtoupper($charset[1]);
  1357 				}
  1463 				}
  1358 				$encodings[] = 'US-ASCII';
  1464 				$encodings[] = 'US-ASCII';
  1359 			}
  1465 			}
  1360 			// Text MIME-type default
  1466 			// Text MIME-type default
  1361 			elseif (substr($sniffed, 0, 5) === 'text/')
  1467 			elseif (substr($sniffed, 0, 5) === 'text/')
  1362 			{
  1468 			{
  1363 				$encodings[] = 'US-ASCII';
  1469 				$encodings[] = 'UTF-8';
  1364 			}
  1470 			}
  1365 		}
  1471 		}
  1366 
  1472 
  1367 		// Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1473 		// Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
  1368 		$encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
  1474 		$encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
  1380 			{
  1486 			{
  1381 				// Create new parser
  1487 				// Create new parser
  1382 				$parser = $this->registry->create('Parser');
  1488 				$parser = $this->registry->create('Parser');
  1383 
  1489 
  1384 				// If it's parsed fine
  1490 				// If it's parsed fine
  1385 				if ($parser->parse($utf8_data, 'UTF-8'))
  1491 				if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url))
  1386 				{
  1492 				{
  1387 					$this->data = $parser->get_data();
  1493 					$this->data = $parser->get_data();
  1388 					if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
  1494 					if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
  1389 					{
  1495 					{
  1390 						$this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
  1496 						$this->error = "A feed could not be found at `$this->feed_url`. This does not appear to be a valid RSS or Atom feed.";
  1391 						$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  1497 						$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  1392 						return false;
  1498 						return false;
  1393 					}
  1499 					}
  1394 
  1500 
  1395 					if (isset($headers))
  1501 					if (isset($headers))
  1399 					$this->data['build'] = SIMPLEPIE_BUILD;
  1505 					$this->data['build'] = SIMPLEPIE_BUILD;
  1400 
  1506 
  1401 					// Cache the file if caching is enabled
  1507 					// Cache the file if caching is enabled
  1402 					if ($cache && !$cache->save($this))
  1508 					if ($cache && !$cache->save($this))
  1403 					{
  1509 					{
  1404 						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);
  1510 						trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  1405 					}
  1511 					}
  1406 					return true;
  1512 					return true;
  1407 				}
  1513 				}
  1408 			}
  1514 			}
  1409 		}
  1515 		}
  1410 
  1516 
  1411 		if (isset($parser))
  1517 		if (isset($parser))
  1412 		{
  1518 		{
  1413 			// We have an error, just set SimplePie_Misc::error to it and quit
  1519 			// We have an error, just set SimplePie_Misc::error to it and quit
  1414 			$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());
  1520 			$this->error = $this->feed_url;
       
  1521 			$this->error .= sprintf(' is invalid XML, 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());
  1415 		}
  1522 		}
  1416 		else
  1523 		else
  1417 		{
  1524 		{
  1418 			$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.';
  1525 			$this->error = 'The data could not be converted to UTF-8.';
       
  1526 			if (!extension_loaded('mbstring') && !extension_loaded('iconv') && !class_exists('\UConverter')) {
       
  1527 				$this->error .= ' You MUST have either the iconv, mbstring or intl (PHP 5.5+) extension installed and enabled.';
       
  1528 			} else {
       
  1529 				$missingExtensions = array();
       
  1530 				if (!extension_loaded('iconv')) {
       
  1531 					$missingExtensions[] = 'iconv';
       
  1532 				}
       
  1533 				if (!extension_loaded('mbstring')) {
       
  1534 					$missingExtensions[] = 'mbstring';
       
  1535 				}
       
  1536 				if (!class_exists('\UConverter')) {
       
  1537 					$missingExtensions[] = 'intl (PHP 5.5+)';
       
  1538 				}
       
  1539 				$this->error .= ' Try installing/enabling the ' . implode(' or ', $missingExtensions) . ' extension.';
       
  1540 			}
  1419 		}
  1541 		}
  1420 
  1542 
  1421 		$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  1543 		$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  1422 
  1544 
  1423 		return false;
  1545 		return false;
  1469 					}
  1591 					}
  1470 				}
  1592 				}
  1471 				// Check if the cache has been updated
  1593 				// Check if the cache has been updated
  1472 				elseif ($cache->mtime() + $this->cache_duration < time())
  1594 				elseif ($cache->mtime() + $this->cache_duration < time())
  1473 				{
  1595 				{
  1474 					// If we have last-modified and/or etag set
  1596 					// Want to know if we tried to send last-modified and/or etag headers
       
  1597 					// when requesting this file. (Note that it's up to the file to
       
  1598 					// support this, but we don't always send the headers either.)
       
  1599 					$this->check_modified = true;
  1475 					if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1600 					if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
  1476 					{
  1601 					{
  1477 						$headers = array(
  1602 						$headers = array(
  1478 							'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',
  1603 							'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',
  1479 						);
  1604 						);
  1484 						if (isset($this->data['headers']['etag']))
  1609 						if (isset($this->data['headers']['etag']))
  1485 						{
  1610 						{
  1486 							$headers['if-none-match'] = $this->data['headers']['etag'];
  1611 							$headers['if-none-match'] = $this->data['headers']['etag'];
  1487 						}
  1612 						}
  1488 
  1613 
  1489 						$file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
  1614 						$file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
  1490 
  1615 
  1491 						if ($file->success)
  1616 						if ($file->success)
  1492 						{
  1617 						{
  1493 							if ($file->status_code === 304)
  1618 							if ($file->status_code === 304)
  1494 							{
  1619 							{
       
  1620 								// Set raw_data to false here too, to signify that the cache
       
  1621 								// is still valid.
       
  1622 								$this->raw_data = false;
  1495 								$cache->touch();
  1623 								$cache->touch();
  1496 								return true;
  1624 								return true;
  1497 							}
  1625 							}
  1498 						}
  1626 						}
  1499 						else
  1627 						else
  1500 						{
  1628 						{
       
  1629 							$this->check_modified = false;
       
  1630 							if($this->force_cache_fallback)
       
  1631 							{
       
  1632 								$cache->touch();
       
  1633 								return true;
       
  1634 							}
       
  1635 
  1501 							unset($file);
  1636 							unset($file);
  1502 						}
  1637 						}
  1503 					}
  1638 					}
  1504 				}
  1639 				}
  1505 				// If the cache is still valid, just return true
  1640 				// If the cache is still valid, just return true
  1526 			else
  1661 			else
  1527 			{
  1662 			{
  1528 				$headers = array(
  1663 				$headers = array(
  1529 					'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',
  1664 					'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',
  1530 				);
  1665 				);
  1531 				$file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
  1666 				$file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
  1532 			}
  1667 			}
  1533 		}
  1668 		}
  1534 		// If the file connection has an error, set SimplePie::error to that and quit
  1669 		// If the file connection has an error, set SimplePie::error to that and quit
  1535 		if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  1670 		if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
  1536 		{
  1671 		{
  1539 		}
  1674 		}
  1540 
  1675 
  1541 		if (!$this->force_feed)
  1676 		if (!$this->force_feed)
  1542 		{
  1677 		{
  1543 			// Check if the supplied URL is a feed, if it isn't, look for it.
  1678 			// Check if the supplied URL is a feed, if it isn't, look for it.
  1544 			$locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
  1679 			$locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds, $this->force_fsockopen, $this->curl_options));
  1545 
  1680 
  1546 			if (!$locate->is_feed($file))
  1681 			if (!$locate->is_feed($file))
  1547 			{
  1682 			{
  1548 				// We need to unset this so that if SimplePie::set_file() has been called that object is untouched
  1683 				$copyStatusCode = $file->status_code;
  1549 				unset($file);
  1684 				$copyContentType = $file->headers['content-type'];
  1550 				try
  1685 				try
  1551 				{
  1686 				{
  1552 					if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
  1687 					$microformats = false;
       
  1688 					if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
       
  1689 						$doc = new DOMDocument();
       
  1690 						@$doc->loadHTML($file->body);
       
  1691 						$xpath = new DOMXpath($doc);
       
  1692 						// Check for both h-feed and h-entry, as both a feed with no entries
       
  1693 						// and a list of entries without an h-feed wrapper are both valid.
       
  1694 						$query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
       
  1695 							'contains(concat(" ", @class, " "), " h-entry ")]';
       
  1696 						$result = $xpath->query($query);
       
  1697 						$microformats = $result->length !== 0;
       
  1698 					}
       
  1699 					// Now also do feed discovery, but if microformats were found don't
       
  1700 					// overwrite the current value of file.
       
  1701 					$discovered = $locate->find($this->autodiscovery,
       
  1702 					                            $this->all_discovered_feeds);
       
  1703 					if ($microformats)
  1553 					{
  1704 					{
  1554 						$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.";
  1705 						if ($hub = $locate->get_rel_link('hub'))
  1555 						$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
  1706 						{
  1556 						return false;
  1707 							$self = $locate->get_rel_link('self');
       
  1708 							$this->store_links($file, $hub, $self);
       
  1709 						}
       
  1710 						// Push the current file onto all_discovered feeds so the user can
       
  1711 						// be shown this as one of the options.
       
  1712 						if (isset($this->all_discovered_feeds)) {
       
  1713 							$this->all_discovered_feeds[] = $file;
       
  1714 						}
  1557 					}
  1715 					}
       
  1716 					else
       
  1717 					{
       
  1718 						if ($discovered)
       
  1719 						{
       
  1720 							$file = $discovered;
       
  1721 						}
       
  1722 						else
       
  1723 						{
       
  1724 							// We need to unset this so that if SimplePie::set_file() has
       
  1725 							// been called that object is untouched
       
  1726 							unset($file);
       
  1727 							$this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`";
       
  1728 							$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
       
  1729 							return false;
       
  1730 						}
       
  1731 					}
  1558 				}
  1732 				}
  1559 				catch (SimplePie_Exception $e)
  1733 				catch (SimplePie_Exception $e)
  1560 				{
  1734 				{
       
  1735 					// We need to unset this so that if SimplePie::set_file() has been called that object is untouched
       
  1736 					unset($file);
  1561 					// This is usually because DOMDocument doesn't exist
  1737 					// This is usually because DOMDocument doesn't exist
  1562 					$this->error = $e->getMessage();
  1738 					$this->error = $e->getMessage();
  1563 					$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
  1739 					$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
  1564 					return false;
  1740 					return false;
  1565 				}
  1741 				}
  1566 				if ($cache)
  1742 				if ($cache)
  1567 				{
  1743 				{
  1568 					$this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1744 					$this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
  1569 					if (!$cache->save($this))
  1745 					if (!$cache->save($this))
  1570 					{
  1746 					{
  1571 						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);
  1747 						trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
  1572 					}
  1748 					}
  1573 					$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
  1749 					$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
  1574 				}
  1750 				}
  1575 				$this->feed_url = $file->url;
  1751 			}
  1576 			}
  1752 			$this->feed_url = $file->url;
  1577 			$locate = null;
  1753 			$locate = null;
  1578 		}
  1754 		}
  1579 
  1755 
  1580 		$this->raw_data = $file->body;
  1756 		$this->raw_data = $file->body;
  1581 
  1757 		$this->permanent_url = $file->permanent_url;
  1582 		$headers = $file->headers;
  1758 		$headers = $file->headers;
  1583 		$sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
  1759 		$sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
  1584 		$sniffed = $sniffer->get_type();
  1760 		$sniffed = $sniffer->get_type();
  1585 
  1761 
  1586 		return array($headers, $sniffed);
  1762 		return array($headers, $sniffed);
  1587 	}
  1763 	}
  1588 
  1764 
  1589 	/**
  1765 	/**
  1590 	 * Get the error message for the occurred error.
  1766 	 * Get the error message for the occured error
  1591 	 *
  1767 	 *
  1592 	 * @return string|array Error message, or array of messages for multifeeds
  1768 	 * @return string|array Error message, or array of messages for multifeeds
  1593 	 */
  1769 	 */
  1594 	public function error()
  1770 	public function error()
  1595 	{
  1771 	{
  1763 	}
  1939 	}
  1764 
  1940 
  1765 	/**
  1941 	/**
  1766 	 * Get the URL for the feed
  1942 	 * Get the URL for the feed
  1767 	 *
  1943 	 *
  1768 	 * May or may not be different from the URL passed to {@see set_feed_url()},
  1944 	 * When the 'permanent' mode is enabled, returns the original feed URL,
  1769 	 * depending on whether auto-discovery was used.
  1945 	 * except in the case of an `HTTP 301 Moved Permanently` status response,
       
  1946 	 * in which case the location of the first redirection is returned.
       
  1947 	 *
       
  1948 	 * When the 'permanent' mode is disabled (default),
       
  1949 	 * may or may not be different from the URL passed to {@see set_feed_url()},
       
  1950 	 * depending on whether auto-discovery was used, and whether there were
       
  1951 	 * any redirects along the way.
  1770 	 *
  1952 	 *
  1771 	 * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
  1953 	 * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
  1772 	 * @todo If we have a perm redirect we should return the new URL
  1954 	 * @todo Support <itunes:new-feed-url>
  1773 	 * @todo When we make the above change, let's support <itunes:new-feed-url> as well
       
  1774 	 * @todo Also, |atom:link|@rel=self
  1955 	 * @todo Also, |atom:link|@rel=self
       
  1956 	 * @param bool $permanent Permanent mode to return only the original URL or the first redirection
       
  1957 	 * iff it is a 301 redirection
  1775 	 * @return string|null
  1958 	 * @return string|null
  1776 	 */
  1959 	 */
  1777 	public function subscribe_url()
  1960 	public function subscribe_url($permanent = false)
  1778 	{
  1961 	{
  1779 		if ($this->feed_url !== null)
  1962 		if ($permanent)
  1780 		{
  1963 		{
  1781 			return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
  1964 			if ($this->permanent_url !== null)
       
  1965 			{
       
  1966 				// sanitize encodes ampersands which are required when used in a url.
       
  1967 				return str_replace('&amp;', '&',
       
  1968 				                   $this->sanitize($this->permanent_url,
       
  1969 				                                   SIMPLEPIE_CONSTRUCT_IRI));
       
  1970 			}
  1782 		}
  1971 		}
  1783 		else
  1972 		else
  1784 		{
  1973 		{
  1785 			return null;
  1974 			if ($this->feed_url !== null)
  1786 		}
  1975 			{
       
  1976 				return str_replace('&amp;', '&',
       
  1977 				                   $this->sanitize($this->feed_url,
       
  1978 				                                   SIMPLEPIE_CONSTRUCT_IRI));
       
  1979 			}
       
  1980 		}
       
  1981 		return null;
  1787 	}
  1982 	}
  1788 
  1983 
  1789 	/**
  1984 	/**
  1790 	 * Get data for an feed-level element
  1985 	 * Get data for an feed-level element
  1791 	 *
  1986 	 *
  1978 		}
  2173 		}
  1979 		elseif ($this->get_link() !== null)
  2174 		elseif ($this->get_link() !== null)
  1980 		{
  2175 		{
  1981 			return $this->get_link();
  2176 			return $this->get_link();
  1982 		}
  2177 		}
  1983 		else
  2178 
  1984 		{
  2179 		return $this->subscribe_url();
  1985 			return $this->subscribe_url();
       
  1986 		}
       
  1987 	}
  2180 	}
  1988 
  2181 
  1989 	/**
  2182 	/**
  1990 	 * Sanitize feed data
  2183 	 * Sanitize feed data
  1991 	 *
  2184 	 *
  1996 	 * @param string $base Base URL to resolve URLs against
  2189 	 * @param string $base Base URL to resolve URLs against
  1997 	 * @return string Sanitized data
  2190 	 * @return string Sanitized data
  1998 	 */
  2191 	 */
  1999 	public function sanitize($data, $type, $base = '')
  2192 	public function sanitize($data, $type, $base = '')
  2000 	{
  2193 	{
  2001 		return $this->sanitize->sanitize($data, $type, $base);
  2194 		try
       
  2195 		{
       
  2196 			return $this->sanitize->sanitize($data, $type, $base);
       
  2197 		}
       
  2198 		catch (SimplePie_Exception $e)
       
  2199 		{
       
  2200 			if (!$this->enable_exceptions)
       
  2201 			{
       
  2202 				$this->error = $e->getMessage();
       
  2203 				$this->registry->call('Misc', 'error', array($this->error, E_USER_WARNING, $e->getFile(), $e->getLine()));
       
  2204 				return '';
       
  2205 			}
       
  2206 
       
  2207 			throw $e;
       
  2208 		}
  2002 	}
  2209 	}
  2003 
  2210 
  2004 	/**
  2211 	/**
  2005 	 * Get the title of the feed
  2212 	 * Get the title of the feed
  2006 	 *
  2213 	 *
  2037 		}
  2244 		}
  2038 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2245 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2039 		{
  2246 		{
  2040 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2247 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2041 		}
  2248 		}
  2042 		else
  2249 
  2043 		{
  2250 		return null;
  2044 			return null;
       
  2045 		}
       
  2046 	}
  2251 	}
  2047 
  2252 
  2048 	/**
  2253 	/**
  2049 	 * Get a category for the feed
  2254 	 * Get a category for the feed
  2050 	 *
  2255 	 *
  2051 	 * @since Unknown
  2256 	 * @since Unknown
  2052 	 * @param int $key The category that you want to return.  Remember that arrays begin with 0, not 1
  2257 	 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
  2053 	 * @return SimplePie_Category|null
  2258 	 * @return SimplePie_Category|null
  2054 	 */
  2259 	 */
  2055 	public function get_category($key = 0)
  2260 	public function get_category($key = 0)
  2056 	{
  2261 	{
  2057 		$categories = $this->get_categories();
  2262 		$categories = $this->get_categories();
  2058 		if (isset($categories[$key]))
  2263 		if (isset($categories[$key]))
  2059 		{
  2264 		{
  2060 			return $categories[$key];
  2265 			return $categories[$key];
  2061 		}
  2266 		}
  2062 		else
  2267 
  2063 		{
  2268 		return null;
  2064 			return null;
       
  2065 		}
       
  2066 	}
  2269 	}
  2067 
  2270 
  2068 	/**
  2271 	/**
  2069 	 * Get all categories for the feed
  2272 	 * Get all categories for the feed
  2070 	 *
  2273 	 *
  2122 
  2325 
  2123 		if (!empty($categories))
  2326 		if (!empty($categories))
  2124 		{
  2327 		{
  2125 			return array_unique($categories);
  2328 			return array_unique($categories);
  2126 		}
  2329 		}
  2127 		else
  2330 
  2128 		{
  2331 		return null;
  2129 			return null;
       
  2130 		}
       
  2131 	}
  2332 	}
  2132 
  2333 
  2133 	/**
  2334 	/**
  2134 	 * Get an author for the feed
  2335 	 * Get an author for the feed
  2135 	 *
  2336 	 *
  2136 	 * @since 1.1
  2337 	 * @since 1.1
  2137 	 * @param int $key The author that you want to return.  Remember that arrays begin with 0, not 1
  2338 	 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
  2138 	 * @return SimplePie_Author|null
  2339 	 * @return SimplePie_Author|null
  2139 	 */
  2340 	 */
  2140 	public function get_author($key = 0)
  2341 	public function get_author($key = 0)
  2141 	{
  2342 	{
  2142 		$authors = $this->get_authors();
  2343 		$authors = $this->get_authors();
  2143 		if (isset($authors[$key]))
  2344 		if (isset($authors[$key]))
  2144 		{
  2345 		{
  2145 			return $authors[$key];
  2346 			return $authors[$key];
  2146 		}
  2347 		}
  2147 		else
  2348 
  2148 		{
  2349 		return null;
  2149 			return null;
       
  2150 		}
       
  2151 	}
  2350 	}
  2152 
  2351 
  2153 	/**
  2352 	/**
  2154 	 * Get all authors for the feed
  2353 	 * Get all authors for the feed
  2155 	 *
  2354 	 *
  2220 
  2419 
  2221 		if (!empty($authors))
  2420 		if (!empty($authors))
  2222 		{
  2421 		{
  2223 			return array_unique($authors);
  2422 			return array_unique($authors);
  2224 		}
  2423 		}
  2225 		else
  2424 
  2226 		{
  2425 		return null;
  2227 			return null;
       
  2228 		}
       
  2229 	}
  2426 	}
  2230 
  2427 
  2231 	/**
  2428 	/**
  2232 	 * Get a contributor for the feed
  2429 	 * Get a contributor for the feed
  2233 	 *
  2430 	 *
  2234 	 * @since 1.1
  2431 	 * @since 1.1
  2235 	 * @param int $key The contrbutor that you want to return.  Remember that arrays begin with 0, not 1
  2432 	 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
  2236 	 * @return SimplePie_Author|null
  2433 	 * @return SimplePie_Author|null
  2237 	 */
  2434 	 */
  2238 	public function get_contributor($key = 0)
  2435 	public function get_contributor($key = 0)
  2239 	{
  2436 	{
  2240 		$contributors = $this->get_contributors();
  2437 		$contributors = $this->get_contributors();
  2241 		if (isset($contributors[$key]))
  2438 		if (isset($contributors[$key]))
  2242 		{
  2439 		{
  2243 			return $contributors[$key];
  2440 			return $contributors[$key];
  2244 		}
  2441 		}
  2245 		else
  2442 
  2246 		{
  2443 		return null;
  2247 			return null;
       
  2248 		}
       
  2249 	}
  2444 	}
  2250 
  2445 
  2251 	/**
  2446 	/**
  2252 	 * Get all contributors for the feed
  2447 	 * Get all contributors for the feed
  2253 	 *
  2448 	 *
  2306 
  2501 
  2307 		if (!empty($contributors))
  2502 		if (!empty($contributors))
  2308 		{
  2503 		{
  2309 			return array_unique($contributors);
  2504 			return array_unique($contributors);
  2310 		}
  2505 		}
  2311 		else
  2506 
  2312 		{
  2507 		return null;
  2313 			return null;
       
  2314 		}
       
  2315 	}
  2508 	}
  2316 
  2509 
  2317 	/**
  2510 	/**
  2318 	 * Get a single link for the feed
  2511 	 * Get a single link for the feed
  2319 	 *
  2512 	 *
  2320 	 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
  2513 	 * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
  2321 	 * @param int $key The link that you want to return.  Remember that arrays begin with 0, not 1
  2514 	 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
  2322 	 * @param string $rel The relationship of the link to return
  2515 	 * @param string $rel The relationship of the link to return
  2323 	 * @return string|null Link URL
  2516 	 * @return string|null Link URL
  2324 	 */
  2517 	 */
  2325 	public function get_link($key = 0, $rel = 'alternate')
  2518 	public function get_link($key = 0, $rel = 'alternate')
  2326 	{
  2519 	{
  2327 		$links = $this->get_links($rel);
  2520 		$links = $this->get_links($rel);
  2328 		if (isset($links[$key]))
  2521 		if (isset($links[$key]))
  2329 		{
  2522 		{
  2330 			return $links[$key];
  2523 			return $links[$key];
  2331 		}
  2524 		}
  2332 		else
  2525 
  2333 		{
  2526 		return null;
  2334 			return null;
       
  2335 		}
       
  2336 	}
  2527 	}
  2337 
  2528 
  2338 	/**
  2529 	/**
  2339 	 * Get the permalink for the item
  2530 	 * Get the permalink for the item
  2340 	 *
  2531 	 *
  2422 				}
  2613 				}
  2423 				$this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2614 				$this->data['links'][$key] = array_unique($this->data['links'][$key]);
  2424 			}
  2615 			}
  2425 		}
  2616 		}
  2426 
  2617 
  2427 		if (isset($this->data['links'][$rel]))
  2618 		if (isset($this->data['headers']['link']) &&
       
  2619 		    preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
       
  2620 		               $this->data['headers']['link'], $match))
       
  2621 		{
       
  2622 			return array($match[1]);
       
  2623 		}
       
  2624 		else if (isset($this->data['links'][$rel]))
  2428 		{
  2625 		{
  2429 			return $this->data['links'][$rel];
  2626 			return $this->data['links'][$rel];
  2430 		}
  2627 		}
  2431 		else
  2628 
  2432 		{
  2629 		return null;
  2433 			return null;
       
  2434 		}
       
  2435 	}
  2630 	}
  2436 
  2631 
  2437 	public function get_all_discovered_feeds()
  2632 	public function get_all_discovered_feeds()
  2438 	{
  2633 	{
  2439 		return $this->all_discovered_feeds;
  2634 		return $this->all_discovered_feeds;
  2484 		}
  2679 		}
  2485 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2680 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
  2486 		{
  2681 		{
  2487 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2682 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
  2488 		}
  2683 		}
  2489 		else
  2684 
  2490 		{
  2685 		return null;
  2491 			return null;
       
  2492 		}
       
  2493 	}
  2686 	}
  2494 
  2687 
  2495 	/**
  2688 	/**
  2496 	 * Get the copyright info for the feed
  2689 	 * Get the copyright info for the feed
  2497 	 *
  2690 	 *
  2520 		}
  2713 		}
  2521 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2714 		elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
  2522 		{
  2715 		{
  2523 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2716 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2524 		}
  2717 		}
  2525 		else
  2718 
  2526 		{
  2719 		return null;
  2527 			return null;
       
  2528 		}
       
  2529 	}
  2720 	}
  2530 
  2721 
  2531 	/**
  2722 	/**
  2532 	 * Get the language for the feed
  2723 	 * Get the language for the feed
  2533 	 *
  2724 	 *
  2564 		}
  2755 		}
  2565 		elseif (isset($this->data['headers']['content-language']))
  2756 		elseif (isset($this->data['headers']['content-language']))
  2566 		{
  2757 		{
  2567 			return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2758 			return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
  2568 		}
  2759 		}
  2569 		else
  2760 
  2570 		{
  2761 		return null;
  2571 			return null;
       
  2572 		}
       
  2573 	}
  2762 	}
  2574 
  2763 
  2575 	/**
  2764 	/**
  2576 	 * Get the latitude coordinates for the item
  2765 	 * Get the latitude coordinates for the item
  2577 	 *
  2766 	 *
  2593 		}
  2782 		}
  2594 		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))
  2783 		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))
  2595 		{
  2784 		{
  2596 			return (float) $match[1];
  2785 			return (float) $match[1];
  2597 		}
  2786 		}
  2598 		else
  2787 
  2599 		{
  2788 		return null;
  2600 			return null;
       
  2601 		}
       
  2602 	}
  2789 	}
  2603 
  2790 
  2604 	/**
  2791 	/**
  2605 	 * Get the longitude coordinates for the feed
  2792 	 * Get the longitude coordinates for the feed
  2606 	 *
  2793 	 *
  2625 		}
  2812 		}
  2626 		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))
  2813 		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))
  2627 		{
  2814 		{
  2628 			return (float) $match[2];
  2815 			return (float) $match[2];
  2629 		}
  2816 		}
  2630 		else
  2817 
  2631 		{
  2818 		return null;
  2632 			return null;
       
  2633 		}
       
  2634 	}
  2819 	}
  2635 
  2820 
  2636 	/**
  2821 	/**
  2637 	 * Get the feed logo's title
  2822 	 * Get the feed logo's title
  2638 	 *
  2823 	 *
  2662 		}
  2847 		}
  2663 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2848 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
  2664 		{
  2849 		{
  2665 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2850 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
  2666 		}
  2851 		}
  2667 		else
  2852 
  2668 		{
  2853 		return null;
  2669 			return null;
       
  2670 		}
       
  2671 	}
  2854 	}
  2672 
  2855 
  2673 	/**
  2856 	/**
  2674 	 * Get the feed logo's URL
  2857 	 * Get the feed logo's URL
  2675 	 *
  2858 	 *
  2705 		}
  2888 		}
  2706 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2889 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2707 		{
  2890 		{
  2708 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2891 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2709 		}
  2892 		}
  2710 		else
  2893 
  2711 		{
  2894 		return null;
  2712 			return null;
       
  2713 		}
       
  2714 	}
  2895 	}
  2715 
  2896 
  2716 
  2897 
  2717 	/**
  2898 	/**
  2718 	 * Get the feed logo's link
  2899 	 * Get the feed logo's link
  2737 		}
  2918 		}
  2738 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2919 		elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
  2739 		{
  2920 		{
  2740 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2921 			return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
  2741 		}
  2922 		}
  2742 		else
  2923 
  2743 		{
  2924 		return null;
  2744 			return null;
       
  2745 		}
       
  2746 	}
  2925 	}
  2747 
  2926 
  2748 	/**
  2927 	/**
  2749 	 * Get the feed logo's link
  2928 	 * Get the feed logo's link
  2750 	 *
  2929 	 *
  2763 		}
  2942 		}
  2764 		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2943 		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2765 		{
  2944 		{
  2766 			return 88.0;
  2945 			return 88.0;
  2767 		}
  2946 		}
  2768 		else
  2947 
  2769 		{
  2948 		return null;
  2770 			return null;
       
  2771 		}
       
  2772 	}
  2949 	}
  2773 
  2950 
  2774 	/**
  2951 	/**
  2775 	 * Get the feed logo's height
  2952 	 * Get the feed logo's height
  2776 	 *
  2953 	 *
  2789 		}
  2966 		}
  2790 		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2967 		elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
  2791 		{
  2968 		{
  2792 			return 31.0;
  2969 			return 31.0;
  2793 		}
  2970 		}
  2794 		else
  2971 
  2795 		{
  2972 		return null;
  2796 			return null;
       
  2797 		}
       
  2798 	}
  2973 	}
  2799 
  2974 
  2800 	/**
  2975 	/**
  2801 	 * Get the number of items in the feed
  2976 	 * Get the number of items in the feed
  2802 	 *
  2977 	 *
  2812 		$qty = count($this->get_items());
  2987 		$qty = count($this->get_items());
  2813 		if ($max === 0)
  2988 		if ($max === 0)
  2814 		{
  2989 		{
  2815 			return $qty;
  2990 			return $qty;
  2816 		}
  2991 		}
  2817 		else
  2992 
  2818 		{
  2993 		return ($qty > $max) ? $max : $qty;
  2819 			return ($qty > $max) ? $max : $qty;
       
  2820 		}
       
  2821 	}
  2994 	}
  2822 
  2995 
  2823 	/**
  2996 	/**
  2824 	 * Get a single item from the feed
  2997 	 * Get a single item from the feed
  2825 	 *
  2998 	 *
  2827 	 * {@see get_items()} is better suited for
  3000 	 * {@see get_items()} is better suited for
  2828 	 * {@link http://php.net/foreach foreach()} loops.
  3001 	 * {@link http://php.net/foreach foreach()} loops.
  2829 	 *
  3002 	 *
  2830 	 * @see get_item_quantity()
  3003 	 * @see get_item_quantity()
  2831 	 * @since Beta 2
  3004 	 * @since Beta 2
  2832 	 * @param int $key The item that you want to return.  Remember that arrays begin with 0, not 1
  3005 	 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
  2833 	 * @return SimplePie_Item|null
  3006 	 * @return SimplePie_Item|null
  2834 	 */
  3007 	 */
  2835 	public function get_item($key = 0)
  3008 	public function get_item($key = 0)
  2836 	{
  3009 	{
  2837 		$items = $this->get_items();
  3010 		$items = $this->get_items();
  2838 		if (isset($items[$key]))
  3011 		if (isset($items[$key]))
  2839 		{
  3012 		{
  2840 			return $items[$key];
  3013 			return $items[$key];
  2841 		}
  3014 		}
  2842 		else
  3015 
  2843 		{
  3016 		return null;
  2844 			return null;
       
  2845 		}
       
  2846 	}
  3017 	}
  2847 
  3018 
  2848 	/**
  3019 	/**
  2849 	 * Get all items from the feed
  3020 	 * Get all items from the feed
  2850 	 *
  3021 	 *
  2854 	 *
  3025 	 *
  2855 	 * @see get_item_quantity
  3026 	 * @see get_item_quantity
  2856 	 * @since Beta 2
  3027 	 * @since Beta 2
  2857 	 * @param int $start Index to start at
  3028 	 * @param int $start Index to start at
  2858 	 * @param int $end Number of items to return. 0 for all items after `$start`
  3029 	 * @param int $end Number of items to return. 0 for all items after `$start`
  2859 	 * @return array|null List of {@see SimplePie_Item} objects
  3030 	 * @return SimplePie_Item[]|null List of {@see SimplePie_Item} objects
  2860 	 */
  3031 	 */
  2861 	public function get_items($start = 0, $end = 0)
  3032 	public function get_items($start = 0, $end = 0)
  2862 	{
  3033 	{
  2863 		if (!isset($this->data['items']))
  3034 		if (!isset($this->data['items']))
  2864 		{
  3035 		{
  2865 			if (!empty($this->multifeed_objects))
  3036 			if (!empty($this->multifeed_objects))
  2866 			{
  3037 			{
  2867 				$this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  3038 				$this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
  2868 			}
  3039 				if (empty($this->data['items']))
  2869 			else
  3040 				{
  2870 			{
  3041 					return array();
  2871 				$this->data['items'] = array();
  3042 				}
  2872 				if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  3043 				return $this->data['items'];
  2873 				{
  3044 			}
  2874 					$keys = array_keys($items);
  3045 			$this->data['items'] = array();
  2875 					foreach ($keys as $key)
  3046 			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
  2876 					{
  3047 			{
  2877 						$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  3048 				$keys = array_keys($items);
  2878 					}
  3049 				foreach ($keys as $key)
  2879 				}
  3050 				{
  2880 				if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  3051 					$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  2881 				{
  3052 				}
  2882 					$keys = array_keys($items);
  3053 			}
  2883 					foreach ($keys as $key)
  3054 			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
  2884 					{
  3055 			{
  2885 						$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  3056 				$keys = array_keys($items);
  2886 					}
  3057 				foreach ($keys as $key)
  2887 				}
  3058 				{
  2888 				if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  3059 					$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  2889 				{
  3060 				}
  2890 					$keys = array_keys($items);
  3061 			}
  2891 					foreach ($keys as $key)
  3062 			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
  2892 					{
  3063 			{
  2893 						$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  3064 				$keys = array_keys($items);
  2894 					}
  3065 				foreach ($keys as $key)
  2895 				}
  3066 				{
  2896 				if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  3067 					$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  2897 				{
  3068 				}
  2898 					$keys = array_keys($items);
  3069 			}
  2899 					foreach ($keys as $key)
  3070 			if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
  2900 					{
  3071 			{
  2901 						$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  3072 				$keys = array_keys($items);
  2902 					}
  3073 				foreach ($keys as $key)
  2903 				}
  3074 				{
  2904 				if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  3075 					$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  2905 				{
  3076 				}
  2906 					$keys = array_keys($items);
  3077 			}
  2907 					foreach ($keys as $key)
  3078 			if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
  2908 					{
  3079 			{
  2909 						$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  3080 				$keys = array_keys($items);
  2910 					}
  3081 				foreach ($keys as $key)
  2911 				}
  3082 				{
  2912 			}
  3083 					$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
  2913 		}
  3084 				}
  2914 
  3085 			}
  2915 		if (!empty($this->data['items']))
  3086 		}
  2916 		{
  3087 
  2917 			// If we want to order it by date, check if all items have a date, and then sort it
  3088 		if (empty($this->data['items']))
  2918 			if ($this->order_by_date && empty($this->multifeed_objects))
  3089 		{
  2919 			{
  3090 			return array();
  2920 				if (!isset($this->data['ordered_items']))
  3091 		}
  2921 				{
  3092 
  2922 					$do_sort = true;
  3093 		if ($this->order_by_date)
  2923 					foreach ($this->data['items'] as $item)
  3094 		{
  2924 					{
  3095 			if (!isset($this->data['ordered_items']))
  2925 						if (!$item->get_date('U'))
  3096 			{
  2926 						{
  3097 				$this->data['ordered_items'] = $this->data['items'];
  2927 							$do_sort = false;
  3098 				usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
  2928 							break;
  3099 		 	}
  2929 						}
  3100 			$items = $this->data['ordered_items'];
  2930 					}
       
  2931 					$item = null;
       
  2932 					$this->data['ordered_items'] = $this->data['items'];
       
  2933 					if ($do_sort)
       
  2934 					{
       
  2935 						usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
       
  2936 					}
       
  2937 				}
       
  2938 				$items = $this->data['ordered_items'];
       
  2939 			}
       
  2940 			else
       
  2941 			{
       
  2942 				$items = $this->data['items'];
       
  2943 			}
       
  2944 
       
  2945 			// Slice the data as desired
       
  2946 			if ($end === 0)
       
  2947 			{
       
  2948 				return array_slice($items, $start);
       
  2949 			}
       
  2950 			else
       
  2951 			{
       
  2952 				return array_slice($items, $start, $end);
       
  2953 			}
       
  2954 		}
  3101 		}
  2955 		else
  3102 		else
  2956 		{
  3103 		{
  2957 			return array();
  3104 			$items = $this->data['items'];
  2958 		}
  3105 		}
       
  3106 		// Slice the data as desired
       
  3107 		if ($end === 0)
       
  3108 		{
       
  3109 			return array_slice($items, $start);
       
  3110 		}
       
  3111 
       
  3112 		return array_slice($items, $start, $end);
  2959 	}
  3113 	}
  2960 
  3114 
  2961 	/**
  3115 	/**
  2962 	 * Set the favicon handler
  3116 	 * Set the favicon handler
  2963 	 *
  3117 	 *
  2980 		$level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
  3134 		$level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
  2981 		trigger_error('Favicon handling has been removed, please use your own handling', $level);
  3135 		trigger_error('Favicon handling has been removed, please use your own handling', $level);
  2982 
  3136 
  2983 		if (($url = $this->get_link()) !== null)
  3137 		if (($url = $this->get_link()) !== null)
  2984 		{
  3138 		{
  2985 			return 'http://g.etfv.co/' . urlencode($url);
  3139 			return 'https://www.google.com/s2/favicons?domain=' . urlencode($url);
  2986 		}
  3140 		}
  2987 
  3141 
  2988 		return false;
  3142 		return false;
  2989 	}
  3143 	}
  2990 
  3144 
  3009 			trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
  3163 			trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
  3010 			return false;
  3164 			return false;
  3011 		}
  3165 		}
  3012 
  3166 
  3013 		$class = get_class($this);
  3167 		$class = get_class($this);
  3014 		$trace = debug_backtrace();
  3168 		$trace = debug_backtrace(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
  3015 		$file = $trace[0]['file'];
  3169 		$file = $trace[0]['file'];
  3016 		$line = $trace[0]['line'];
  3170 		$line = $trace[0]['line'];
  3017 		trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
  3171 		trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
  3018 	}
  3172 	}
  3019 
  3173 
  3025 	 * @param SimplePie $b
  3179 	 * @param SimplePie $b
  3026 	 * @return boolean
  3180 	 * @return boolean
  3027 	 */
  3181 	 */
  3028 	public static function sort_items($a, $b)
  3182 	public static function sort_items($a, $b)
  3029 	{
  3183 	{
  3030 		return $a->get_date('U') <= $b->get_date('U');
  3184 		$a_date = $a->get_date('U');
       
  3185 		$b_date = $b->get_date('U');
       
  3186 		if ($a_date && $b_date) {
       
  3187 			return $a_date > $b_date ? -1 : 1;
       
  3188 		}
       
  3189 		// Sort items without dates to the top.
       
  3190 		if ($a_date) {
       
  3191 			return 1;
       
  3192 		}
       
  3193 		if ($b_date) {
       
  3194 			return -1;
       
  3195 		}
       
  3196 		return 0;
  3031 	}
  3197 	}
  3032 
  3198 
  3033 	/**
  3199 	/**
  3034 	 * Merge items from several feeds into one
  3200 	 * Merge items from several feeds into one
  3035 	 *
  3201 	 *
  3058 				{
  3224 				{
  3059 					trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  3225 					trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
  3060 				}
  3226 				}
  3061 			}
  3227 			}
  3062 
  3228 
  3063 			$do_sort = true;
  3229 			usort($items, array(get_class($urls[0]), 'sort_items'));
  3064 			foreach ($items as $item)
       
  3065 			{
       
  3066 				if (!$item->get_date('U'))
       
  3067 				{
       
  3068 					$do_sort = false;
       
  3069 					break;
       
  3070 				}
       
  3071 			}
       
  3072 			$item = null;
       
  3073 			if ($do_sort)
       
  3074 			{
       
  3075 				usort($items, array(get_class($urls[0]), 'sort_items'));
       
  3076 			}
       
  3077 
  3230 
  3078 			if ($end === 0)
  3231 			if ($end === 0)
  3079 			{
  3232 			{
  3080 				return array_slice($items, $start);
  3233 				return array_slice($items, $start);
  3081 			}
  3234 			}
       
  3235 
       
  3236 			return array_slice($items, $start, $end);
       
  3237 		}
       
  3238 
       
  3239 		trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
       
  3240 		return array();
       
  3241 	}
       
  3242 
       
  3243 	/**
       
  3244 	 * Store PubSubHubbub links as headers
       
  3245 	 *
       
  3246 	 * There is no way to find PuSH links in the body of a microformats feed,
       
  3247 	 * so they are added to the headers when found, to be used later by get_links.
       
  3248 	 * @param SimplePie_File $file
       
  3249 	 * @param string $hub
       
  3250 	 * @param string $self
       
  3251 	 */
       
  3252 	private function store_links(&$file, $hub, $self) {
       
  3253 		if (isset($file->headers['link']['hub']) ||
       
  3254 			  (isset($file->headers['link']) &&
       
  3255 			   preg_match('/rel=hub/', $file->headers['link'])))
       
  3256 		{
       
  3257 			return;
       
  3258 		}
       
  3259 
       
  3260 		if ($hub)
       
  3261 		{
       
  3262 			if (isset($file->headers['link']))
       
  3263 			{
       
  3264 				if ($file->headers['link'] !== '')
       
  3265 				{
       
  3266 					$file->headers['link'] = ', ';
       
  3267 				}
       
  3268 			}
  3082 			else
  3269 			else
  3083 			{
  3270 			{
  3084 				return array_slice($items, $start, $end);
  3271 				$file->headers['link'] = '';
  3085 			}
  3272 			}
  3086 		}
  3273 			$file->headers['link'] .= '<'.$hub.'>; rel=hub';
  3087 		else
  3274 			if ($self)
  3088 		{
  3275 			{
  3089 			trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
  3276 				$file->headers['link'] .= ', <'.$self.'>; rel=self';
  3090 			return array();
  3277 			}
  3091 		}
  3278 		}
  3092 	}
  3279 	}
  3093 }
  3280 }
  3094 endif;
  3281 endif;