From af0f7c4cbae5b3a8cabfce3b5d1cc29c46c8655b Mon Sep 17 00:00:00 2001 From: Ole Vik Date: Sun, 9 Sep 2018 15:52:34 +0200 Subject: [PATCH 1/2] FileStorage Adapter PSR-16 compliant adapter for abstract handling of transient and persistent files. --- .../Framework/Cache/Adapter/FileStorage.php | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 system/src/Grav/Framework/Cache/Adapter/FileStorage.php diff --git a/system/src/Grav/Framework/Cache/Adapter/FileStorage.php b/system/src/Grav/Framework/Cache/Adapter/FileStorage.php new file mode 100644 index 0000000000..334028d227 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/FileStorage.php @@ -0,0 +1,179 @@ +directory = $directory; + } + + /** + * Fetches a value from storage. + * + * @param string $key The unique key of this item in storage. + * @param mixed $miss Value to return if the key does not exist. + * + * @return mixed The value of the item from storage, or $miss if non-existant. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function doGet($key, $miss = false) + { + parent::validateKey($key); + $now = time(); + $file = $this->directory . DIRECTORY_SEPARATOR . $key; + + if (!file_exists($file) || !$h = @fopen($file, 'rb')) { + return $miss; + } + + if ($now >= (int) $expiresAt = fgets($h)) { + fclose($h); + @unlink($file); + } else { + $i = rawurldecode(rtrim(fgets($h))); + $value = stream_get_contents($h); + fclose($h); + if ($i === $key) { + return unserialize($value); + } + } + + return $miss; + } + + /** + * Persists data in storage. + * + * @param string $key The key of the item to store. + * @param mixed $value The value of the item to store. + * @param null|int|\DateInterval $ttl The Time To Live value of this item. + * + * @return bool True on success and false on failure. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * @throws \Symfony\Component\Filesystem\Exception\IOExceptionInterface + */ + public function doSet($key, $value, $ttl = 31556926) + { + parent::validateKey($key); + $expiresAt = time() + (int) $ttl; + $file = $this->directory . DIRECTORY_SEPARATOR . $key; + + if (!is_writable($this->directory)) { + mkdir($this->directory, 0755, true); + } else { + try { + if ($this->tmp === null) { + $this->tmp = $this->directory . DIRECTORY_SEPARATOR . uniqid('', true); + } + + file_put_contents($this->tmp, $value, LOCK_EX); + + if ($expiresAt !== null) { + touch($this->tmp, $expiresAt); + } + + return rename($this->tmp, $file); + } catch (\CacheException $e) { + throw new \CacheException($e); + } finally { + restore_error_handler(); + } + } + } + + /** + * Delete an item from storage. + * + * @param string $key The unique cache key of the item to delete. + * + * @return bool True if the item was removed, false otherwise. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function doDelete($key) + { + parent::validateKey($key); + $file = $this->directory . DIRECTORY_SEPARATOR . $key; + + return (!file_exists($file) || @unlink($file) || !file_exists($file)); + } + + /** + * Wipes clean the entire storage's keys. + * + * @return bool True on success, false otherwise. + */ + public function doClear() + { + $target = new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS); + $iterator = new \RecursiveIteratorIterator($target); + foreach ($iterator as $file) { + $this->doDelete($file->getFilename()); + } + $result = new \FilesystemIterator($this->directory); + if (!$result->valid()) { + return true; + } else { + return false; + } + } + + /** + * Determines whether an item is present in storage. + * + * @param string $key The unique cache key of the item to check for. + * + * @return bool + * + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function doHas($key) + { + parent::validateKey($key); + $file = $this->directory . DIRECTORY_SEPARATOR . $key; + return file_exists($file) && (@filemtime($file) > time() || $this->doGet($key, null)); + } +} From 4237c4a9fc8414618d78186e3bf6eae4e32ba39b Mon Sep 17 00:00:00 2001 From: Ole Vik Date: Sat, 27 Oct 2018 10:41:58 +0200 Subject: [PATCH 2/2] Only throw error. --- system/src/Grav/Framework/Cache/Adapter/FileStorage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Framework/Cache/Adapter/FileStorage.php b/system/src/Grav/Framework/Cache/Adapter/FileStorage.php index 334028d227..af883b25c9 100644 --- a/system/src/Grav/Framework/Cache/Adapter/FileStorage.php +++ b/system/src/Grav/Framework/Cache/Adapter/FileStorage.php @@ -117,7 +117,7 @@ public function doSet($key, $value, $ttl = 31556926) return rename($this->tmp, $file); } catch (\CacheException $e) { - throw new \CacheException($e); + throw $e; } finally { restore_error_handler(); }