* @copyright 2016 - 2021 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 3.2.0 * @link https://git.timshomepage.net/timw4mail/banker */ namespace Aviat\Banker; use DateInterval; use DateTimeInterface; use Psr\Cache\CacheItemInterface; use Aviat\Banker\Driver\DriverInterface; /** * Base class for Cache items */ class Item implements CacheItemInterface { /** * The driver for the current cache backend * * @var DriverInterface */ protected DriverInterface $driver; /** * The key of the cache item * * @var string */ protected string $key; /** * The expiration time * * @var int | null */ protected ?int $expiresAt; /** * The time to live * * @var int | null */ protected ?int $ttl; /** * The value to save in the cache * * @var mixed */ protected $value; /** * Create a Cache Item object * * @param DriverInterface $driver * @param string $key */ public function __construct(DriverInterface $driver, string $key) { $this->driver = $driver; $this->key = $key; $this->expiresAt = NULL; $this->ttl = NULL; } /** * Returns the key for the current cache item. * * The key is loaded by the Implementing Library, but should be available to * the higher level callers when needed. * * @return string * The key string for this cache item. */ public function getKey(): string { return $this->key; } /** * Retrieves the value of the item from the cache associated with this object's key. * * The value returned must be identical to the value originally stored by set(). * * If isHit() returns false, this method MUST return null. Note that null * is a legitimate cached value, so the isHit() method SHOULD be used to * differentiate between "null value was found" and "no value was found." * * @return mixed * The value corresponding to this cache item's key, or null if not found. */ public function get(): mixed { if ($this->isHit()) { return $this->value ?? $this->driver->get($this->key); } return NULL; } /** * Confirms if the cache item lookup resulted in a cache hit. * * Note: This method MUST NOT have a race condition between calling isHit() * and calling get(). * * @return bool * True if the request resulted in a cache hit. False otherwise. */ public function isHit(): bool { return isset($this->value) || $this->driver->exists($this->key); } /** * Sets the value represented by this cache item. * * The $value argument may be any item that can be serialized by PHP, * although the method of serialization is left up to the Implementing * Library. * * @param mixed $value * The serializable value to be stored. * * @return static * The invoked object. */ public function set(mixed $value): static { $this->value = $value; return $this; } /** * Sets the expiration time for this cache item. * * @param DateTimeInterface|null $expiration * The point in time after which the item MUST be considered expired. * If null is passed explicitly, a default value MAY be used. If none is set, * the value should be stored permanently or for as long as the * implementation allows. * * @return static * The called object. */ public function expiresAt($expiration = NULL): static { if ($expiration instanceof DateTimeInterface) { $expiration = $expiration->getTimestamp(); } $this->expiresAt = (int) $expiration; return $this; } /** * Sets the expiration time for this cache item. * * @param int|DateInterval|null $time * The period of time from the present after which the item MUST be considered * expired. An integer parameter is understood to be the time in seconds until * expiration. If null is passed explicitly, a default value MAY be used. * If none is set, the value should be stored permanently or for as long as the * implementation allows. * * @return static * The called object. */ public function expiresAfter($time = NULL): static { if ($time instanceof DateInterval) { $time = $time->format("%s"); } $this->ttl = (int) $time; return $this; } /** * Save the current value to the cache * * @return bool */ public function save(): bool { if ($this->expiresAt !== NULL && $this->expiresAt !== 0) { $setResult = $this->driver->set($this->key, $this->value); $expResult = $this->driver->expiresAt($this->key, $this->expiresAt); return $setResult && $expResult; } if ($this->ttl !== NULL && $this->ttl !== 0) { return (bool) $this->driver->set($this->key, $this->value, $this->ttl); } return (bool) $this->driver->set($this->key, $this->value); } }