* @copyright 2016 - 2023 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 4.1.1 * @link https://git.timshomepage.net/timw4mail/banker */ namespace Aviat\Banker; use Aviat\Banker\Exception\InvalidArgumentException; use Psr\Cache\{CacheItemInterface, CacheItemPoolInterface}; use Psr\Log\{LoggerAwareInterface, LoggerInterface}; use function is_string; /** * The main cache manager */ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { use _Driver; use KeyValidateTrait; use LoggerTrait; /** * Cache Items to be saved * * @var array */ protected array $deferred = []; /** * Set up the cache backend * * @param array $config * @param LoggerInterface|null $logger */ public function __construct(array $config, ?LoggerInterface $logger = NULL) { $this->driver = $this->loadDriver($config); if ($logger !== NULL) { $this->setLogger($logger); } } /** * Returns a Cache Item representing the specified key. * * This method must always return a CacheItemInterface object, even in case of * a cache miss. It MUST NOT return null. * * @param string $key * The key for which to return the corresponding Cache Item. * * @throws InvalidArgumentException * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * * @return CacheItemInterface * The corresponding Cache Item. */ public function getItem(string $key): CacheItemInterface { $this->validateKey($key); // If a deferred item exists, return that if (array_key_exists($key, $this->deferred)) { return $this->deferred[$key]; } return new Item($this->driver, $key); } /** * Returns a traversable set of cache items. * * @param string[] $keys * An indexed array of keys of items to retrieve. * * @throws InvalidArgumentException * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * * @return iterable * A traversable collection of Cache Items keyed by the cache keys of * each item. A Cache item will be returned for each key, even if that * key is not found. However, if no keys are specified then an empty * traversable MUST be returned instead. */ public function getItems(array $keys = []): iterable { $this->validateKeys($keys); if (empty($keys)) { return new ItemCollection([]); } // Get the set of items selected $items = []; foreach($keys as $key) { $items[$key] = array_key_exists($key, $this->deferred) ? $this->deferred[$key] : new Item($this->driver, $key); } return new ItemCollection($items); } /** * Confirms if the cache contains specified cache item. * * Note: This method MAY avoid retrieving the cached value for performance reasons. * This could result in a race condition with CacheItemInterface::get(). To avoid * such situation use CacheItemInterface::isHit() instead. * * @param string $key * The key for which to check existence. * * @throws InvalidArgumentException * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * * @return bool * True if item exists in the cache, false otherwise. */ public function hasItem(string $key): bool { $this->validateKey($key); // See if there are any deferred items if (array_key_exists($key, $this->deferred)) { return TRUE; } return $this->driver->exists($key); } /** * Deletes all items in the pool. * * @return bool * True if the pool was successfully cleared. False if there was an error. */ public function clear(): bool { return $this->driver->flush(); } /** * Removes the item from the pool. * * @param string $key * The key to delete. * * @throws InvalidArgumentException * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * * @return bool * True if the item was successfully removed. False if there was an error. */ public function deleteItem(string $key): bool { $this->validateKey($key); if ( ! $this->hasItem($key)) { return FALSE; } return $this->driver->delete($key); } /** * Removes multiple items from the pool. * * @param string[] $keys * An array of keys that should be removed from the pool. * @throws InvalidArgumentException * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException * MUST be thrown. * * @return bool * True if the items were successfully removed. False if there was an error. */ public function deleteItems(array $keys): bool { $this->validateKeys($keys); return $this->driver->deleteMultiple($keys); } /** * Persists a cache item immediately. * * @param CacheItemInterface $item * The cache item to save. * * @return bool * True if the item was successfully persisted. False if there was an error. */ public function save(CacheItemInterface $item): bool { if (method_exists($item, 'save')) { return $item->save(); } return FALSE; } /** * Sets a cache item to be persisted later. * * @param CacheItemInterface $item * The cache item to save. * * @return bool * False if the item could not be queued or if a commit was attempted and failed. True otherwise. */ public function saveDeferred(CacheItemInterface $item): bool { $key = $item->getKey(); $this->deferred[$key] = $item; return TRUE; } /** * Persists any deferred cache items. * * @return bool * True if all not-yet-saved items were successfully saved or there were none. False otherwise. */ public function commit(): bool { if (empty($this->deferred)) { return TRUE; } $result = TRUE; foreach($this->deferred as $item) { $result = $result && $this->save($item); } if ($result === TRUE) { $this->deferred = []; } return $result; } }