SimplePie::fetch_data PHP Method

fetch_data() protected method

If the data is already cached, attempt to fetch it from there instead
protected fetch_data ( SimplePie_Cache | false &$cache ) : array | true
$cache SimplePie_Cache | false Cache handler, or false to not load from the cache
return array | true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
    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);
    }