protected function fetch_data(&$cache)
{
// If it's enabled, use the cache
if ($cache) {
// Load the Cache
$this->data = $cache->load();
if (!empty($this->data)) {
// If the cache is for an outdated build of SimplePie
if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) {
$cache->unlink();
$this->data = array();
} elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) {
$cache = false;
$this->data = array();
} elseif (isset($this->data['feed_url'])) {
// If the autodiscovery cache is still valid use it.
if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) {
// Do not need to do feed autodiscovery yet.
if ($this->data['feed_url'] !== $this->data['url']) {
$this->set_feed_url($this->data['feed_url']);
return $this->init();
}
$cache->unlink();
$this->data = array();
}
} elseif ($cache->mtime() + $this->cache_duration < time()) {
// 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'])) {
$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');
if (isset($this->data['headers']['last-modified'])) {
$headers['if-modified-since'] = $this->data['headers']['last-modified'];
}
if (isset($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, $this->curl_options));
if ($file->success) {
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();
return true;
}
} else {
$this->check_modified = false;
if ($this->force_cache_fallback) {
$cache->touch();
return true;
}
unset($file);
}
}
} else {
$this->raw_data = false;
return true;
}
} else {
$cache->unlink();
$this->data = array();
}
}
// If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
if (!isset($file)) {
if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url) {
$file =& $this->file;
} else {
$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');
$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 (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) {
$this->error = $file->error;
return !empty($this->data);
}
if (!$this->force_feed) {
// Check if the supplied URL is a feed, if it isn't, look for it.
$locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
if (!$locate->is_feed($file)) {
$copyStatusCode = $file->status_code;
$copyContentType = $file->headers['content-type'];
try {
$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) {
if ($hub = $locate->get_rel_link('hub')) {
$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) {
// 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->error = $e->getMessage();
$this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
return false;
}
if ($cache) {
$this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
if (!$cache->save($this)) {
trigger_error("{$this->cache_location} is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
}
$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
}
$this->feed_url = $file->url;
}
$locate = null;
}
$this->raw_data = $file->body;
$this->permanent_url = $file->permanent_url;
$headers = $file->headers;
$sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
$sniffed = $sniffer->get_type();
return array($headers, $sniffed);
}