From dc53bf5ccce99812431958c89486395e68766a1f Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 8 May 2020 10:54:09 -0400 Subject: [PATCH] Refactor shared implementation methods into a trait, check keys in pool --- build/phpdox.xml | 23 +++++-------- src/Pool.php | 52 ++++-------------------------- src/Teller.php | 61 +++-------------------------------- src/_Driver.php | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 117 deletions(-) create mode 100644 src/_Driver.php diff --git a/build/phpdox.xml b/build/phpdox.xml index eb46b9a..5a763a2 100644 --- a/build/phpdox.xml +++ b/build/phpdox.xml @@ -9,7 +9,7 @@ - + @@ -35,7 +35,7 @@ --> - + @@ -78,15 +78,15 @@ - + - + - - - - - - - - + diff --git a/src/Pool.php b/src/Pool.php index 09af360..82cadb1 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -15,7 +15,6 @@ */ namespace Aviat\Banker; -use Aviat\Banker\Driver\DriverInterface; use Aviat\Banker\Exception\InvalidArgumentException; use Psr\Cache\{CacheItemInterface, CacheItemPoolInterface}; use Psr\Log\{LoggerAwareInterface, LoggerInterface}; @@ -26,16 +25,9 @@ use function is_string; * The main cache manager */ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { - + use _Driver; use LoggerTrait; - /** - * Driver class for handling the chosen caching backend - * - * @var DriverInterface - */ - protected DriverInterface $driver; - /** * Cache Items to be saved * @@ -77,10 +69,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { */ public function getItem($key): CacheItemInterface { - if ( ! is_string($key)) - { - throw new InvalidArgumentException(); - } + $this->validateKey($key); // If a deferred item exists, return that if (array_key_exists($key, $this->deferred)) @@ -109,6 +98,8 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { */ public function getItems(array $keys = []) { + $this->validateKeys($keys); + if (empty($keys)) { return new ItemCollection([]); @@ -150,10 +141,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { */ public function hasItem($key): bool { - if ( ! is_string($key)) - { - throw new InvalidArgumentException(); - } + $this->validateKey($key); // See if there are any deferred items if (array_key_exists($key, $this->deferred)) @@ -190,10 +178,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { */ public function deleteItem($key): bool { - if ( ! is_string($key)) - { - throw new InvalidArgumentException(); - } + $this->validateKey($key); if ( ! $this->hasItem($key)) { @@ -218,13 +203,7 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { */ public function deleteItems(array $keys): bool { - foreach ($keys as $key) - { - if ( ! is_string($key)) - { - throw new InvalidArgumentException(); - } - } + $this->validateKeys($keys); return $this->driver->deleteMultiple($keys); } @@ -287,21 +266,4 @@ final class Pool implements CacheItemPoolInterface, LoggerAwareInterface { return $result; } - - /** - * Instantiate the appropriate cache backend based on the config - * - * @param array $driverConfig - * @return DriverInterface - */ - protected function loadDriver(array $driverConfig = []): DriverInterface - { - $driver = ucfirst(strtolower($driverConfig['driver'] ?? 'null')); - $class = __NAMESPACE__ . "\\Driver\\${driver}Driver"; - - $driverConfig['connection'] = $driverConfig['connection'] ?? []; - $driverConfig['options'] = $driverConfig['options'] ?? []; - - return new $class($driverConfig['connection'], $driverConfig['options']); - } } \ No newline at end of file diff --git a/src/Teller.php b/src/Teller.php index 111fefc..8790862 100644 --- a/src/Teller.php +++ b/src/Teller.php @@ -15,17 +15,17 @@ */ namespace Aviat\Banker; -use Aviat\Banker\Driver\DriverInterface; -use Aviat\Banker\Exception\InvalidArgumentException; use Psr\Log\LoggerAwareInterface; use Psr\SimpleCache; use Psr\Log\LoggerInterface; +/** + * Implements PSR-16 (SimpleCache) + */ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface { + use _Driver; use LoggerTrait; - private DriverInterface $driver; - /** * Set up the cache backend * @@ -194,57 +194,4 @@ class Teller implements SimpleCache\CacheInterface, LoggerAwareInterface { return $this->driver->exists($key); } - - /** - * @param $keys - * @param bool $hash - * @throws InvalidArgumentException - */ - private function validateKeys($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)); - } - - /** - * @param string $key - * @throws InvalidArgumentException - */ - private function validateKey($key): void - { - if ( ! is_string($key)) - { - throw new InvalidArgumentException('Cache key must be a string.'); - } - - if (is_string($key) && preg_match("`[{}()/@:\\\]`", $key) === 1) - { - throw new InvalidArgumentException('Invalid characters in cache key'); - } - } - - /** - * Instantiate the appropriate cache backend based on the config - * - * @param array $driverConfig - * @return DriverInterface - */ - protected function loadDriver(array $driverConfig = []): DriverInterface - { - $driver = ucfirst(strtolower($driverConfig['driver'] ?? 'null')); - $class = __NAMESPACE__ . "\\Driver\\${driver}Driver"; - - $driverConfig['connection'] = $driverConfig['connection'] ?? []; - $driverConfig['options'] = $driverConfig['options'] ?? []; - - return new $class($driverConfig['connection'], $driverConfig['options']); - } } \ No newline at end of file diff --git a/src/_Driver.php b/src/_Driver.php new file mode 100644 index 0000000..2d31611 --- /dev/null +++ b/src/_Driver.php @@ -0,0 +1,84 @@ + + * @copyright 2016 - 2020 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 3.0.0 + * @link https://git.timshomepage.net/timw4mail/banker + */ +namespace Aviat\Banker; + +use Aviat\Banker\Driver\DriverInterface; +use Aviat\Banker\Exception\InvalidArgumentException; + +/** + * Private trait for shared driver-related functionality + */ +trait _Driver { + /** + * Driver class for handling the chosen caching backend + * + * @var DriverInterface + */ + private DriverInterface $driver; + + /** + * Instantiate the appropriate cache backend based on the config + * + * @param array $driverConfig + * @return DriverInterface + */ + protected function loadDriver(array $driverConfig = []): DriverInterface + { + $driver = ucfirst(strtolower($driverConfig['driver'] ?? 'null')); + $class = __NAMESPACE__ . "\\Driver\\${driver}Driver"; + + $driverConfig['connection'] = $driverConfig['connection'] ?? []; + $driverConfig['options'] = $driverConfig['options'] ?? []; + + return new $class($driverConfig['connection'], $driverConfig['options']); + } + + /** + * @param $keys + * @param bool $hash + * @throws InvalidArgumentException + */ + private function validateKeys($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)); + } + + /** + * @param string $key + * @throws InvalidArgumentException + */ + private function validateKey($key): void + { + if ( ! is_string($key)) + { + throw new InvalidArgumentException('Cache key must be a string.'); + } + + if (is_string($key) && preg_match("`[{}()/@:\\\]`", $key) === 1) + { + throw new InvalidArgumentException('Invalid characters in cache key'); + } + } +} \ No newline at end of file