From 5068f8751a52ef9d0ce53a7eab21f8bf9a57b940 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 5 Mar 2016 17:35:55 +0100 Subject: [PATCH] [Cache] Add namespace handling to all adapters --- .../Cache/Adapter/AbstractAdapter.php | 6 +-- .../Cache/Adapter/DoctrineAdapter.php | 4 +- .../Cache/Adapter/FilesystemAdapter.php | 8 +++- .../Component/Cache/Adapter/ProxyAdapter.php | 48 ++++++++++++++++--- .../Cache/Tests/Adapter/ApcuAdapterTest.php | 2 +- .../Adapter/NamespacedProxyAdapterTest.php | 26 ++++++++++ 6 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 src/Symfony/Component/Cache/Tests/Adapter/NamespacedProxyAdapterTest.php diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index dbb8258936606..a6da1952a57bd 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -32,7 +32,7 @@ abstract class AbstractAdapter implements CacheItemPoolInterface, LoggerAwareInt protected function __construct($namespace = '', $defaultLifetime = 0) { - $this->namespace = $namespace; + $this->namespace = $this->getId($namespace, true); $this->createCacheItem = \Closure::bind( function ($key, $value, $isHit) use ($defaultLifetime) { $item = new CacheItem(); @@ -331,12 +331,12 @@ public function __destruct() } } - private function getId($key) + private function getId($key, $ns = false) { if (!is_string($key)) { throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key))); } - if (!isset($key[0])) { + if (!isset($key[0]) && !$ns) { throw new InvalidArgumentException('Cache key length must be greater than zero'); } if (isset($key[strcspn($key, '{}()/\@:')])) { diff --git a/src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php b/src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php index 41da56d597c91..f89148a7871f8 100644 --- a/src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php @@ -20,9 +20,9 @@ class DoctrineAdapter extends AbstractAdapter { private $provider; - public function __construct(CacheProvider $provider, $defaultLifetime = null) + public function __construct(CacheProvider $provider, $defaultLifetime = 0, $namespace = '') { - parent::__construct('', $defaultLifetime); + parent::__construct($namespace, $defaultLifetime); $this->provider = $provider; } diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php index db6d9ce4cf4e7..a9ac89ff2a805 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemAdapter.php @@ -20,10 +20,16 @@ class FilesystemAdapter extends AbstractAdapter { private $directory; - public function __construct($directory, $defaultLifetime = null) + public function __construct($directory, $defaultLifetime = 0, $namespace = '') { parent::__construct('', $defaultLifetime); + if (!isset($directory[0])) { + $directory = sys_get_temp_dir().'/symfony-cache'; + } + if (isset($namespace[0])) { + $directory .= '/'.$namespace; + } if (!file_exists($dir = $directory.'/.')) { @mkdir($directory, 0777, true); } diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index eaeb5ba4fbd44..3bce3cb5bb612 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -14,6 +14,7 @@ use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; /** * @author Nicolas Grekas @@ -21,19 +22,24 @@ class ProxyAdapter implements CacheItemPoolInterface { private $pool; + private $namespace; + private $namespaceLen; private $createCacheItem; private $hits = 0; private $misses = 0; - public function __construct(CacheItemPoolInterface $pool) + public function __construct(CacheItemPoolInterface $pool, $defaultLifetime = 0, $namespace = '') { $this->pool = $pool; + $this->namespace = $this->getId($namespace, true); + $this->namespaceLen = strlen($namespace); $this->createCacheItem = \Closure::bind( - function ($key, $value, $isHit) { + function ($key, $value, $isHit) use ($defaultLifetime) { $item = new CacheItem(); $item->key = $key; $item->value = $value; $item->isHit = $isHit; + $item->defaultLifetime = $defaultLifetime; return $item; }, @@ -48,7 +54,7 @@ function ($key, $value, $isHit) { public function getItem($key) { $f = $this->createCacheItem; - $item = $this->pool->getItem($key); + $item = $this->pool->getItem($this->getId($key)); if ($isHit = $item->isHit()) { ++$this->hits; } else { @@ -63,6 +69,12 @@ public function getItem($key) */ public function getItems(array $keys = array()) { + if ($this->namespaceLen) { + foreach ($keys as $i => $key) { + $keys[$i] = $this->getId($key); + } + } + return $this->generateItems($this->pool->getItems($keys)); } @@ -71,7 +83,7 @@ public function getItems(array $keys = array()) */ public function hasItem($key) { - return $this->pool->hasItem($key); + return $this->pool->hasItem($this->getId($key)); } /** @@ -87,7 +99,7 @@ public function clear() */ public function deleteItem($key) { - return $this->pool->deleteItem($key); + return $this->pool->deleteItem($this->getId($key)); } /** @@ -95,6 +107,12 @@ public function deleteItem($key) */ public function deleteItems(array $keys) { + if ($this->namespaceLen) { + foreach ($keys as $i => $key) { + $keys[$i] = $this->getId($key); + } + } + return $this->pool->deleteItems($keys); } @@ -129,7 +147,7 @@ private function doSave(CacheItemInterface $item, $method) } $item = (array) $item; $expiry = $item[CacheItem::CAST_PREFIX.'expiry']; - $poolItem = $this->pool->getItem($item[CacheItem::CAST_PREFIX.'key']); + $poolItem = $this->pool->getItem($this->namespace.$item[CacheItem::CAST_PREFIX.'key']); $poolItem->set($item[CacheItem::CAST_PREFIX.'value']); $poolItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null); @@ -146,6 +164,9 @@ private function generateItems($items) } else { ++$this->misses; } + if ($this->namespaceLen) { + $key = substr($key, $this->namespaceLen); + } yield $key => $f($key, $item->get(), $isHit); } @@ -170,4 +191,19 @@ public function getMisses() { return $this->misses; } + + private function getId($key, $ns = false) + { + if (!is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key))); + } + if (!isset($key[0]) && !$ns) { + throw new InvalidArgumentException('Cache key length must be greater than zero'); + } + if (isset($key[strcspn($key, '{}()/\@:')])) { + throw new InvalidArgumentException('Cache key contains reserved characters {}()/\@:'); + } + + return $this->namespace.$key; + } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index aa2b170f4b9e5..b6ce21e1efe06 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -28,6 +28,6 @@ public function createCachePool() $this->markTestSkipped('Fails transiently on Windows.'); } - return new ApcuAdapter(__CLASS__); + return new ApcuAdapter(str_replace('\\', '.', __CLASS__)); } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/NamespacedProxyAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/NamespacedProxyAdapterTest.php new file mode 100644 index 0000000000000..28898e780ed6f --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Adapter/NamespacedProxyAdapterTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\ProxyAdapter; + +/** + * @group time-sensitive + */ +class NamespacedProxyAdapterTest extends ProxyAdapterTest +{ + public function createCachePool() + { + return new ProxyAdapter(new ArrayAdapter(), 0, 'foo'); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy