Add appropriate parameter types for updated psr/cache interface
Gitea - aviat/banker/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2021-02-18 19:23:20 -05:00
parent 94f40e6cd0
commit 18e61abd37
15 changed files with 97 additions and 73 deletions

View File

@ -1,5 +1,9 @@
# Changelog
## 4.0.0
* Updated Cache implementation to latest version
* Increased required PHP version to 8
## 3.2.0
* Improved validation of cache keys
* Updated dependencies

View File

@ -12,7 +12,7 @@
"psr-16"
],
"provide": {
"psr/cache-implementation": "^1.0.0",
"psr/cache-implementation": "^3.0.0",
"psr/simple-cache-implementation": "^1.0.0"
},
"autoload": {
@ -26,11 +26,11 @@
}
},
"require": {
"php": ">=7.4",
"php": ">= 8",
"ext-json": "*",
"predis/predis": "^1.1",
"psr/log": "^1.0",
"psr/cache": "^1.0.1",
"psr/cache": "^3.0.0",
"psr/simple-cache": "^1.0.1"
},
"require-dev": {

View File

@ -36,11 +36,8 @@ abstract class AbstractDriver implements DriverInterface, LoggerAwareInterface {
/**
* Common constructor interface for driver classes
*
* @param array $config - Connection parameters for the specified backend
* @param array $options - Special connection options for the specified backend
*/
abstract public function __construct(array $config = [], array $options = []);
abstract public function __construct();
/**
* Retrieve a set of values by their cache key

View File

@ -17,6 +17,7 @@ namespace Aviat\Banker\Driver;
use Aviat\Banker\Exception\CacheException;
use DateInterval;
use function apcu_clear_cache;
use function apcu_delete;
use function apcu_exists;
@ -31,12 +32,10 @@ class ApcuDriver extends AbstractDriver {
/**
* Constructor
*
* @param array $config - Not used by this driver
* @param array $options - Not used by this driver
* @throws CacheException
* @codeCoverageIgnore
*/
public function __construct(array $config = [], array $options = [])
public function __construct()
{
if ( ! extension_loaded('apcu'))
{
@ -61,7 +60,7 @@ class ApcuDriver extends AbstractDriver {
* @param string $key
* @return mixed
*/
public function get(string $key)
public function get(string $key): mixed
{
return apcu_fetch($key);
}
@ -85,10 +84,10 @@ class ApcuDriver extends AbstractDriver {
*
* @param string $key
* @param mixed $value
* @param int $expires
* @param int|DateInterval|null $expires
* @return bool
*/
public function set(string $key, $value, ?int $expires = NULL): bool
public function set(string $key, mixed $value, int|DateInterval|null $expires = NULL): bool
{
$ttl = $this->getTTLFromExpiration($expires);
@ -174,10 +173,10 @@ class ApcuDriver extends AbstractDriver {
/**
* Convert expiration date argument into TTL argument
*
* @param int $expires
* @param int|null $expires
* @return int
*/
protected function getTTLFromExpiration($expires): int
protected function getTTLFromExpiration(?int $expires): int
{
$ttl = (int)$expires - time();

View File

@ -15,6 +15,8 @@
*/
namespace Aviat\Banker\Driver;
use DateInterval;
/**
* Interface for different cache backends
*/
@ -33,10 +35,10 @@ interface DriverInterface {
*
* @param string $key
* @param mixed $value
* @param int $expires
* @param DateInterval|int|null $expires
* @return bool
*/
public function set(string $key, $value, ?int $expires = NULL): bool;
public function set(string $key, mixed $value, DateInterval|int|null $expires = NULL): bool;
/**
* Get the value for the selected cache key
@ -44,7 +46,7 @@ interface DriverInterface {
* @param string $key
* @return mixed
*/
public function get(string $key);
public function get(string $key): mixed;
/**
* Retrieve a set of values by their cache key

View File

@ -17,6 +17,8 @@ namespace Aviat\Banker\Driver;
use Aviat\Banker\Exception\CacheException;
use Aviat\Banker\Exception\InvalidArgumentException;
use DateInterval;
use Memcached;
use MemcachedException;
@ -28,7 +30,7 @@ class MemcachedDriver extends AbstractDriver {
/**
* @var Memcached
*/
private ?Memcached $conn;
private Memcached $conn;
/**
* Driver for PHP Memcache extension
@ -96,7 +98,7 @@ class MemcachedDriver extends AbstractDriver {
* @param string $key
* @return mixed
*/
public function get(string $key)
public function get(string $key): mixed
{
return $this->conn->get($key);
}
@ -120,10 +122,11 @@ class MemcachedDriver extends AbstractDriver {
*
* @param string $key
* @param mixed $value
* @param int $expires
* @param int|DateInterval|null $expires
* @return bool
* @throws InvalidArgumentException
*/
public function set(string $key, $value, ?int $expires = NULL): bool
public function set(string $key, mixed $value, int|DateInterval|null $expires = NULL): bool
{
$this->validateKey($key);
@ -171,15 +174,20 @@ class MemcachedDriver extends AbstractDriver {
$deleted = $this->conn->deleteMulti($keys);
foreach ($deleted as $key => $status)
if (is_array($deleted))
{
if ($status !== TRUE)
foreach ($deleted as $key => $status)
{
return FALSE;
if ($status !== TRUE)
{
return FALSE;
}
}
return TRUE;
}
return TRUE;
return FALSE;
}
/**

View File

@ -15,6 +15,7 @@
*/
namespace Aviat\Banker\Driver;
use DateInterval;
/**
* Cache backend for use without a cache server. Only does transient
@ -30,12 +31,9 @@ class NullDriver extends AbstractDriver {
protected array $store = [];
/**
* NullDriver constructor.
*
* @param array $config
* @param array $options
* NullDriver constructor
*/
public function __construct(array $config = [], array $options = [])
public function __construct()
{
$this->store = [];
}
@ -57,7 +55,7 @@ class NullDriver extends AbstractDriver {
* @param string $key
* @return mixed
*/
public function get(string $key)
public function get(string $key): mixed
{
return $this->exists($key)
? $this->store[$key]
@ -69,10 +67,10 @@ class NullDriver extends AbstractDriver {
*
* @param string $key
* @param mixed $value
* @param int $expires
* @param DateInterval|int|null $expires
* @return bool
*/
public function set(string $key, $value, ?int $expires = NULL): bool
public function set(string $key, mixed $value, DateInterval|int|null $expires = NULL): bool
{
$this->store[$key] = $value;
return $this->store[$key] === $value;

View File

@ -18,6 +18,8 @@ namespace Aviat\Banker\Driver;
use Aviat\Banker\Exception\CacheException;
use Predis\Client;
use DateInterval;
/**
* Redis cache backend
*/
@ -28,7 +30,7 @@ class RedisDriver extends AbstractDriver {
*
* @var Client
*/
protected ?Client $conn;
protected Client $conn;
/**
* RedisDriver constructor.
@ -74,7 +76,7 @@ class RedisDriver extends AbstractDriver {
* @param string $key
* @return mixed
*/
public function get(string $key)
public function get(string $key): mixed
{
$raw = $this->conn->get($key);
return unserialize($raw);
@ -85,10 +87,10 @@ class RedisDriver extends AbstractDriver {
*
* @param string $key
* @param mixed $value
* @param int $expires
* @param int|null $expires
* @return bool
*/
public function set(string $key, $value, ?int $expires = NULL): bool
public function set(string $key, mixed $value, DateInterval|int|null $expires = NULL): bool
{
$value = serialize($value);

View File

@ -102,7 +102,7 @@ class Item implements CacheItemInterface {
* @return mixed
* The value corresponding to this cache item's key, or null if not found.
*/
public function get()
public function get(): mixed
{
if ($this->isHit())
{
@ -136,10 +136,10 @@ class Item implements CacheItemInterface {
* @param mixed $value
* The serializable value to be stored.
*
* @return Item
* @return static
* The invoked object.
*/
public function set($value): Item
public function set(mixed $value): static
{
$this->value = $value;
return $this;
@ -154,10 +154,10 @@ class Item implements CacheItemInterface {
* the value should be stored permanently or for as long as the
* implementation allows.
*
* @return Item
* @return static
* The called object.
*/
public function expiresAt($expiration = NULL): Item
public function expiresAt($expiration = NULL): static
{
if ($expiration instanceof DateTimeInterface)
{
@ -179,10 +179,10 @@ class Item implements CacheItemInterface {
* If none is set, the value should be stored permanently or for as long as the
* implementation allows.
*
* @return Item
* @return static
* The called object.
*/
public function expiresAfter($time = NULL): Item
public function expiresAfter($time = NULL): static
{
if ($time instanceof DateInterval)
{

View File

@ -19,29 +19,22 @@ use Aviat\Banker\Exception\InvalidArgumentException;
trait KeyValidateTrait {
/**
* @param $keys
* @param iterable $keys
* @param bool $hash
* @throws InvalidArgumentException
*/
protected function validateKeys($keys, bool $hash = FALSE): void
protected function validateKeys(iterable $keys, bool $hash = FALSE): void
{
// Check type of keys
if ( ! is_iterable($keys))
{
throw new InvalidArgumentException('Keys must be an array or a traversable object');
}
$keys = ($hash) ? array_keys((array)$keys) : (array)$keys;
// Check each key
array_walk($keys, fn($key) => $this->validateKey($key));
array_walk($keys, [$this, 'validateKey']);
}
/**
* @param string $key
* @param mixed $key
* @throws InvalidArgumentException
*/
protected function validateKey($key): void
protected function validateKey(mixed $key): void
{
if ( ! is_string($key))
{

View File

@ -39,7 +39,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
* Set up the cache backend
*
* @param array $config
* @param LoggerInterface $logger
* @param LoggerInterface|null $logger
*/
public function __construct(array $config, ?LoggerInterface $logger = NULL)
{
@ -67,7 +67,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
* @return CacheItemInterface
* The corresponding Cache Item.
*/
public function getItem($key): CacheItemInterface
public function getItem(string $key): CacheItemInterface
{
$this->validateKey($key);
@ -90,13 +90,13 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
* If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
* MUST be thrown.
*
* @return array|\Traversable
* @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 = [])
public function getItems(array $keys = []): iterable
{
$this->validateKeys($keys);
@ -134,7 +134,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
* @return bool
* True if item exists in the cache, false otherwise.
*/
public function hasItem($key): bool
public function hasItem(string $key): bool
{
$this->validateKey($key);
@ -171,7 +171,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface {
* @return bool
* True if the item was successfully removed. False if there was an error.
*/
public function deleteItem($key): bool
public function deleteItem(string $key): bool
{
$this->validateKey($key);

View File

@ -15,6 +15,7 @@
*/
namespace Aviat\Banker;
use Aviat\Banker\Exception\InvalidArgumentException;
use Psr\Log\LoggerAwareInterface;
use Psr\SimpleCache;
use Psr\Log\LoggerInterface;
@ -30,7 +31,7 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
* Set up the cache backend
*
* @param array $config
* @param LoggerInterface $logger
* @param LoggerInterface|null $logger
*/
public function __construct(array $config, ?LoggerInterface $logger = NULL)
{
@ -53,7 +54,7 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null)
public function get($key, $default = null):mixed
{
$this->validateKey($key);
@ -74,7 +75,7 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
* @throws SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function set($key, $value, $ttl = null): bool
public function set($key, mixed $value, $ttl = null): bool
{
$this->validateKey($key);
@ -122,6 +123,12 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
*/
public function getMultiple($keys, $default = null)
{
// Check type of keys
if ( ! is_iterable($keys))
{
throw new InvalidArgumentException('Keys must be an array or a traversable object');
}
$this->validateKeys($keys);
return $this->driver->getMultiple((array)$keys);
@ -143,6 +150,12 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
*/
public function setMultiple($values, $ttl = null): bool
{
// Check type of keys
if ( ! is_iterable($values))
{
throw new InvalidArgumentException('Values must be an array or a traversable object');
}
$this->validateKeys($values, TRUE);
return ($ttl === NULL)
@ -163,6 +176,12 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface {
*/
public function deleteMultiple($keys): bool
{
// Check type of keys
if ( ! is_iterable($keys))
{
throw new InvalidArgumentException('Keys must be an array or a traversable object');
}
$this->validateKeys($keys);
return $this->driver->deleteMultiple((array)$keys);

View File

@ -18,6 +18,7 @@ namespace Aviat\Banker\Tests\Driver;
use Aviat\Banker\Driver\DriverInterface;
use Aviat\Banker\Exception\InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use TypeError;
class DriverTestBase extends TestCase {

View File

@ -21,6 +21,7 @@ use Monolog\Logger;
use Monolog\Handler\SyslogHandler;
use PHPUnit\Framework\TestCase;
use Psr\Log\{LoggerInterface, NullLogger};
use TypeError;
class PoolTest extends TestCase {
@ -97,8 +98,7 @@ class PoolTest extends TestCase {
public function testItemBadKey(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Cache key must be a string.');
$this->expectException(TypeError::class);
$this->pool->getItem([]);
}
@ -173,8 +173,7 @@ class PoolTest extends TestCase {
{
$this->pool->clear();
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Cache key must be a string.');
$this->expectException(TypeError::class);
$this->pool->hasItem(34);
}
@ -213,8 +212,8 @@ class PoolTest extends TestCase {
public function testDeleteItemBadKey(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Cache key must be a string.');
$this->expectException(TypeError::class);
// $this->expectExceptionMessage('Cache key must be a string.');
$this->pool->deleteItem(34);
}

View File

@ -201,8 +201,10 @@ class TellerTest extends TestCase {
/**
* @dataProvider keyValidationTests
* @param string $key
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function testKeyValidation($key): void
public function testKeyValidation(string $key): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid characters in cache key');