Source of file Pool.php

Size: 6,246 Bytes - Last Modified: 2020-05-08T12:23:11-04:00

../src/Pool.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
<?php declare(strict_types=1);
/**
 * Banker
 *
 * A Caching library implementing psr/cache (PSR 6) and psr/simple-cache (PSR 16)
 *
 * PHP version 7.4
 *
 * @package     Banker
 * @author      Timothy J. Warren <tim@timshomepage.net>
 * @copyright   2016 - 2020  Timothy J. Warren
 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
 * @version     3.1.0
 * @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 LoggerTrait;

	/**
	 * Cache Items to be saved
	 *
	 * @var array
	 */
	protected array $deferred = [];

	/**
	 * Set up the cache backend
	 *
	 * @param array $config
	 * @param LoggerInterface $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($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 array|\Traversable
	 *   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 = [])
	{
		$this->validateKeys($keys);

		if (empty($keys))
		{
			return new ItemCollection([]);
		}

		// Get the set of items selected
		$items = [];
		foreach($keys as $key)
		{
			if ( ! is_string($key))
			{
				throw new InvalidArgumentException();
			}

			$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($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($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
	{
		return $item->save();
	}

	/**
	 * 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;
	}
}