<?php namespace Google\Auth\Cache; use ErrorException; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; class FileSystemCacheItemPool implements CacheItemPoolInterface { private string $cachePath; private array $buffer = []; public function __construct(string $path) { $this->cachePath = $path; if (is_dir($this->cachePath)) { return; } if (!@mkdir($this->cachePath, 0777, true) && !is_dir($this->cachePath)) { throw new ErrorException("Cache folder couldn't be created."); } } public function getItem(string $key): CacheItemInterface { if (!$this->validKey($key)) { throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); } $item = new TypedItem($key); $itemPath = $this->cacheFilePath($key); if (!file_exists($itemPath)) { return $item; } $serializedItem = file_get_contents($itemPath); if ($serializedItem === false) { return $item; } $item->set(unserialize($serializedItem)); return $item; } public function getItems(array $keys = []): iterable { $result = []; foreach ($keys as $key) { $result[$key] = $this->getItem($key); } return $result; } public function save(CacheItemInterface $item): bool { if (!$this->validKey($item->getKey())) { return false; } $itemPath = $this->cacheFilePath($item->getKey()); $serializedItem = serialize($item->get()); $result = file_put_contents($itemPath, $serializedItem, LOCK_EX); if ($result === false) { return false; } return true; } public function hasItem(string $key): bool { return $this->getItem($key)->isHit(); } public function clear(): bool { $this->buffer = []; if (!is_dir($this->cachePath)) { return false; } $files = scandir($this->cachePath); if (!$files) { return false; } foreach ($files as $fileName) { if ($fileName === '.' || $fileName === '..') { continue; } if (!unlink($this->cachePath . '/' . $fileName)) { return false; } } return true; } public function deleteItem(string $key): bool { if (!$this->validKey($key)) { throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); } $itemPath = $this->cacheFilePath($key); if (!file_exists($itemPath)) { return true; } return unlink($itemPath); } public function deleteItems(array $keys): bool { $result = true; foreach ($keys as $key) { if (!$this->deleteItem($key)) { $result = false; } } return $result; } public function saveDeferred(CacheItemInterface $item): bool { array_push($this->buffer, $item); return true; } public function commit(): bool { $result = true; foreach ($this->buffer as $item) { if (!$this->save($item)) { $result = false; } } return $result; } private function cacheFilePath(string $key): string { return $this->cachePath . '/' . $key; } private function validKey(string $key): bool { return (bool) preg_match('|^[a-zA-Z0-9_\.]+$|', $key); } }