Merge branch 'wip-MDL-56001-master' of git://github.com/abgreeve/moodle

This commit is contained in:
Dan Poltawski 2016-10-04 12:42:25 +01:00
commit a553501042
37 changed files with 1313 additions and 365 deletions

460
lib/simplepie/library/SimplePie.php Normal file → Executable file
View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @version 1.4.1
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -50,7 +50,7 @@ define('SIMPLEPIE_NAME', 'SimplePie');
/** /**
* SimplePie Version * SimplePie Version
*/ */
define('SIMPLEPIE_VERSION', '1.3.1'); define('SIMPLEPIE_VERSION', '1.4.1');
/** /**
* SimplePie Build * SimplePie Build
@ -445,6 +445,13 @@ class SimplePie
*/ */
public $feed_url; public $feed_url;
/**
* @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently
* @see SimplePie::subscribe_url()
* @access private
*/
public $permanent_url = null;
/** /**
* @var object Instance of SimplePie_File to use as a feed * @var object Instance of SimplePie_File to use as a feed
* @see SimplePie::set_file() * @see SimplePie::set_file()
@ -466,6 +473,13 @@ class SimplePie
*/ */
public $timeout = 10; public $timeout = 10;
/**
* @var array Custom curl options
* @see SimplePie::set_curl_options()
* @access private
*/
public $curl_options = array();
/** /**
* @var bool Forces fsockopen() to be used for remote files instead * @var bool Forces fsockopen() to be used for remote files instead
* of cURL, even if a new enough version is installed * of cURL, even if a new enough version is installed
@ -489,6 +503,14 @@ class SimplePie
*/ */
public $cache = true; public $cache = true;
/**
* @var bool Force SimplePie to fallback to expired cache, if enabled,
* when feed is unavailable.
* @see SimplePie::force_cache_fallback()
* @access private
*/
public $force_cache_fallback = false;
/** /**
* @var int Cache duration (in seconds) * @var int Cache duration (in seconds)
* @see SimplePie::set_cache_duration() * @see SimplePie::set_cache_duration()
@ -594,6 +616,12 @@ class SimplePie
*/ */
public $item_limit = 0; public $item_limit = 0;
/**
* @var bool Stores if last-modified and/or etag headers were sent with the
* request when checking a feed.
*/
public $check_modified = false;
/** /**
* @var array Stores the default attributes to be stripped by strip_attributes(). * @var array Stores the default attributes to be stripped by strip_attributes().
* @see SimplePie::strip_attributes() * @see SimplePie::strip_attributes()
@ -601,6 +629,13 @@ class SimplePie
*/ */
public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
/**
* @var array Stores the default attributes to add to different tags by add_attributes().
* @see SimplePie::add_attributes()
* @access private
*/
public $add_attributes = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none'));
/** /**
* @var array Stores the default tags to be stripped by strip_htmltags(). * @var array Stores the default tags to be stripped by strip_htmltags().
* @see SimplePie::strip_htmltags() * @see SimplePie::strip_htmltags()
@ -637,7 +672,7 @@ class SimplePie
if (func_num_args() > 0) if (func_num_args() > 0)
{ {
$level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING; $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
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); 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);
$args = func_get_args(); $args = func_get_args();
switch (count($args)) { switch (count($args)) {
@ -728,6 +763,7 @@ class SimplePie
else else
{ {
$this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1)); $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
$this->permanent_url = $this->feed_url;
} }
} }
@ -742,6 +778,7 @@ class SimplePie
if ($file instanceof SimplePie_File) if ($file instanceof SimplePie_File)
{ {
$this->feed_url = $file->url; $this->feed_url = $file->url;
$this->permanent_url = $this->feed_url;
$this->file =& $file; $this->file =& $file;
return true; return true;
} }
@ -780,6 +817,19 @@ class SimplePie
$this->timeout = (int) $timeout; $this->timeout = (int) $timeout;
} }
/**
* Set custom curl options
*
* This allows you to change default curl options
*
* @since 1.0 Beta 3
* @param array $curl_options Curl options to add to default settings
*/
public function set_curl_options(array $curl_options = array())
{
$this->curl_options = $curl_options;
}
/** /**
* Force SimplePie to use fsockopen() instead of cURL * Force SimplePie to use fsockopen() instead of cURL
* *
@ -805,6 +855,21 @@ class SimplePie
$this->cache = (bool) $enable; $this->cache = (bool) $enable;
} }
/**
* SimplePie to continue to fall back to expired cache, if enabled, when
* feed is unavailable.
*
* This tells SimplePie to ignore any file errors and fall back to cache
* instead. This only works if caching is enabled and cached content
* still exists.
* @param bool $enable Force use of cache on fail.
*/
public function force_cache_fallback($enable = false)
{
$this->force_cache_fallback= (bool) $enable;
}
/** /**
* Set the length of time (in seconds) that the contents of a feed will be * Set the length of time (in seconds) that the contents of a feed will be
* cached * cached
@ -1073,6 +1138,7 @@ class SimplePie
$this->strip_comments(false); $this->strip_comments(false);
$this->strip_htmltags(false); $this->strip_htmltags(false);
$this->strip_attributes(false); $this->strip_attributes(false);
$this->add_attributes(false);
$this->set_image_handler(false); $this->set_image_handler(false);
} }
} }
@ -1119,16 +1185,25 @@ class SimplePie
$this->sanitize->strip_attributes($attribs); $this->sanitize->strip_attributes($attribs);
} }
public function add_attributes($attribs = '')
{
if ($attribs === '')
{
$attribs = $this->add_attributes;
}
$this->sanitize->add_attributes($attribs);
}
/** /**
* Set the output encoding * Set the output encoding
* *
* Allows you to override SimplePie's output to match that of your webpage. * Allows you to override SimplePie's output to match that of your webpage.
* This is useful for times when your webpages are not being served as * This is useful for times when your webpages are not being served as
* UTF-8. This setting will be obeyed by {@see handle_content_type()}, and * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
* is similar to {@see set_input_encoding()}. * is similar to {@see set_input_encoding()}.
* *
* It should be noted, however, that not all character encodings can support * It should be noted, however, that not all character encodings can support
* all characters. If your page is being served as ISO-8859-1 and you try * all characters. If your page is being served as ISO-8859-1 and you try
* to display a Japanese feed, you'll likely see garbled characters. * to display a Japanese feed, you'll likely see garbled characters.
* Because of this, it is highly recommended to ensure that your webpages * Because of this, it is highly recommended to ensure that your webpages
* are served as UTF-8. * are served as UTF-8.
@ -1195,10 +1270,20 @@ class SimplePie
$this->item_limit = (int) $limit; $this->item_limit = (int) $limit;
} }
/**
* Enable throwing exceptions
*
* @param boolean $enable Should we throw exceptions, or use the old-style error property?
*/
public function enable_exceptions($enable = true)
{
$this->enable_exceptions = $enable;
}
/** /**
* Initialize the feed object * Initialize the feed object
* *
* This is what makes everything happen. Period. This is where all of the * This is what makes everything happen. Period. This is where all of the
* configuration options get processed, feeds are fetched, cached, and * configuration options get processed, feeds are fetched, cached, and
* parsed, and all of that other good stuff. * parsed, and all of that other good stuff.
* *
@ -1236,7 +1321,7 @@ class SimplePie
// Pass whatever was set with config options over to the sanitizer. // Pass whatever was set with config options over to the sanitizer.
// Pass the classes in for legacy support; new classes should use the registry instead // Pass the classes in for legacy support; new classes should use the registry instead
$this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache')); $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
$this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen); $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen, $this->curl_options);
if (!empty($this->multifeed_url)) if (!empty($this->multifeed_url))
{ {
@ -1265,6 +1350,7 @@ class SimplePie
$this->error = null; $this->error = null;
$this->data = array(); $this->data = array();
$this->check_modified = false;
$this->multifeed_objects = array(); $this->multifeed_objects = array();
$cache = false; $cache = false;
@ -1296,7 +1382,7 @@ class SimplePie
// First check to see if input has been overridden. // First check to see if input has been overridden.
if ($this->input_encoding !== false) if ($this->input_encoding !== false)
{ {
$encodings[] = $this->input_encoding; $encodings[] = strtoupper($this->input_encoding);
} }
$application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
@ -1318,14 +1404,14 @@ class SimplePie
{ {
if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
{ {
$encodings[] = $charset[1]; $encodings[] = strtoupper($charset[1]);
} }
$encodings[] = 'US-ASCII'; $encodings[] = 'US-ASCII';
} }
// Text MIME-type default // Text MIME-type default
elseif (substr($sniffed, 0, 5) === 'text/') elseif (substr($sniffed, 0, 5) === 'text/')
{ {
$encodings[] = 'US-ASCII'; $encodings[] = 'UTF-8';
} }
} }
@ -1347,7 +1433,7 @@ class SimplePie
$parser = $this->registry->create('Parser'); $parser = $this->registry->create('Parser');
// If it's parsed fine // If it's parsed fine
if ($parser->parse($utf8_data, 'UTF-8')) if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url))
{ {
$this->data = $parser->get_data(); $this->data = $parser->get_data();
if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE)) if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
@ -1376,7 +1462,8 @@ class SimplePie
if (isset($parser)) if (isset($parser))
{ {
// We have an error, just set SimplePie_Misc::error to it and quit // We have an error, just set SimplePie_Misc::error to it and quit
$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()); $this->error = $this->feed_url;
$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());
} }
else else
{ {
@ -1436,7 +1523,10 @@ class SimplePie
// Check if the cache has been updated // Check if the cache has been updated
elseif ($cache->mtime() + $this->cache_duration < time()) elseif ($cache->mtime() + $this->cache_duration < time())
{ {
// If we have last-modified and/or etag set // Want to know if we tried to send last-modified and/or etag headers
// when requesting this file. (Note that it's up to the file to
// support this, but we don't always send the headers either.)
$this->check_modified = true;
if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
{ {
$headers = array( $headers = array(
@ -1451,18 +1541,28 @@ class SimplePie
$headers['if-none-match'] = $this->data['headers']['etag']; $headers['if-none-match'] = $this->data['headers']['etag'];
} }
$file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen)); $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
if ($file->success) if ($file->success)
{ {
if ($file->status_code === 304) if ($file->status_code === 304)
{ {
// Set raw_data to false here too, to signify that the cache
// is still valid.
$this->raw_data = false;
$cache->touch(); $cache->touch();
return true; return true;
} }
} }
else else
{ {
$this->check_modified = false;
if($this->force_cache_fallback)
{
$cache->touch();
return true;
}
unset($file); unset($file);
} }
} }
@ -1493,7 +1593,7 @@ class SimplePie
$headers = array( $headers = array(
'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', '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',
); );
$file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen)); $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
} }
} }
// If the file connection has an error, set SimplePie::error to that and quit // If the file connection has an error, set SimplePie::error to that and quit
@ -1510,19 +1610,75 @@ class SimplePie
if (!$locate->is_feed($file)) if (!$locate->is_feed($file))
{ {
// We need to unset this so that if SimplePie::set_file() has been called that object is untouched $copyStatusCode = $file->status_code;
unset($file); $copyContentType = $file->headers['content-type'];
try try
{ {
if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))) $microformats = false;
if (function_exists('Mf2\parse')) {
// Check for both h-feed and h-entry, as both a feed with no entries
// and a list of entries without an h-feed wrapper are both valid.
$position = 0;
while ($position = strpos($file->body, 'h-feed', $position))
{
$start = $position < 200 ? 0 : $position - 200;
$check = substr($file->body, $start, 400);
if ($microformats = preg_match('/class="[^"]*h-feed/', $check))
{
break;
}
$position += 7;
}
$position = 0;
while ($position = strpos($file->body, 'h-entry', $position))
{
$start = $position < 200 ? 0 : $position - 200;
$check = substr($file->body, $start, 400);
if ($microformats = preg_match('/class="[^"]*h-entry/', $check))
{
break;
}
$position += 7;
}
}
// Now also do feed discovery, but if an h-entry was found don't
// overwrite the current value of file.
$discovered = $locate->find($this->autodiscovery,
$this->all_discovered_feeds);
if ($microformats)
{ {
$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."; if ($hub = $locate->get_rel_link('hub'))
$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__)); {
return false; $self = $locate->get_rel_link('self');
$this->store_links($file, $hub, $self);
}
// Push the current file onto all_discovered feeds so the user can
// be shown this as one of the options.
if (isset($this->all_discovered_feeds)) {
$this->all_discovered_feeds[] = $file;
}
}
else
{
if ($discovered)
{
$file = $discovered;
}
else
{
// We need to unset this so that if SimplePie::set_file() has
// been called that object is untouched
unset($file);
$this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`";
$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
return false;
}
} }
} }
catch (SimplePie_Exception $e) catch (SimplePie_Exception $e)
{ {
// We need to unset this so that if SimplePie::set_file() has been called that object is untouched
unset($file);
// This is usually because DOMDocument doesn't exist // This is usually because DOMDocument doesn't exist
$this->error = $e->getMessage(); $this->error = $e->getMessage();
$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine())); $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
@ -1543,7 +1699,7 @@ class SimplePie
} }
$this->raw_data = $file->body; $this->raw_data = $file->body;
$this->permanent_url = $file->permanent_url;
$headers = $file->headers; $headers = $file->headers;
$sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file)); $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
$sniffed = $sniffer->get_type(); $sniffed = $sniffer->get_type();
@ -1729,26 +1885,44 @@ class SimplePie
/** /**
* Get the URL for the feed * Get the URL for the feed
*
* When the 'permanent' mode is enabled, returns the original feed URL,
* except in the case of an `HTTP 301 Moved Permanently` status response,
* in which case the location of the first redirection is returned.
* *
* May or may not be different from the URL passed to {@see set_feed_url()}, * When the 'permanent' mode is disabled (default),
* may or may not be different from the URL passed to {@see set_feed_url()},
* depending on whether auto-discovery was used. * depending on whether auto-discovery was used.
* *
* @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.) * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
* @todo If we have a perm redirect we should return the new URL * @todo Support <itunes:new-feed-url>
* @todo When we make the above change, let's support <itunes:new-feed-url> as well
* @todo Also, |atom:link|@rel=self * @todo Also, |atom:link|@rel=self
* @param bool $permanent Permanent mode to return only the original URL or the first redirection
* iff it is a 301 redirection
* @return string|null * @return string|null
*/ */
public function subscribe_url() public function subscribe_url($permanent = false)
{ {
if ($this->feed_url !== null) if ($permanent)
{ {
return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); if ($this->permanent_url !== null)
{
// sanitize encodes ampersands which are required when used in a url.
return str_replace('&amp;', '&',
$this->sanitize($this->permanent_url,
SIMPLEPIE_CONSTRUCT_IRI));
}
} }
else else
{ {
return null; if ($this->feed_url !== null)
{
return str_replace('&amp;', '&',
$this->sanitize($this->feed_url,
SIMPLEPIE_CONSTRUCT_IRI));
}
} }
return null;
} }
/** /**
@ -1963,7 +2137,21 @@ class SimplePie
*/ */
public function sanitize($data, $type, $base = '') public function sanitize($data, $type, $base = '')
{ {
return $this->sanitize->sanitize($data, $type, $base); try
{
return $this->sanitize->sanitize($data, $type, $base);
}
catch (SimplePie_Exception $e)
{
if (!$this->enable_exceptions)
{
$this->error = $e->getMessage();
$this->registry->call('Misc', 'error', array($this->error, E_USER_WARNING, $e->getFile(), $e->getLine()));
return '';
}
throw $e;
}
} }
/** /**
@ -2014,7 +2202,7 @@ class SimplePie
* Get a category for the feed * Get a category for the feed
* *
* @since Unknown * @since Unknown
* @param int $key The category that you want to return. Remember that arrays begin with 0, not 1 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
* @return SimplePie_Category|null * @return SimplePie_Category|null
*/ */
public function get_category($key = 0) public function get_category($key = 0)
@ -2099,7 +2287,7 @@ class SimplePie
* Get an author for the feed * Get an author for the feed
* *
* @since 1.1 * @since 1.1
* @param int $key The author that you want to return. Remember that arrays begin with 0, not 1 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
* @return SimplePie_Author|null * @return SimplePie_Author|null
*/ */
public function get_author($key = 0) public function get_author($key = 0)
@ -2197,7 +2385,7 @@ class SimplePie
* Get a contributor for the feed * Get a contributor for the feed
* *
* @since 1.1 * @since 1.1
* @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
* @return SimplePie_Author|null * @return SimplePie_Author|null
*/ */
public function get_contributor($key = 0) public function get_contributor($key = 0)
@ -2283,7 +2471,7 @@ class SimplePie
* Get a single link for the feed * Get a single link for the feed
* *
* @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8) * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
* @param int $key The link that you want to return. Remember that arrays begin with 0, not 1 * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
* @param string $rel The relationship of the link to return * @param string $rel The relationship of the link to return
* @return string|null Link URL * @return string|null Link URL
*/ */
@ -2393,6 +2581,12 @@ class SimplePie
{ {
return $this->data['links'][$rel]; return $this->data['links'][$rel];
} }
else if (isset($this->data['headers']['link']) &&
preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
$this->data['headers']['link'], $match))
{
return array($match[1]);
}
else else
{ {
return null; return null;
@ -2794,7 +2988,7 @@ class SimplePie
* *
* @see get_item_quantity() * @see get_item_quantity()
* @since Beta 2 * @since Beta 2
* @param int $key The item that you want to return. Remember that arrays begin with 0, not 1 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
* @return SimplePie_Item|null * @return SimplePie_Item|null
*/ */
public function get_item($key = 0) public function get_item($key = 0)
@ -2821,7 +3015,7 @@ class SimplePie
* @since Beta 2 * @since Beta 2
* @param int $start Index to start at * @param int $start Index to start at
* @param int $end Number of items to return. 0 for all items after `$start` * @param int $end Number of items to return. 0 for all items after `$start`
* @return array|null List of {@see SimplePie_Item} objects * @return SimplePie_Item[]|null List of {@see SimplePie_Item} objects
*/ */
public function get_items($start = 0, $end = 0) public function get_items($start = 0, $end = 0)
{ {
@ -2830,96 +3024,81 @@ class SimplePie
if (!empty($this->multifeed_objects)) if (!empty($this->multifeed_objects))
{ {
$this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
if (empty($this->data['items']))
{
return array();
}
return $this->data['items'];
} }
else $this->data['items'] = array();
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
{ {
$this->data['items'] = array(); $keys = array_keys($items);
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) foreach ($keys as $key)
{ {
$keys = array_keys($items); $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
foreach ($keys as $key)
{
$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
}
} }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
{
$keys = array_keys($items);
foreach ($keys as $key)
{ {
$keys = array_keys($items); $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
foreach ($keys as $key)
{
$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
}
} }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
{
$keys = array_keys($items);
foreach ($keys as $key)
{ {
$keys = array_keys($items); $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
foreach ($keys as $key)
{
$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
}
} }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) }
if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
{
$keys = array_keys($items);
foreach ($keys as $key)
{ {
$keys = array_keys($items); $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
foreach ($keys as $key)
{
$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
}
} }
if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item')) }
if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
{
$keys = array_keys($items);
foreach ($keys as $key)
{ {
$keys = array_keys($items); $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
foreach ($keys as $key)
{
$this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
}
} }
} }
} }
if (!empty($this->data['items'])) if (empty($this->data['items']))
{ {
// If we want to order it by date, check if all items have a date, and then sort it return array();
if ($this->order_by_date && empty($this->multifeed_objects)) }
{
if (!isset($this->data['ordered_items']))
{
$do_sort = true;
foreach ($this->data['items'] as $item)
{
if (!$item->get_date('U'))
{
$do_sort = false;
break;
}
}
$item = null;
$this->data['ordered_items'] = $this->data['items'];
if ($do_sort)
{
usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
}
}
$items = $this->data['ordered_items'];
}
else
{
$items = $this->data['items'];
}
// Slice the data as desired if ($this->order_by_date)
if ($end === 0) {
if (!isset($this->data['ordered_items']))
{ {
return array_slice($items, $start); $this->data['ordered_items'] = $this->data['items'];
} usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
else }
{ $items = $this->data['ordered_items'];
return array_slice($items, $start, $end);
}
} }
else else
{ {
return array(); $items = $this->data['items'];
}
// Slice the data as desired
if ($end === 0)
{
return array_slice($items, $start);
}
else
{
return array_slice($items, $start, $end);
} }
} }
@ -2992,7 +3171,19 @@ class SimplePie
*/ */
public static function sort_items($a, $b) public static function sort_items($a, $b)
{ {
return $a->get_date('U') <= $b->get_date('U'); $a_date = $a->get_date('U');
$b_date = $b->get_date('U');
if ($a_date && $b_date) {
return $a_date > $b_date ? -1 : 1;
}
// Sort items without dates to the top.
if ($a_date) {
return 1;
}
if ($b_date) {
return -1;
}
return 0;
} }
/** /**
@ -3025,20 +3216,7 @@ class SimplePie
} }
} }
$do_sort = true; usort($items, array(get_class($urls[0]), 'sort_items'));
foreach ($items as $item)
{
if (!$item->get_date('U'))
{
$do_sort = false;
break;
}
}
$item = null;
if ($do_sort)
{
usort($items, array(get_class($urls[0]), 'sort_items'));
}
if ($end === 0) if ($end === 0)
{ {
@ -3055,4 +3233,42 @@ class SimplePie
return array(); return array();
} }
} }
/**
* Store PubSubHubbub links as headers
*
* There is no way to find PuSH links in the body of a microformats feed,
* so they are added to the headers when found, to be used later by get_links.
* @param SimplePie_File $file
* @param string $hub
* @param string $self
*/
private function store_links(&$file, $hub, $self) {
if (isset($file->headers['link']['hub']) ||
(isset($file->headers['link']) &&
preg_match('/rel=hub/', $file->headers['link'])))
{
return;
}
if ($hub)
{
if (isset($file->headers['link']))
{
if ($file->headers['link'] !== '')
{
$file->headers['link'] = ', ';
}
}
else
{
$file->headers['link'] = '';
}
$file->headers['link'] .= '<'.$hub.'>; rel=hub';
if ($self)
{
$file->headers['link'] .= ', <'.$self.'>; rel=self';
}
}
}
} }

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -62,8 +61,10 @@ class SimplePie_Cache
* @var array * @var array
*/ */
protected static $handlers = array( protected static $handlers = array(
'mysql' => 'SimplePie_Cache_MySQL', 'mysql' => 'SimplePie_Cache_MySQL',
'memcache' => 'SimplePie_Cache_Memcache', 'memcache' => 'SimplePie_Cache_Memcache',
'memcached' => 'SimplePie_Cache_Memcached',
'redis' => 'SimplePie_Cache_Redis'
); );
/** /**

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -136,11 +135,7 @@ class SimplePie_Cache_File implements SimplePie_Cache_Base
*/ */
public function mtime() public function mtime()
{ {
if (file_exists($this->name)) return @filemtime($this->name);
{
return filemtime($this->name);
}
return false;
} }
/** /**
@ -150,11 +145,7 @@ class SimplePie_Cache_File implements SimplePie_Cache_Base
*/ */
public function touch() public function touch()
{ {
if (file_exists($this->name)) return @touch($this->name);
{
return touch($this->name);
}
return false;
} }
/** /**

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -95,10 +94,8 @@ class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
'prefix' => 'simplepie_', 'prefix' => 'simplepie_',
), ),
); );
$parsed = SimplePie_Cache::parse_URL($location); $this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
$this->options['host'] = empty($parsed['host']) ? $this->options['host'] : $parsed['host'];
$this->options['port'] = empty($parsed['port']) ? $this->options['port'] : $parsed['port'];
$this->options['extras'] = array_merge($this->options['extras'], $parsed['extras']);
$this->name = $this->options['extras']['prefix'] . md5("$name:$type"); $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
$this->cache = new Memcache(); $this->cache = new Memcache();
@ -147,7 +144,7 @@ class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
if ($data !== false) if ($data !== false)
{ {
// essentially ignore the mtime because Memcache expires on it's own // essentially ignore the mtime because Memcache expires on its own
return time(); return time();
} }
@ -165,7 +162,7 @@ class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
if ($data !== false) if ($data !== false)
{ {
return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration); return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
} }
return false; return false;

View file

@ -0,0 +1,166 @@
<?php
/**
* SimplePie
*
* A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution.
*
* Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package SimplePie
* @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman
* @author Geoffrey Sneddon
* @author Ryan McCue
* @link http://simplepie.org/ SimplePie
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
/**
* Caches data to memcached
*
* Registered for URLs with the "memcached" protocol
*
* For example, `memcached://localhost:11211/?timeout=3600&prefix=sp_` will
* connect to memcached on `localhost` on port 11211. All tables will be
* prefixed with `sp_` and data will expire after 3600 seconds
*
* @package SimplePie
* @subpackage Caching
* @author Paul L. McNeely
* @uses Memcached
*/
class SimplePie_Cache_Memcached implements SimplePie_Cache_Base
{
/**
* Memcached instance
* @var Memcached
*/
protected $cache;
/**
* Options
* @var array
*/
protected $options;
/**
* Cache name
* @var string
*/
protected $name;
/**
* Create a new cache object
* @param string $location Location string (from SimplePie::$cache_location)
* @param string $name Unique ID for the cache
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
*/
public function __construct($location, $name, $type) {
$this->options = array(
'host' => '127.0.0.1',
'port' => 11211,
'extras' => array(
'timeout' => 3600, // one hour
'prefix' => 'simplepie_',
),
);
$this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
$this->name = $this->options['extras']['prefix'] . md5("$name:$type");
$this->cache = new Memcached();
$this->cache->addServer($this->options['host'], (int)$this->options['port']);
}
/**
* Save data to the cache
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
* @return bool Successfulness
*/
public function save($data) {
if ($data instanceof SimplePie) {
$data = $data->data;
}
return $this->setData(serialize($data));
}
/**
* Retrieve the data saved to the cache
* @return array Data for SimplePie::$data
*/
public function load() {
$data = $this->cache->get($this->name);
if ($data !== false) {
return unserialize($data);
}
return false;
}
/**
* Retrieve the last modified time for the cache
* @return int Timestamp
*/
public function mtime() {
$data = $this->cache->get($this->name . '_mtime');
return (int) $data;
}
/**
* Set the last modified time to the current time
* @return bool Success status
*/
public function touch() {
$data = $this->cache->get($this->name);
return $this->setData($data);
}
/**
* Remove the cache
* @return bool Success status
*/
public function unlink() {
return $this->cache->delete($this->name, 0);
}
/**
* Set the last modified time and data to Memcached
* @return bool Success status
*/
private function setData($data) {
if ($data !== false) {
$this->cache->set($this->name . '_mtime', time(), (int)$this->options['extras']['timeout']);
return $this->cache->set($this->name, $data, (int)$this->options['extras']['timeout']);
}
return false;
}
}

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -94,9 +93,11 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
'path' => '', 'path' => '',
'extras' => array( 'extras' => array(
'prefix' => '', 'prefix' => '',
'cache_purge_time' => 2592000
), ),
); );
$this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
$this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
// Path is prefixed with a "/" // Path is prefixed with a "/"
$this->options['dbname'] = substr($this->options['path'], 1); $this->options['dbname'] = substr($this->options['path'], 1);
@ -130,16 +131,20 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'); $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
if ($query === false) if ($query === false)
{ {
trigger_error("Can't create " . $this->options['extras']['prefix'] . "cache_data table, check permissions", E_USER_WARNING);
$this->mysql = null; $this->mysql = null;
return;
} }
} }
if (!in_array($this->options['extras']['prefix'] . 'items', $db)) if (!in_array($this->options['extras']['prefix'] . 'items', $db))
{ {
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'); $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` MEDIUMBLOB NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
if ($query === false) if ($query === false)
{ {
trigger_error("Can't create " . $this->options['extras']['prefix'] . "items table, check permissions", E_USER_WARNING);
$this->mysql = null; $this->mysql = null;
return;
} }
} }
} }
@ -157,6 +162,17 @@ class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
return false; return false;
} }
$query = $this->mysql->prepare('DELETE i, cd FROM `' . $this->options['extras']['prefix'] . 'cache_data` cd, ' .
'`' . $this->options['extras']['prefix'] . 'items` i ' .
'WHERE cd.id = i.feed_id ' .
'AND cd.mtime < (unix_timestamp() - :purge_time)');
$query->bindValue(':purge_time', $this->options['extras']['cache_purge_time']);
if (!$query->execute())
{
return false;
}
if ($data instanceof SimplePie) if ($data instanceof SimplePie)
{ {
$data = clone $data; $data = clone $data;

View file

@ -0,0 +1,166 @@
<?php
/**
* SimplePie Redis Cache Extension
*
* @package SimplePie
* @author Jan Kozak <galvani78@gmail.com>
* @link http://galvani.cz/
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version 0.2.9
*/
/**
* Caches data to redis
*
* Registered for URLs with the "redis" protocol
*
* For example, `redis://localhost:6379/?timeout=3600&prefix=sp_&dbIndex=0` will
* connect to redis on `localhost` on port 6379. All tables will be
* prefixed with `simple_primary-` and data will expire after 3600 seconds
*
* @package SimplePie
* @subpackage Caching
* @uses Redis
*/
class SimplePie_Cache_Redis implements SimplePie_Cache_Base {
/**
* Redis instance
*
* @var \Redis
*/
protected $cache;
/**
* Options
*
* @var array
*/
protected $options;
/**
* Cache name
*
* @var string
*/
protected $name;
/**
* Cache Data
*
* @var type
*/
protected $data;
/**
* Create a new cache object
*
* @param string $location Location string (from SimplePie::$cache_location)
* @param string $name Unique ID for the cache
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
*/
public function __construct($location, $name, $options = null) {
//$this->cache = \flow\simple\cache\Redis::getRedisClientInstance();
$parsed = SimplePie_Cache::parse_URL($location);
$redis = new Redis();
$redis->connect($parsed['host'], $parsed['port']);
$this->cache = $redis;
if (!is_null($options) && is_array($options)) {
$this->options = $options;
} else {
$this->options = array (
'prefix' => 'rss:simple_primary:',
'expire' => 0,
);
}
$this->name = $this->options['prefix'] . $name;
}
/**
* @param \Redis $cache
*/
public function setRedisClient(\Redis $cache) {
$this->cache = $cache;
}
/**
* Save data to the cache
*
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
* @return bool Successfulness
*/
public function save($data) {
if ($data instanceof SimplePie) {
$data = $data->data;
}
$response = $this->cache->set($this->name, serialize($data));
if ($this->options['expire']) {
$this->cache->expire($this->name, $this->options['expire']);
}
return $response;
}
/**
* Retrieve the data saved to the cache
*
* @return array Data for SimplePie::$data
*/
public function load() {
$data = $this->cache->get($this->name);
if ($data !== false) {
return unserialize($data);
}
return false;
}
/**
* Retrieve the last modified time for the cache
*
* @return int Timestamp
*/
public function mtime() {
$data = $this->cache->get($this->name);
if ($data !== false) {
return time();
}
return false;
}
/**
* Set the last modified time to the current time
*
* @return bool Success status
*/
public function touch() {
$data = $this->cache->get($this->name);
if ($data !== false) {
$return = $this->cache->set($this->name, $data);
if ($this->options['expire']) {
return $this->cache->expire($this->name, $this->ttl);
}
return $return;
}
return false;
}
/**
* Remove the cache
*
* @return bool Success status
*/
public function unlink() {
return $this->cache->set($this->name, null);
}
}

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -169,7 +168,6 @@ class SimplePie_Decode_HTML_Entities
case "\x09": case "\x09":
case "\x0A": case "\x0A":
case "\x0B": case "\x0B":
case "\x0B":
case "\x0C": case "\x0C":
case "\x20": case "\x20":
case "\x3C": case "\x3C":

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -451,7 +450,7 @@ class SimplePie_Enclosure
/** /**
* Get the duration of the enclosure * Get the duration of the enclosure
* *
* @param string $convert Convert seconds into hh:mm:ss * @param bool $convert Convert seconds into hh:mm:ss
* @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found) * @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found)
*/ */
public function get_duration($convert = false) public function get_duration($convert = false)
@ -942,7 +941,7 @@ class SimplePie_Enclosure
* - `height` (integer): The height of the embedded media. Accepts any * - `height` (integer): The height of the embedded media. Accepts any
* numeric pixel value (such as `360`) or `auto`. Defaults to `auto`, * numeric pixel value (such as `360`) or `auto`. Defaults to `auto`,
* and it is recommended that you use this default. * and it is recommended that you use this default.
* - `loop` (boolean): Do you want the media to loop when its done? * - `loop` (boolean): Do you want the media to loop when it's done?
* Defaults to `false`. * Defaults to `false`.
* - `mediaplayer` (string): The location of the included * - `mediaplayer` (string): The location of the included
* `mediaplayer.swf` file. This allows for the playback of Flash Video * `mediaplayer.swf` file. This allows for the playback of Flash Video

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.4-dev * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -64,8 +63,9 @@ class SimplePie_File
var $redirects = 0; var $redirects = 0;
var $error; var $error;
var $method = SIMPLEPIE_FILE_SOURCE_NONE; var $method = SIMPLEPIE_FILE_SOURCE_NONE;
var $permanent_url;
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $curl_options = array())
{ {
if (class_exists('idna_convert')) if (class_exists('idna_convert'))
{ {
@ -74,6 +74,7 @@ class SimplePie_File
$url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
} }
$this->url = $url; $this->url = $url;
$this->permanent_url = $url;
$this->useragent = $useragent; $this->useragent = $useragent;
if (preg_match('/^http(s)?:\/\//i', $url)) if (preg_match('/^http(s)?:\/\//i', $url))
{ {
@ -102,6 +103,7 @@ class SimplePie_File
curl_setopt($fp, CURLOPT_URL, $url); curl_setopt($fp, CURLOPT_URL, $url);
curl_setopt($fp, CURLOPT_HEADER, 1); curl_setopt($fp, CURLOPT_HEADER, 1);
curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($fp, CURLOPT_FAILONERROR, 1);
curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($fp, CURLOPT_REFERER, $url); curl_setopt($fp, CURLOPT_REFERER, $url);
@ -112,6 +114,9 @@ class SimplePie_File
curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
} }
foreach ($curl_options as $curl_param => $curl_value) {
curl_setopt($fp, $curl_param, $curl_value);
}
$this->headers = curl_exec($fp); $this->headers = curl_exec($fp);
if (curl_errno($fp) === 23 || curl_errno($fp) === 61) if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
@ -126,7 +131,10 @@ class SimplePie_File
} }
else else
{ {
$info = curl_getinfo($fp); // Use the updated url provided by curl_getinfo after any redirects.
if ($info = curl_getinfo($fp)) {
$this->url = $info['url'];
}
curl_close($fp); curl_close($fp);
$this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
$this->headers = array_pop($this->headers); $this->headers = array_pop($this->headers);
@ -134,13 +142,16 @@ class SimplePie_File
if ($parser->parse()) if ($parser->parse())
{ {
$this->headers = $parser->headers; $this->headers = $parser->headers;
$this->body = $parser->body; $this->body = trim($parser->body);
$this->status_code = $parser->status_code; $this->status_code = $parser->status_code;
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
{ {
$this->redirects++; $this->redirects++;
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); $previousStatusCode = $this->status_code;
$this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
$this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
return;
} }
} }
} }
@ -216,13 +227,16 @@ class SimplePie_File
if ($parser->parse()) if ($parser->parse())
{ {
$this->headers = $parser->headers; $this->headers = $parser->headers;
$this->body = $parser->body; $this->body = trim($parser->body);
$this->status_code = $parser->status_code; $this->status_code = $parser->status_code;
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
{ {
$this->redirects++; $this->redirects++;
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); $previousStatusCode = $this->status_code;
$this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
$this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
return;
} }
if (isset($this->headers['content-encoding'])) if (isset($this->headers['content-encoding']))
{ {
@ -239,7 +253,7 @@ class SimplePie_File
} }
else else
{ {
$this->body = $decoder->data; $this->body = trim($decoder->data);
} }
break; break;
@ -282,7 +296,7 @@ class SimplePie_File
else else
{ {
$this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
if (!$this->body = file_get_contents($url)) if (empty($url) || !($this->body = trim(file_get_contents($url))))
{ {
$this->error = 'file_get_contents could not read the file'; $this->error = 'file_get_contents could not read the file';
$this->success = false; $this->success = false;

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -259,6 +258,15 @@ class SimplePie_IRI
$this->set_iri($iri); $this->set_iri($iri);
} }
/**
* Clean up
*/
public function __destruct() {
$this->set_iri(null, true);
$this->set_path(null, true);
$this->set_authority(null, true);
}
/** /**
* Create a new IRI object by resolving a relative IRI * Create a new IRI object by resolving a relative IRI
* *
@ -768,24 +776,20 @@ class SimplePie_IRI
*/ */
public function is_valid() public function is_valid()
{ {
$isauthority = $this->iuserinfo !== null || $this->ihost !== null || $this->port !== null; if ($this->ipath === '') return true;
if ($this->ipath !== '' &&
( $isauthority = $this->iuserinfo !== null || $this->ihost !== null ||
$isauthority && ( $this->port !== null;
$this->ipath[0] !== '/' || if ($isauthority && $this->ipath[0] === '/') return true;
substr($this->ipath, 0, 2) === '//'
) || if (!$isauthority && (substr($this->ipath, 0, 2) === '//')) return false;
(
$this->scheme === null && // Relative urls cannot have a colon in the first path segment (and the
!$isauthority && // slashes themselves are not included so skip the first character).
strpos($this->ipath, ':') !== false && if (!$this->scheme && !$isauthority &&
(strpos($this->ipath, '/') === false ? true : strpos($this->ipath, ':') < strpos($this->ipath, '/')) strpos($this->ipath, ':') !== false &&
) strpos($this->ipath, '/', 1) !== false &&
) strpos($this->ipath, ':') < strpos($this->ipath, '/', 1)) return false;
)
{
return false;
}
return true; return true;
} }
@ -797,9 +801,14 @@ class SimplePie_IRI
* @param string $iri * @param string $iri
* @return bool * @return bool
*/ */
public function set_iri($iri) public function set_iri($iri, $clear_cache = false)
{ {
static $cache; static $cache;
if ($clear_cache)
{
$cache = null;
return;
}
if (!$cache) if (!$cache)
{ {
$cache = array(); $cache = array();
@ -879,9 +888,14 @@ class SimplePie_IRI
* @param string $authority * @param string $authority
* @return bool * @return bool
*/ */
public function set_authority($authority) public function set_authority($authority, $clear_cache = false)
{ {
static $cache; static $cache;
if ($clear_cache)
{
$cache = null;
return;
}
if (!$cache) if (!$cache)
$cache = array(); $cache = array();
@ -1049,9 +1063,14 @@ class SimplePie_IRI
* @param string $ipath * @param string $ipath
* @return bool * @return bool
*/ */
public function set_path($ipath) public function set_path($ipath, $clear_cache = false)
{ {
static $cache; static $cache;
if ($clear_cache)
{
$cache = null;
return;
}
if (!$cache) if (!$cache)
{ {
$cache = array(); $cache = array();

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -203,14 +202,13 @@ class SimplePie_Item
* *
* Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
* for RDF. If none of these are supplied (or `$hash` is true), creates an * for RDF. If none of these are supplied (or `$hash` is true), creates an
* MD5 hash based on the permalink and title. If either of those are not * MD5 hash based on the permalink, title and content.
* supplied, creates a hash based on the full feed data.
* *
* @since Beta 2 * @since Beta 2
* @param boolean $hash Should we force using a hash instead of the supplied ID? * @param boolean $hash Should we force using a hash instead of the supplied ID?
* @return string * @return string
*/ */
public function get_id($hash = false) public function get_id($hash = false, $fn = '')
{ {
if (!$hash) if (!$hash)
{ {
@ -238,23 +236,10 @@ class SimplePie_Item
{ {
return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT); return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
} }
elseif (($return = $this->get_permalink()) !== null)
{
return $return;
}
elseif (($return = $this->get_title()) !== null)
{
return $return;
}
}
if ($this->get_permalink() !== null || $this->get_title() !== null)
{
return md5($this->get_permalink() . $this->get_title());
}
else
{
return md5(serialize($this->data));
} }
if ($fn === '' || !is_callable($fn)) $fn = 'md5';
return call_user_func($fn,
$this->get_permalink().$this->get_title().$this->get_content());
} }
/** /**
@ -406,6 +391,30 @@ class SimplePie_Item
return null; return null;
} }
} }
/**
* Get the media:thumbnail of the item
*
* Uses `<media:thumbnail>`
*
*
* @return array|null
*/
public function get_thumbnail()
{
if (!isset($this->data['thumbnail']))
{
if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
{
$this->data['thumbnail'] = $return[0]['attribs'][''];
}
else
{
$this->data['thumbnail'] = null;
}
}
return $this->data['thumbnail'];
}
/** /**
* Get a category for the item * Get a category for the item
@ -433,7 +442,7 @@ class SimplePie_Item
* Uses `<atom:category>`, `<category>` or `<dc:subject>` * Uses `<atom:category>`, `<category>` or `<dc:subject>`
* *
* @since Beta 3 * @since Beta 3
* @return array|null List of {@see SimplePie_Category} objects * @return SimplePie_Category[]|null List of {@see SimplePie_Category} objects
*/ */
public function get_categories() public function get_categories()
{ {
@ -446,15 +455,15 @@ class SimplePie_Item
$label = null; $label = null;
if (isset($category['attribs']['']['term'])) if (isset($category['attribs']['']['term']))
{ {
$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if (isset($category['attribs']['']['scheme'])) if (isset($category['attribs']['']['scheme']))
{ {
$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if (isset($category['attribs']['']['label'])) if (isset($category['attribs']['']['label']))
{ {
$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_HTML);
} }
$categories[] = $this->registry->create('Category', array($term, $scheme, $label)); $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
} }
@ -462,10 +471,10 @@ class SimplePie_Item
{ {
// This is really the label, but keep this as the term also for BC. // This is really the label, but keep this as the term also for BC.
// Label will also work on retrieving because that falls back to term. // Label will also work on retrieving because that falls back to term.
$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML);
if (isset($category['attribs']['']['domain'])) if (isset($category['attribs']['']['domain']))
{ {
$scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_HTML);
} }
else else
{ {
@ -475,11 +484,11 @@ class SimplePie_Item
} }
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
{ {
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
} }
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
{ {
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
} }
if (!empty($categories)) if (!empty($categories))
@ -616,7 +625,7 @@ class SimplePie_Item
$email = null; $email = null;
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
{ {
$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
{ {
@ -624,7 +633,7 @@ class SimplePie_Item
} }
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
{ {
$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if ($name !== null || $email !== null || $uri !== null) if ($name !== null || $email !== null || $uri !== null)
{ {
@ -638,7 +647,7 @@ class SimplePie_Item
$email = null; $email = null;
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
{ {
$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
{ {
@ -646,7 +655,7 @@ class SimplePie_Item
} }
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
{ {
$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
} }
if ($name !== null || $email !== null || $url !== null) if ($name !== null || $email !== null || $url !== null)
{ {
@ -655,19 +664,19 @@ class SimplePie_Item
} }
if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author')) if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
{ {
$authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT))); $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_HTML)));
} }
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
{ {
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
} }
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
{ {
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
} }
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
{ {
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null)); $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
} }
if (!empty($authors)) if (!empty($authors))
@ -738,6 +747,18 @@ class SimplePie_Item
{ {
$this->data['date']['raw'] = $return[0]['data']; $this->data['date']['raw'] = $return[0]['data'];
} }
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
{ {
$this->data['date']['raw'] = $return[0]['data']; $this->data['date']['raw'] = $return[0]['data'];
@ -754,18 +775,6 @@ class SimplePie_Item
{ {
$this->data['date']['raw'] = $return[0]['data']; $this->data['date']['raw'] = $return[0]['data'];
} }
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
{
$this->data['date']['raw'] = $return[0]['data'];
}
if (!empty($this->data['date']['raw'])) if (!empty($this->data['date']['raw']))
{ {
@ -821,7 +830,7 @@ class SimplePie_Item
if (!empty($this->data['updated']['raw'])) if (!empty($this->data['updated']['raw']))
{ {
$parser = $this->registry->call('Parse_Date', 'get'); $parser = $this->registry->call('Parse_Date', 'get');
$this->data['updated']['parsed'] = $parser->parse($this->data['date']['raw']); $this->data['updated']['parsed'] = $parser->parse($this->data['updated']['raw']);
} }
else else
{ {
@ -1080,8 +1089,8 @@ class SimplePie_Item
* *
* @since Beta 2 * @since Beta 2
* @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
* @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists). * @todo If an element exists at a level, but its value is empty, we should fall back to the value from the parent (if it exists).
* @return array|null List of SimplePie_Enclosure items * @return SimplePie_Enclosure[]|null List of SimplePie_Enclosure items
*/ */
public function get_enclosures() public function get_enclosures()
{ {
@ -2658,7 +2667,9 @@ class SimplePie_Item
// PLAYER // PLAYER
if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
{ {
$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
$player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
}
} }
else else
{ {
@ -2733,7 +2744,9 @@ class SimplePie_Item
{ {
foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
{ {
$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); if (isset($thumbnail['attribs']['']['url'])) {
$thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
}
} }
if (is_array($thumbnails)) if (is_array($thumbnails))
{ {

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -121,34 +120,41 @@ class SimplePie_Locator
{ {
if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
{ {
return $working; return $working[0];
} }
if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
{ {
return $working; return $working[0];
} }
if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
{ {
return $working; return $working[0];
} }
if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
{ {
return $working; return $working[0];
} }
} }
return null; return null;
} }
public function is_feed($file) public function is_feed($file, $check_html = false)
{ {
if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
{ {
$sniffer = $this->registry->create('Content_Type_Sniffer', array($file)); $sniffer = $this->registry->create('Content_Type_Sniffer', array($file));
$sniffed = $sniffer->get_type(); $sniffed = $sniffer->get_type();
if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) $mime_types = array('application/rss+xml', 'application/rdf+xml',
'text/rdf', 'application/atom+xml', 'text/xml',
'application/xml', 'application/x-rss+xml');
if ($check_html)
{
$mime_types[] = 'text/html';
}
if (in_array($sniffed, $mime_types))
{ {
return true; return true;
} }
@ -242,14 +248,14 @@ class SimplePie_Locator
continue; continue;
} }
if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href])) if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('text/html', 'application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
{ {
$this->checked_feeds++; $this->checked_feeds++;
$headers = array( $headers = array(
'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', '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',
); );
$feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent)); $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent));
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true))
{ {
$feeds[$href] = $feed; $feeds[$href] = $feed;
} }
@ -275,9 +281,9 @@ class SimplePie_Locator
{ {
$href = trim($link->getAttribute('href')); $href = trim($link->getAttribute('href'));
$parsed = $this->registry->call('Misc', 'parse_url', array($href)); $parsed = $this->registry->call('Misc', 'parse_url', array($href));
if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) if ($parsed['scheme'] === '' || preg_match('/^(https?|feed)?$/i', $parsed['scheme']))
{ {
if ($this->base_location < $link->getLineNo()) if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo())
{ {
$href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base)); $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
} }
@ -312,6 +318,57 @@ class SimplePie_Locator
return null; return null;
} }
public function get_rel_link($rel)
{
if ($this->dom === null)
{
throw new SimplePie_Exception('DOMDocument not found, unable to use '.
'locator');
}
if (!class_exists('DOMXpath'))
{
throw new SimplePie_Exception('DOMXpath not found, unable to use '.
'get_rel_link');
}
$xpath = new DOMXpath($this->dom);
$query = '//a[@rel and @href] | //link[@rel and @href]';
foreach ($xpath->query($query) as $link)
{
$href = trim($link->getAttribute('href'));
$parsed = $this->registry->call('Misc', 'parse_url', array($href));
if ($parsed['scheme'] === '' ||
preg_match('/^https?$/i', $parsed['scheme']))
{
if (method_exists($link, 'getLineNo') &&
$this->base_location < $link->getLineNo())
{
$href =
$this->registry->call('Misc', 'absolutize_url',
array(trim($link->getAttribute('href')),
$this->base));
}
else
{
$href =
$this->registry->call('Misc', 'absolutize_url',
array(trim($link->getAttribute('href')),
$this->http_base));
}
if ($href === false)
{
return null;
}
$rel_values = explode(' ', strtolower($link->getAttribute('rel')));
if (in_array($rel, $rel_values))
{
return $href;
}
}
}
return null;
}
public function extension(&$array) public function extension(&$array)
{ {
foreach ($array as $key => $value) foreach ($array as $key => $value)
@ -330,7 +387,7 @@ class SimplePie_Locator
$feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent)); $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent));
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
{ {
return $feed; return array($feed);
} }
else else
{ {
@ -358,7 +415,7 @@ class SimplePie_Locator
$feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent)); $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent));
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
{ {
return $feed; return array($feed);
} }
else else
{ {

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -124,7 +123,7 @@ class SimplePie_Misc
{ {
$attribs[$j][2] = $attribs[$j][1]; $attribs[$j][2] = $attribs[$j][1];
} }
$return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8'); $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]));
} }
} }
} }
@ -138,7 +137,7 @@ class SimplePie_Misc
foreach ($element['attribs'] as $key => $value) foreach ($element['attribs'] as $key => $value)
{ {
$key = strtolower($key); $key = strtolower($key);
$full .= " $key=\"" . htmlspecialchars($value['data']) . '"'; $full .= " $key=\"" . htmlspecialchars($value['data'], ENT_COMPAT, 'UTF-8') . '"';
} }
if ($element['self_closing']) if ($element['self_closing'])
{ {
@ -224,6 +223,23 @@ class SimplePie_Misc
} }
} }
public static function array_merge_recursive($array1, $array2)
{
foreach ($array2 as $key => $value)
{
if (is_array($value))
{
$array1[$key] = SimplePie_Misc::array_merge_recursive($array1[$key], $value);
}
else
{
$array1[$key] = $value;
}
}
return $array1;
}
public static function parse_url($url) public static function parse_url($url)
{ {
$iri = new SimplePie_IRI($url); $iri = new SimplePie_IRI($url);

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -173,7 +172,7 @@ class SimplePie_Parse_Date
'aug' => 8, 'aug' => 8,
'august' => 8, 'august' => 8,
'sep' => 9, 'sep' => 9,
'september' => 8, 'september' => 9,
'oct' => 10, 'oct' => 10,
'october' => 10, 'october' => 10,
'nov' => 11, 'nov' => 11,
@ -331,6 +330,7 @@ class SimplePie_Parse_Date
'CCT' => 23400, 'CCT' => 23400,
'CDT' => -18000, 'CDT' => -18000,
'CEDT' => 7200, 'CEDT' => 7200,
'CEST' => 7200,
'CET' => 3600, 'CET' => 3600,
'CGST' => -7200, 'CGST' => -7200,
'CGT' => -10800, 'CGT' => -10800,
@ -720,7 +720,7 @@ class SimplePie_Parse_Date
{ {
$output .= substr($string, $position, $pos - $position); $output .= substr($string, $position, $pos - $position);
$position = $pos + 1; $position = $pos + 1;
if ($string[$pos - 1] !== '\\') if ($pos === 0 || $string[$pos - 1] !== '\\')
{ {
$depth++; $depth++;
while ($depth && $position < $length) while ($depth && $position < $length)

File diff suppressed because one or more lines are too long

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

9
lib/simplepie/library/SimplePie/Registry.php Normal file → Executable file
View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -113,7 +112,7 @@ class SimplePie_Registry
*/ */
public function register($type, $class, $legacy = false) public function register($type, $class, $legacy = false)
{ {
if (!is_subclass_of($class, $this->default[$type])) if (!@is_subclass_of($class, $this->default[$type]))
{ {
return false; return false;
} }
@ -222,4 +221,4 @@ class SimplePie_Registry
$result = call_user_func_array(array($class, $method), $parameters); $result = call_user_func_array(array($class, $method), $parameters);
return $result; return $result;
} }
} }

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue
@ -61,7 +60,8 @@ class SimplePie_Sanitize
var $image_handler = ''; var $image_handler = '';
var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
var $encode_instead_of_strip = false; var $encode_instead_of_strip = false;
var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); var $strip_attributes = array('bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
var $add_attributes = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none'));
var $strip_comments = false; var $strip_comments = false;
var $output_encoding = 'UTF-8'; var $output_encoding = 'UTF-8';
var $enable_cache = true; var $enable_cache = true;
@ -160,7 +160,7 @@ class SimplePie_Sanitize
$this->encode_instead_of_strip = (bool) $encode; $this->encode_instead_of_strip = (bool) $encode;
} }
public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc')) public function strip_attributes($attribs = array('bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
{ {
if ($attribs) if ($attribs)
{ {
@ -179,6 +179,25 @@ class SimplePie_Sanitize
} }
} }
public function add_attributes($attribs = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none')))
{
if ($attribs)
{
if (is_array($attribs))
{
$this->add_attributes = $attribs;
}
else
{
$this->add_attributes = explode(',', $attribs);
}
}
else
{
$this->add_attributes = false;
}
}
public function strip_comments($strip = false) public function strip_comments($strip = false)
{ {
$this->strip_comments = (bool) $strip; $this->strip_comments = (bool) $strip;
@ -247,18 +266,28 @@ class SimplePie_Sanitize
if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
{ {
if (!class_exists('DOMDocument'))
{
throw new SimplePie_Exception('DOMDocument not found, unable to use sanitizer');
}
$document = new DOMDocument(); $document = new DOMDocument();
$document->encoding = 'UTF-8'; $document->encoding = 'UTF-8';
// See https://github.com/simplepie/simplepie/issues/334
$unique_tag = '#'.uniqid().'#';
$data = trim($unique_tag . $data . $unique_tag);
$data = $this->preprocess($data, $type); $data = $this->preprocess($data, $type);
set_error_handler(array('SimplePie_Misc', 'silence_errors')); set_error_handler(array('SimplePie_Misc', 'silence_errors'));
$document->loadHTML($data); $document->loadHTML($data);
restore_error_handler(); restore_error_handler();
$xpath = new DOMXPath($document);
// Strip comments // Strip comments
if ($this->strip_comments) if ($this->strip_comments)
{ {
$xpath = new DOMXPath($document);
$comments = $xpath->query('//comment()'); $comments = $xpath->query('//comment()');
foreach ($comments as $comment) foreach ($comments as $comment)
@ -274,7 +303,7 @@ class SimplePie_Sanitize
{ {
foreach ($this->strip_htmltags as $tag) foreach ($this->strip_htmltags as $tag)
{ {
$this->strip_tag($tag, $document, $type); $this->strip_tag($tag, $document, $xpath, $type);
} }
} }
@ -282,7 +311,15 @@ class SimplePie_Sanitize
{ {
foreach ($this->strip_attributes as $attrib) foreach ($this->strip_attributes as $attrib)
{ {
$this->strip_attr($attrib, $document); $this->strip_attr($attrib, $xpath);
}
}
if ($this->add_attributes)
{
foreach ($this->add_attributes as $tag => $valuePairs)
{
$this->add_attr($tag, $valuePairs, $document);
} }
} }
@ -310,7 +347,7 @@ class SimplePie_Sanitize
} }
else else
{ {
$file = $this->registry->create('File', array($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen)); $file = $this->registry->create('File', array($img->getAttribute('src'), $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen));
$headers = $file->headers; $headers = $file->headers;
if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
@ -329,19 +366,11 @@ class SimplePie_Sanitize
} }
} }
// Remove the DOCTYPE
// Seems to cause segfaulting if we don't do this
if ($document->firstChild instanceof DOMDocumentType)
{
$document->removeChild($document->firstChild);
}
// Move everything from the body to the root
$real_body = $document->getElementsByTagName('body')->item(0)->childNodes->item(0);
$document->replaceChild($real_body, $document->firstChild);
// Finally, convert to a HTML string // Finally, convert to a HTML string
$data = trim($document->saveHTML()); $data = trim($document->saveHTML());
$result = explode($unique_tag, $data);
// The tags may not be found again if there was invalid markup.
$data = count($result) === 3 ? $result[1] : '';
if ($this->remove_div) if ($this->remove_div)
{ {
@ -379,6 +408,7 @@ class SimplePie_Sanitize
protected function preprocess($html, $type) protected function preprocess($html, $type)
{ {
$ret = ''; $ret = '';
$html = preg_replace('%</?(?:html|body)[^>]*?'.'>%is', '', $html);
if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML) if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML)
{ {
// Atom XHTML constructs are wrapped with a div by default // Atom XHTML constructs are wrapped with a div by default
@ -451,9 +481,8 @@ class SimplePie_Sanitize
} }
} }
protected function strip_tag($tag, $document, $type) protected function strip_tag($tag, $document, $xpath, $type)
{ {
$xpath = new DOMXPath($document);
$elements = $xpath->query('body//' . $tag); $elements = $xpath->query('body//' . $tag);
if ($this->encode_instead_of_strip) if ($this->encode_instead_of_strip)
{ {
@ -536,9 +565,8 @@ class SimplePie_Sanitize
} }
} }
protected function strip_attr($attrib, $document) protected function strip_attr($attrib, $xpath)
{ {
$xpath = new DOMXPath($document);
$elements = $xpath->query('//*[@' . $attrib . ']'); $elements = $xpath->query('//*[@' . $attrib . ']');
foreach ($elements as $element) foreach ($elements as $element)
@ -546,4 +574,16 @@ class SimplePie_Sanitize
$element->removeAttribute($attrib); $element->removeAttribute($attrib);
} }
} }
protected function add_attr($tag, $valuePairs, $document)
{
$elements = $document->getElementsByTagName($tag);
foreach ($elements as $element)
{
foreach ($valuePairs as $attrib => $value)
{
$element->setAttribute($attrib, $value);
}
}
}
} }

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -5,7 +5,7 @@
* A PHP-Based RSS and Atom Feed Framework. * A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution. * Takes the hard work out of managing a complete RSS/Atom solution.
* *
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors * Copyright (c) 2004-2016, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
@ -33,8 +33,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* @package SimplePie * @package SimplePie
* @version 1.3.1 * @copyright 2004-2016 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
* @author Ryan Parman * @author Ryan Parman
* @author Geoffrey Sneddon * @author Geoffrey Sneddon
* @author Ryan McCue * @author Ryan McCue

View file

@ -8,3 +8,11 @@ Changes:
Dan Poltawski <talktodan@gmail.com> Dan Poltawski <talktodan@gmail.com>
Petr Skoda Petr Skoda
2016/09/22
==========
Updated to version 1.4.2 (MDL-56001)
The actual code has not been updated and still reads 1.4.1, but this is tagged as 1.4.2 on the site.
My guess is that they forgot to update the numbers when tagging the new version number. An issue has
been created on their github account (https://github.com/simplepie/simplepie/issues/472).
By Adrian Greeve <adrian@moodle.com>

View file

@ -123,7 +123,7 @@
<location>simplepie</location> <location>simplepie</location>
<name>SimplePie</name> <name>SimplePie</name>
<license>BSD</license> <license>BSD</license>
<version>1.3.1</version> <version>1.4.2</version>
<licenseversion></licenseversion> <licenseversion></licenseversion>
</library> </library>
<library> <library>