diff --git a/includes/FeedsHTTPCache.inc b/includes/FeedsHTTPCache.inc index 07ce08f..a6490c8 100644 --- a/includes/FeedsHTTPCache.inc +++ b/includes/FeedsHTTPCache.inc @@ -37,6 +37,28 @@ class FeedsHTTPCache extends DrupalDatabaseCache { } /** + * Saves raw contents to a file in the cache directory. + * + * @param string $cid + * The cache ID. + * @param object $response + * The HTTP Response object. + * + * @return string|null + * The name of the file that was created or NULL if no file was created. + */ + public function saveFile($cid, $response) { + if (isset($response->data)) { + $file_cache_dir = $this->getCacheDir(); + file_prepare_directory($file_cache_dir, FILE_CREATE_DIRECTORY); + $filename = $this->constructFilePath($cid); + file_put_contents($filename, $response->data); + + return $filename; + } + } + + /** * Deletes a file from the cache directory. * * @param string $cid @@ -154,20 +176,17 @@ class FeedsHTTPCache extends DrupalDatabaseCache { /** * {@inheritdoc} */ - public function set($cid, $data, $expire = CACHE_PERMANENT) { - // Create a cache item to only cache what is needed. - $item = new FeedsHTTPCacheItem($data); - - // If the object contains the raw data, save it to a file. - if (isset($data->data)) { - $file_cache_dir = $this->getCacheDir(); - file_prepare_directory($file_cache_dir, FILE_CREATE_DIRECTORY); - $filename = $this->constructFilePath($cid); - file_put_contents($filename, $data->data); - - $item->setFilePath($filename); + public function set($cid, $item, $expire = CACHE_PERMANENT) { + if ($item instanceof FeedsHTTPCacheItem) { + // Given item already got rid of the raw data. + $item->setCid($cid); + return parent::set($cid, $item, $expire); } + // Create a cache item to only cache what is needed. + // The cache item will take care of saving the raw data to a file. + $item = new FeedsHTTPCacheItem($cid, $item); + parent::set($cid, $item, $expire); } diff --git a/includes/FeedsHTTPCacheItem.inc b/includes/FeedsHTTPCacheItem.inc index 8d3c73a..4b2ee9e 100644 --- a/includes/FeedsHTTPCacheItem.inc +++ b/includes/FeedsHTTPCacheItem.inc @@ -5,6 +5,18 @@ */ class FeedsHTTPCacheItem { /** + * The cache bin to save the data to. + * + * @var string + */ + const CACHE_BIN = 'cache_feeds_http'; + + /** + * The cache ID. + */ + protected $cid; + + /** * Headers of the response. * * @var array @@ -21,13 +33,17 @@ class FeedsHTTPCacheItem { /** * FeedsHTTPCacheItem object constructor. * - * @param object $result + * @param string $cid + * The cache ID. + * @param object $response * The HTTP response object. */ - public function __construct($result) { + public function __construct($cid, $response) { + $this->setCid($cid); + // Copy over other metadata from result, but not the raw data. // Value is assigned by reference to save memory. - foreach ($result as $key => &$value) { + foreach ($response as $key => &$value) { switch ($key) { case 'headers': $this->headers = (array) $value; @@ -38,16 +54,29 @@ class FeedsHTTPCacheItem { break; case 'data': - // Data should not be cached, so this one is not set! + // Data should not be cached in the database, so save data to a file + // instead. The whole response object is passed to save memory usage. + // The data could potentially be huge. + $this->saveResponseData($response); break; default: - $this->$key = $result->$key; + $this->$key = $response->$key; } } } /** + * Sets cache ID. + * + * @param string $cid + * The cache ID. + */ + public function setCid($cid) { + $this->cid = $cid; + } + + /** * Sets file path. * * @param string $file_path @@ -84,6 +113,23 @@ class FeedsHTTPCacheItem { } /** + * Returns cache object. + * + * @return FeedsHTTPCache + * An instance of FeedsHTTPCache. + */ + public function getCacheObject() { + $cache_object = _cache_get_object(self::CACHE_BIN); + if (!($cache_object instanceof FeedsHTTPCache)) { + // A different cache class could be used for the cache_feeds_http bin that + // does not extend FeedsHTTPCache. In this case, just instantiate the + // FeedsHTTPCache class. + $cache_object = new FeedsHTTPCache(self::CACHE_BIN); + } + return $cache_object; + } + + /** * Gets the cached file from the file system. * * @return string|null @@ -95,4 +141,25 @@ class FeedsHTTPCacheItem { return file_get_contents($this->file_path); } } + + /** + * Writes data to a file. + * + * @param object $response + * The HTTP Response object that contains the data. + */ + public function saveResponseData($response) { + if (isset($response->data)) { + // Get cache object, this object knows where to save the file. + $filename = $cache_object->saveFile($this->cid, $response); + $this->setFilePath($filename); + } + } + + /** + * Saves item to cache. + */ + public function cacheSet() { + cache_set($this->cid, $this, self::CACHE_BIN); + } } diff --git a/libraries/http_request.inc b/libraries/http_request.inc index 6fedc60..8cd563f 100644 --- a/libraries/http_request.inc +++ b/libraries/http_request.inc @@ -264,7 +264,7 @@ function http_request_get($url, $username = NULL, $password = NULL, $accept_inva // In case of 304 Not Modified try to return cached data. if ($result->code == 304) { - if (isset($last_result)) { + if (isset($last_result->data)) { $last_result->from_cache = TRUE; return $last_result; } @@ -341,8 +341,9 @@ function http_request_get_cache($url) { * @param stdClass $result * The result of the HTTP request. */ -function http_request_set_cache($url, stdClass $result) { - cache_set(hash('sha256', $url), $result, 'cache_feeds_http'); +function http_request_set_cache($url, $result) { + $item = ($result instanceof FeedsHTTPCacheItem) ? $result : new FeedsHTTPCacheItem(hash('sha256', $url), $result); + $item->cacheSet(); } /**