diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md index c2faae90c0b4d..981311492f1e3 100644 --- a/UPGRADE-4.3.md +++ b/UPGRADE-4.3.md @@ -8,6 +8,13 @@ BrowserKit * Deprecated `Response::buildHeader()` * Deprecated `Response::getStatus()`, use `Response::getStatusCode()` instead +Cache +----- + + * The `psr/simple-cache` dependency has been removed - run `composer require psr/simple-cache` if you need it. + * Deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead. + * Deprecated `SimpleCacheAdapter`, use `Psr16Adapter instead. + Config ------ @@ -18,6 +25,7 @@ FrameworkBundle * Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will be mandatory in 5.0. + * Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. HttpFoundation -------------- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 7e6703801bfb9..05669ffad31bb 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -13,6 +13,8 @@ Cache ----- * Removed `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead. + * Removed all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead. + * Removed `SimpleCacheAdapter`, use `Psr16Adapter instead. Config ------ @@ -163,6 +165,7 @@ FrameworkBundle * The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter. * Removed support for legacy translations directories `src/Resources/translations/` and `src/Resources//translations/`, use `translations/` instead. * Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been removed. + * Removed the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. HttpFoundation -------------- diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 435fe4224d5e3..ec9f65711cb22 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -8,6 +8,7 @@ CHANGELOG be mandatory in 5.0. * Added `ControllerTrait::isFormValid()` * Added an `help_html` form option to display the `help` text as HTML + * Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead * [BC Break] When using Messenger, the default transport changed from using Symfony's serializer service to use `PhpSerializer`, which uses diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index 488cd868f3e32..753dee0e74e80 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -11,7 +11,8 @@ - + + The "Psr\SimpleCache\CacheInterface" / "%service_id%" service is deprecated since Symfony 4.3. Use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 713a895e0e66c..de270782d9a07 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": "^7.1.3", "ext-xml": "*", - "symfony/cache": "~4.2", + "symfony/cache": "~4.3", "symfony/config": "~4.2", "symfony/contracts": "^1.0.2", "symfony/dependency-injection": "^4.2", diff --git a/src/Symfony/Component/Cache/Adapter/Psr16Adapter.php b/src/Symfony/Component/Cache/Adapter/Psr16Adapter.php new file mode 100644 index 0000000000000..a14ee082be1eb --- /dev/null +++ b/src/Symfony/Component/Cache/Adapter/Psr16Adapter.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * Turns a PSR-16 cache into a PSR-6 one. + * + * @author Nicolas Grekas + */ +class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface +{ + use ProxyTrait; + + private $miss; + + public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0) + { + parent::__construct($namespace, $defaultLifetime); + + $this->pool = $pool; + $this->miss = new \stdClass(); + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) { + if ($this->miss !== $value) { + yield $key => $value; + } + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return $this->pool->has($id); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + return $this->pool->deleteMultiple($ids); + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); + } +} diff --git a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php index 2e6d03a1f0b41..d0d42e57f0a7c 100644 --- a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php @@ -11,69 +11,11 @@ namespace Symfony\Component\Cache\Adapter; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Component\Cache\Traits\ProxyTrait; +@trigger_error(sprintf('The "%s" class is @deprecated since Symfony 4.3, use "Psr16Adapter" instead.', SimpleCacheAdapter::class), E_USER_DEPRECATED); /** - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use Psr16Adapter instead. */ -class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface, ResettableInterface +class SimpleCacheAdapter extends Psr16Adapter { - use ProxyTrait; - - private $miss; - - public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0) - { - parent::__construct($namespace, $defaultLifetime); - - $this->pool = $pool; - $this->miss = new \stdClass(); - } - - /** - * {@inheritdoc} - */ - protected function doFetch(array $ids) - { - foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) { - if ($this->miss !== $value) { - yield $key => $value; - } - } - } - - /** - * {@inheritdoc} - */ - protected function doHave($id) - { - return $this->pool->has($id); - } - - /** - * {@inheritdoc} - */ - protected function doClear($namespace) - { - return $this->pool->clear(); - } - - /** - * {@inheritdoc} - */ - protected function doDelete(array $ids) - { - return $this->pool->deleteMultiple($ids); - } - - /** - * {@inheritdoc} - */ - protected function doSave(array $values, $lifetime) - { - return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); - } } diff --git a/src/Symfony/Component/Cache/CHANGELOG.md b/src/Symfony/Component/Cache/CHANGELOG.md index 9016bc5dbfe2e..37dd2e11a0e61 100644 --- a/src/Symfony/Component/Cache/CHANGELOG.md +++ b/src/Symfony/Component/Cache/CHANGELOG.md @@ -1,6 +1,13 @@ CHANGELOG ========= +4.3.0 +----- + + * removed `psr/simple-cache` dependency, run `composer require psr/simple-cache` if you need it + * deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead + * deprecated `SimpleCacheAdapter`, use `Psr16Adapter` instead + 4.2.0 ----- diff --git a/src/Symfony/Component/Cache/Exception/CacheException.php b/src/Symfony/Component/Cache/Exception/CacheException.php index e87b2db8fe733..d2e975b2bc606 100644 --- a/src/Symfony/Component/Cache/Exception/CacheException.php +++ b/src/Symfony/Component/Cache/Exception/CacheException.php @@ -14,6 +14,12 @@ use Psr\Cache\CacheException as Psr6CacheInterface; use Psr\SimpleCache\CacheException as SimpleCacheInterface; -class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface -{ +if (interface_exists(SimpleCacheInterface::class)) { + class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface + { + } +} else { + class CacheException extends \Exception implements Psr6CacheInterface + { + } } diff --git a/src/Symfony/Component/Cache/Exception/InvalidArgumentException.php b/src/Symfony/Component/Cache/Exception/InvalidArgumentException.php index 828bf3ed77999..7f9584a264328 100644 --- a/src/Symfony/Component/Cache/Exception/InvalidArgumentException.php +++ b/src/Symfony/Component/Cache/Exception/InvalidArgumentException.php @@ -14,6 +14,12 @@ use Psr\Cache\InvalidArgumentException as Psr6CacheInterface; use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface; -class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface -{ +if (interface_exists(SimpleCacheInterface::class)) { + class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface + { + } +} else { + class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface + { + } } diff --git a/src/Symfony/Component/Cache/Exception/LogicException.php b/src/Symfony/Component/Cache/Exception/LogicException.php index d299673eb2246..9ffa7ed69566b 100644 --- a/src/Symfony/Component/Cache/Exception/LogicException.php +++ b/src/Symfony/Component/Cache/Exception/LogicException.php @@ -14,6 +14,12 @@ use Psr\Cache\CacheException as Psr6CacheInterface; use Psr\SimpleCache\CacheException as SimpleCacheInterface; -class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface -{ +if (interface_exists(SimpleCacheInterface::class)) { + class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface + { + } +} else { + class LogicException extends \LogicException implements Psr6CacheInterface + { + } } diff --git a/src/Symfony/Component/Cache/LockRegistry.php b/src/Symfony/Component/Cache/LockRegistry.php index e0318e900c4d5..3fa8bb851237c 100644 --- a/src/Symfony/Component/Cache/LockRegistry.php +++ b/src/Symfony/Component/Cache/LockRegistry.php @@ -45,6 +45,7 @@ class LockRegistry __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php', __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php', __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.php', + __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'Psr16Adapter.php', __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisAdapter.php', __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php', __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php', diff --git a/src/Symfony/Component/Cache/Psr16Cache.php b/src/Symfony/Component/Cache/Psr16Cache.php new file mode 100644 index 0000000000000..589ffa0d8b7b8 --- /dev/null +++ b/src/Symfony/Component/Cache/Psr16Cache.php @@ -0,0 +1,263 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache; + +use Psr\Cache\CacheException as Psr6CacheException; +use Psr\Cache\CacheItemPoolInterface; +use Psr\SimpleCache\CacheException as SimpleCacheException; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * Turns a PSR-6 cache into a PSR-16 one. + * + * @author Nicolas Grekas + */ +class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface +{ + use ProxyTrait; + + private const METADATA_EXPIRY_OFFSET = 1527506807; + + private $createCacheItem; + private $cacheItemPrototype; + + public function __construct(CacheItemPoolInterface $pool) + { + $this->pool = $pool; + + if (!$pool instanceof AdapterInterface) { + return; + } + $cacheItemPrototype = &$this->cacheItemPrototype; + $createCacheItem = \Closure::bind( + function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) { + $item = clone $cacheItemPrototype; + $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key); + $item->value = $value; + $item->isHit = false; + + return $item; + }, + null, + CacheItem::class + ); + $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) { + if (null === $this->cacheItemPrototype) { + $this->get($allowInt && \is_int($key) ? (string) $key : $key); + } + $this->createCacheItem = $createCacheItem; + + return $createCacheItem($key, null, $allowInt)->set($value); + }; + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + try { + $item = $this->pool->getItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + if (null === $this->cacheItemPrototype) { + $this->cacheItemPrototype = clone $item; + $this->cacheItemPrototype->set(null); + } + + return $item->isHit() ? $item->get() : $default; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + try { + if (null !== $f = $this->createCacheItem) { + $item = $f($key, $value); + } else { + $item = $this->pool->getItem($key)->set($value); + } + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + if (null !== $ttl) { + $item->expiresAfter($ttl); + } + + return $this->pool->save($item); + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + try { + return $this->pool->deleteItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + try { + $items = $this->pool->getItems($keys); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + $values = []; + + if (!$this->pool instanceof AdapterInterface) { + foreach ($items as $key => $item) { + $values[$key] = $item->isHit() ? $item->get() : $default; + } + + return $values; + } + + foreach ($items as $key => $item) { + if (!$item->isHit()) { + $values[$key] = $default; + continue; + } + $values[$key] = $item->get(); + + if (!$metadata = $item->getMetadata()) { + continue; + } + unset($metadata[CacheItem::METADATA_TAGS]); + + if ($metadata) { + $values[$key] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]]; + } + } + + return $values; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + $valuesIsArray = \is_array($values); + if (!$valuesIsArray && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values))); + } + $items = []; + + try { + if (null !== $f = $this->createCacheItem) { + $valuesIsArray = false; + foreach ($values as $key => $value) { + $items[$key] = $f($key, $value, true); + } + } elseif ($valuesIsArray) { + $items = []; + foreach ($values as $key => $value) { + $items[] = (string) $key; + } + $items = $this->pool->getItems($items); + } else { + foreach ($values as $key => $value) { + if (\is_int($key)) { + $key = (string) $key; + } + $items[$key] = $this->pool->getItem($key)->set($value); + } + } + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + $ok = true; + + foreach ($items as $key => $item) { + if ($valuesIsArray) { + $item->set($values[$key]); + } + if (null !== $ttl) { + $item->expiresAfter($ttl); + } + $ok = $this->pool->saveDeferred($item) && $ok; + } + + return $this->pool->commit() && $ok; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + try { + return $this->pool->deleteItems($keys); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + try { + return $this->pool->hasItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } +} diff --git a/src/Symfony/Component/Cache/Simple/AbstractCache.php b/src/Symfony/Component/Cache/Simple/AbstractCache.php index 7a2a3cb36e996..29fbd7719ecb8 100644 --- a/src/Symfony/Component/Cache/Simple/AbstractCache.php +++ b/src/Symfony/Component/Cache/Simple/AbstractCache.php @@ -12,16 +12,20 @@ namespace Symfony\Component\Cache\Simple; use Psr\Log\LoggerAwareInterface; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; +use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\AbstractTrait; +use Symfony\Contracts\Cache\CacheInterface; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', AbstractCache::class, AbstractAdapter::class, CacheInterface::class), E_USER_DEPRECATED); /** - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use AbstractAdapter and type-hint for CacheInterface instead. */ -abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface +abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface { use AbstractTrait { deleteItems as private; diff --git a/src/Symfony/Component/Cache/Simple/ApcuCache.php b/src/Symfony/Component/Cache/Simple/ApcuCache.php index 0877c394bbda3..c22771e8227c5 100644 --- a/src/Symfony/Component/Cache/Simple/ApcuCache.php +++ b/src/Symfony/Component/Cache/Simple/ApcuCache.php @@ -13,6 +13,11 @@ use Symfony\Component\Cache\Traits\ApcuTrait; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ApcuCache::class, ApcuAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use ApcuAdapter and type-hint for CacheInterface instead. + */ class ApcuCache extends AbstractCache { use ApcuTrait; diff --git a/src/Symfony/Component/Cache/Simple/ArrayCache.php b/src/Symfony/Component/Cache/Simple/ArrayCache.php index e36dacb829470..3df5b4990c241 100644 --- a/src/Symfony/Component/Cache/Simple/ArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/ArrayCache.php @@ -12,16 +12,20 @@ namespace Symfony\Component\Cache\Simple; use Psr\Log\LoggerAwareInterface; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\ArrayTrait; +use Symfony\Contracts\Cache\CacheInterface; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ArrayCache::class, ArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED); /** - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use ArrayAdapter and type-hint for CacheInterface instead. */ -class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface +class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface { use ArrayTrait { ArrayTrait::deleteItem as delete; diff --git a/src/Symfony/Component/Cache/Simple/ChainCache.php b/src/Symfony/Component/Cache/Simple/ChainCache.php index 18e9462ba02ad..a0122fdee9292 100644 --- a/src/Symfony/Component/Cache/Simple/ChainCache.php +++ b/src/Symfony/Component/Cache/Simple/ChainCache.php @@ -11,21 +11,25 @@ namespace Symfony\Component\Cache\Simple; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; +use Symfony\Component\Cache\Adapter\ChainAdapter; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Service\ResetInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ChainCache::class, ChainAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + /** * Chains several caches together. * * Cached items are fetched from the first cache having them in its data store. * They are saved and deleted in all caches at once. * - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use ChainAdapter and type-hint for CacheInterface instead. */ -class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface +class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface { private $miss; private $caches = []; @@ -33,8 +37,8 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf private $cacheCount; /** - * @param CacheInterface[] $caches The ordered list of caches used to fetch cached items - * @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones + * @param Psr16CacheInterface[] $caches The ordered list of caches used to fetch cached items + * @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones */ public function __construct(array $caches, int $defaultLifetime = 0) { @@ -43,8 +47,8 @@ public function __construct(array $caches, int $defaultLifetime = 0) } foreach ($caches as $cache) { - if (!$cache instanceof CacheInterface) { - throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class)); + if (!$cache instanceof Psr16CacheInterface) { + throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), Psr16CacheInterface::class)); } } diff --git a/src/Symfony/Component/Cache/Simple/DoctrineCache.php b/src/Symfony/Component/Cache/Simple/DoctrineCache.php index 0ba701d7cd9a6..6a6d0031533e8 100644 --- a/src/Symfony/Component/Cache/Simple/DoctrineCache.php +++ b/src/Symfony/Component/Cache/Simple/DoctrineCache.php @@ -12,8 +12,15 @@ namespace Symfony\Component\Cache\Simple; use Doctrine\Common\Cache\CacheProvider; +use Symfony\Component\Cache\Adapter\DoctrineAdapter; use Symfony\Component\Cache\Traits\DoctrineTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', DoctrineCache::class, DoctrineAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use DoctrineAdapter and type-hint for CacheInterface instead. + */ class DoctrineCache extends AbstractCache { use DoctrineTrait; diff --git a/src/Symfony/Component/Cache/Simple/FilesystemCache.php b/src/Symfony/Component/Cache/Simple/FilesystemCache.php index 8e04d533556ef..8891abd94c9fe 100644 --- a/src/Symfony/Component/Cache/Simple/FilesystemCache.php +++ b/src/Symfony/Component/Cache/Simple/FilesystemCache.php @@ -11,11 +11,18 @@ namespace Symfony\Component\Cache\Simple; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Marshaller\DefaultMarshaller; use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Traits\FilesystemTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', FilesystemCache::class, FilesystemAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use FilesystemAdapter and type-hint for CacheInterface instead. + */ class FilesystemCache extends AbstractCache implements PruneableInterface { use FilesystemTrait; diff --git a/src/Symfony/Component/Cache/Simple/MemcachedCache.php b/src/Symfony/Component/Cache/Simple/MemcachedCache.php index 8e418b071e632..e1934119aa74a 100644 --- a/src/Symfony/Component/Cache/Simple/MemcachedCache.php +++ b/src/Symfony/Component/Cache/Simple/MemcachedCache.php @@ -11,9 +11,16 @@ namespace Symfony\Component\Cache\Simple; +use Symfony\Component\Cache\Adapter\MemcachedAdapter; use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\Traits\MemcachedTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', MemcachedCache::class, MemcachedAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use MemcachedAdapter and type-hint for CacheInterface instead. + */ class MemcachedCache extends AbstractCache { use MemcachedTrait; diff --git a/src/Symfony/Component/Cache/Simple/NullCache.php b/src/Symfony/Component/Cache/Simple/NullCache.php index fa986aebd11b0..d1ca6f71873b0 100644 --- a/src/Symfony/Component/Cache/Simple/NullCache.php +++ b/src/Symfony/Component/Cache/Simple/NullCache.php @@ -11,12 +11,16 @@ namespace Symfony\Component\Cache\Simple; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; +use Symfony\Components\Cache\Adapter\NullAdapter; +use Symfony\Contracts\Cache\CacheInterface; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', NullCache::class, NullAdapter::class, CacheInterface::class), E_USER_DEPRECATED); /** - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use NullAdapter and type-hint for CacheInterface instead. */ -class NullCache implements CacheInterface +class NullCache implements Psr16CacheInterface { /** * {@inheritdoc} diff --git a/src/Symfony/Component/Cache/Simple/PdoCache.php b/src/Symfony/Component/Cache/Simple/PdoCache.php index 521e9b8f2d7f5..07849e93feb9a 100644 --- a/src/Symfony/Component/Cache/Simple/PdoCache.php +++ b/src/Symfony/Component/Cache/Simple/PdoCache.php @@ -11,10 +11,17 @@ namespace Symfony\Component\Cache\Simple; +use Symfony\Component\Cache\Adapter\PdoAdapter; use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Traits\PdoTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PdoCache::class, PdoAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use PdoAdapter and type-hint for CacheInterface instead. + */ class PdoCache extends AbstractCache implements PruneableInterface { use PdoTrait; diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index 6ba8527885e32..566609359d568 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -11,28 +11,28 @@ namespace Symfony\Component\Cache\Simple; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\PhpArrayTrait; +use Symfony\Contracts\Cache\CacheInterface; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpArrayCache::class, PhpArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED); /** - * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. - * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter. - * - * @author Titouan Galopin - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead. */ -class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface +class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface { use PhpArrayTrait; /** - * @param string $file The PHP file were values are cached - * @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit + * @param string $file The PHP file were values are cached + * @param Psr16CacheInterface $fallbackPool A pool to fallback on when an item is not hit */ - public function __construct(string $file, CacheInterface $fallbackPool) + public function __construct(string $file, Psr16CacheInterface $fallbackPool) { $this->file = $file; $this->pool = $fallbackPool; @@ -43,9 +43,9 @@ public function __construct(string $file, CacheInterface $fallbackPool) * * @param string $file The PHP file were values are cached * - * @return CacheInterface + * @return Psr16CacheInterface */ - public static function create($file, CacheInterface $fallbackPool) + public static function create($file, Psr16CacheInterface $fallbackPool) { // Shared memory is available in PHP 7.0+ with OPCache enabled if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) { diff --git a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php index 37432c5af8e4b..060244a086643 100644 --- a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php @@ -11,10 +11,17 @@ namespace Symfony\Component\Cache\Simple; +use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\Cache\Exception\CacheException; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Traits\PhpFilesTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpFilesCache::class, PhpFilesAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use PhpFilesAdapter and type-hint for CacheInterface instead. + */ class PhpFilesCache extends AbstractCache implements PruneableInterface { use PhpFilesTrait; diff --git a/src/Symfony/Component/Cache/Simple/Psr6Cache.php b/src/Symfony/Component/Cache/Simple/Psr6Cache.php index fceb9ba70fd80..090f48c172860 100644 --- a/src/Symfony/Component/Cache/Simple/Psr6Cache.php +++ b/src/Symfony/Component/Cache/Simple/Psr6Cache.php @@ -11,254 +11,13 @@ namespace Symfony\Component\Cache\Simple; -use Psr\Cache\CacheException as Psr6CacheException; -use Psr\Cache\CacheItemPoolInterface; -use Psr\SimpleCache\CacheException as SimpleCacheException; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Component\Cache\Traits\ProxyTrait; +use Symfony\Component\Cache\Psr16Cache; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Psr6Cache::class, Psr16Cache::class), E_USER_DEPRECATED); /** - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use Psr16Cache instead. */ -class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface +class Psr6Cache extends Psr16Cache { - use ProxyTrait; - - private const METADATA_EXPIRY_OFFSET = 1527506807; - - private $createCacheItem; - private $cacheItemPrototype; - - public function __construct(CacheItemPoolInterface $pool) - { - $this->pool = $pool; - - if (!$pool instanceof AdapterInterface) { - return; - } - $cacheItemPrototype = &$this->cacheItemPrototype; - $createCacheItem = \Closure::bind( - function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) { - $item = clone $cacheItemPrototype; - $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key); - $item->value = $value; - $item->isHit = false; - - return $item; - }, - null, - CacheItem::class - ); - $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) { - if (null === $this->cacheItemPrototype) { - $this->get($allowInt && \is_int($key) ? (string) $key : $key); - } - $this->createCacheItem = $createCacheItem; - - return $createCacheItem($key, null, $allowInt)->set($value); - }; - } - - /** - * {@inheritdoc} - */ - public function get($key, $default = null) - { - try { - $item = $this->pool->getItem($key); - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - if (null === $this->cacheItemPrototype) { - $this->cacheItemPrototype = clone $item; - $this->cacheItemPrototype->set(null); - } - - return $item->isHit() ? $item->get() : $default; - } - - /** - * {@inheritdoc} - */ - public function set($key, $value, $ttl = null) - { - try { - if (null !== $f = $this->createCacheItem) { - $item = $f($key, $value); - } else { - $item = $this->pool->getItem($key)->set($value); - } - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - if (null !== $ttl) { - $item->expiresAfter($ttl); - } - - return $this->pool->save($item); - } - - /** - * {@inheritdoc} - */ - public function delete($key) - { - try { - return $this->pool->deleteItem($key); - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * {@inheritdoc} - */ - public function clear() - { - return $this->pool->clear(); - } - - /** - * {@inheritdoc} - */ - public function getMultiple($keys, $default = null) - { - if ($keys instanceof \Traversable) { - $keys = iterator_to_array($keys, false); - } elseif (!\is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys))); - } - - try { - $items = $this->pool->getItems($keys); - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - $values = []; - - if (!$this->pool instanceof AdapterInterface) { - foreach ($items as $key => $item) { - $values[$key] = $item->isHit() ? $item->get() : $default; - } - - return $values; - } - - foreach ($items as $key => $item) { - if (!$item->isHit()) { - $values[$key] = $default; - continue; - } - $values[$key] = $item->get(); - - if (!$metadata = $item->getMetadata()) { - continue; - } - unset($metadata[CacheItem::METADATA_TAGS]); - - if ($metadata) { - $values[$key] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]]; - } - } - - return $values; - } - - /** - * {@inheritdoc} - */ - public function setMultiple($values, $ttl = null) - { - $valuesIsArray = \is_array($values); - if (!$valuesIsArray && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values))); - } - $items = []; - - try { - if (null !== $f = $this->createCacheItem) { - $valuesIsArray = false; - foreach ($values as $key => $value) { - $items[$key] = $f($key, $value, true); - } - } elseif ($valuesIsArray) { - $items = []; - foreach ($values as $key => $value) { - $items[] = (string) $key; - } - $items = $this->pool->getItems($items); - } else { - foreach ($values as $key => $value) { - if (\is_int($key)) { - $key = (string) $key; - } - $items[$key] = $this->pool->getItem($key)->set($value); - } - } - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - $ok = true; - - foreach ($items as $key => $item) { - if ($valuesIsArray) { - $item->set($values[$key]); - } - if (null !== $ttl) { - $item->expiresAfter($ttl); - } - $ok = $this->pool->saveDeferred($item) && $ok; - } - - return $this->pool->commit() && $ok; - } - - /** - * {@inheritdoc} - */ - public function deleteMultiple($keys) - { - if ($keys instanceof \Traversable) { - $keys = iterator_to_array($keys, false); - } elseif (!\is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys))); - } - - try { - return $this->pool->deleteItems($keys); - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * {@inheritdoc} - */ - public function has($key) - { - try { - return $this->pool->hasItem($key); - } catch (SimpleCacheException $e) { - throw $e; - } catch (Psr6CacheException $e) { - throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); - } - } } diff --git a/src/Symfony/Component/Cache/Simple/RedisCache.php b/src/Symfony/Component/Cache/Simple/RedisCache.php index df2a96e86b580..2933bf15b3b52 100644 --- a/src/Symfony/Component/Cache/Simple/RedisCache.php +++ b/src/Symfony/Component/Cache/Simple/RedisCache.php @@ -11,9 +11,16 @@ namespace Symfony\Component\Cache\Simple; +use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\Traits\RedisTrait; +use Symfony\Contracts\Cache\CacheInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', RedisCache::class, RedisAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + +/** + * @deprecated since Symfony 4.3, use RedisAdapter and type-hint for CacheInterface instead. + */ class RedisCache extends AbstractCache { use RedisTrait; diff --git a/src/Symfony/Component/Cache/Simple/TraceableCache.php b/src/Symfony/Component/Cache/Simple/TraceableCache.php index 2db335ac968a1..ad9bfcf09ca60 100644 --- a/src/Symfony/Component/Cache/Simple/TraceableCache.php +++ b/src/Symfony/Component/Cache/Simple/TraceableCache.php @@ -11,23 +11,24 @@ namespace Symfony\Component\Cache\Simple; -use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\CacheInterface as Psr16CacheInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Service\ResetInterface; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', TraceableCache::class, TraceableAdapter::class, CacheInterface::class), E_USER_DEPRECATED); + /** - * An adapter that collects data about all cache calls. - * - * @author Nicolas Grekas + * @deprecated since Symfony 4.3, use TraceableAdapter and type-hint for CacheInterface instead. */ -class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface +class TraceableCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface { private $pool; private $miss; private $calls = []; - public function __construct(CacheInterface $pool) + public function __construct(Psr16CacheInterface $pool) { $this->pool = $pool; $this->miss = new \stdClass(); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/Psr16AdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/Psr16AdapterTest.php new file mode 100644 index 0000000000000..19907ddf78733 --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Adapter/Psr16AdapterTest.php @@ -0,0 +1,31 @@ + + * + * 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\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\Psr16Adapter; +use Symfony\Component\Cache\Psr16Cache; + +/** + * @group time-sensitive + */ +class Psr16AdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testPrune' => 'Psr16adapter just proxies', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new Psr16Adapter(new Psr16Cache(new FilesystemAdapter()), '', $defaultLifetime); + } +} diff --git a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php index 3028af47c6f2a..b11f72d5a395b 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -11,12 +11,12 @@ namespace Symfony\Component\Cache\Tests\Adapter; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; -use Symfony\Component\Cache\Simple\Psr6Cache; +use Symfony\Component\Cache\Simple\FilesystemCache; /** * @group time-sensitive + * @group legacy */ class SimpleCacheAdapterTest extends AdapterTestCase { @@ -26,6 +26,6 @@ class SimpleCacheAdapterTest extends AdapterTestCase public function createCachePool($defaultLifetime = 0) { - return new SimpleCacheAdapter(new Psr6Cache(new FilesystemAdapter()), '', $defaultLifetime); + return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); } } diff --git a/src/Symfony/Component/Cache/Tests/Psr16CacheTest.php b/src/Symfony/Component/Cache/Tests/Psr16CacheTest.php new file mode 100644 index 0000000000000..8fb10f237286b --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Psr16CacheTest.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests; + +use Cache\IntegrationTests\SimpleCacheTest; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Psr16Cache; + +/** + * @group time-sensitive + */ +class Psr16CacheTest extends SimpleCacheTest +{ + protected function setUp() + { + parent::setUp(); + + if (array_key_exists('testPrune', $this->skippedTests)) { + return; + } + + $pool = $this->createSimpleCache(); + if ($pool instanceof Psr16Cache) { + $pool = ((array) $pool)[sprintf("\0%s\0pool", Psr16Cache::class)]; + } + + if (!$pool instanceof PruneableInterface) { + $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; + } + } + + public function createSimpleCache($defaultLifetime = 0) + { + return new Psr16Cache(new FilesystemAdapter('', $defaultLifetime)); + } + + public static function validKeys() + { + return array_merge(parent::validKeys(), [["a\0b"]]); + } + + public function testDefaultLifeTime() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createSimpleCache(2); + $cache->clear(); + + $cache->set('key.dlt', 'value'); + sleep(1); + + $this->assertSame('value', $cache->get('key.dlt')); + + sleep(2); + $this->assertNull($cache->get('key.dlt')); + + $cache->clear(); + } + + public function testNotUnserializable() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createSimpleCache(); + $cache->clear(); + + $cache->set('foo', new NotUnserializable()); + + $this->assertNull($cache->get('foo')); + + $cache->setMultiple(['foo' => new NotUnserializable()]); + + foreach ($cache->getMultiple(['foo']) as $value) { + } + $this->assertNull($value); + + $cache->clear(); + } + + public function testPrune() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + /** @var PruneableInterface|CacheInterface $cache */ + $cache = $this->createSimpleCache(); + $cache->clear(); + + $cache->set('foo', 'foo-val', new \DateInterval('PT05S')); + $cache->set('bar', 'bar-val', new \DateInterval('PT10S')); + $cache->set('baz', 'baz-val', new \DateInterval('PT15S')); + $cache->set('qux', 'qux-val', new \DateInterval('PT20S')); + + sleep(30); + $cache->prune(); + $this->assertTrue($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertTrue($this->isPruned($cache, 'qux')); + + $cache->set('foo', 'foo-val'); + $cache->set('bar', 'bar-val', new \DateInterval('PT20S')); + $cache->set('baz', 'baz-val', new \DateInterval('PT40S')); + $cache->set('qux', 'qux-val', new \DateInterval('PT80S')); + + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertFalse($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'qux')); + + $cache->clear(); + } + + protected function isPruned($cache, $name) + { + if (Psr16Cache::class !== \get_class($cache)) { + $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); + } + + $pool = ((array) $cache)[sprintf("\0%s\0pool", Psr16Cache::class)]; + $getFileMethod = (new \ReflectionObject($pool))->getMethod('getFile'); + $getFileMethod->setAccessible(true); + + return !file_exists($getFileMethod->invoke($pool, $name)); + } +} + +class NotUnserializable implements \Serializable +{ + public function serialize() + { + return serialize(123); + } + + public function unserialize($ser) + { + throw new \Exception(__CLASS__); + } +} diff --git a/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php index dd5e1509c1bcc..a9f5d98b92a44 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php @@ -13,6 +13,9 @@ use Symfony\Component\Cache\Simple\RedisCache; +/** + * @group legacy + */ abstract class AbstractRedisCacheTest extends CacheTestCase { protected $skippedTests = [ diff --git a/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php index f37b95a093fad..b3220946038cd 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/ApcuCacheTest.php @@ -13,6 +13,9 @@ use Symfony\Component\Cache\Simple\ApcuCache; +/** + * @group legacy + */ class ApcuCacheTest extends CacheTestCase { protected $skippedTests = [ diff --git a/src/Symfony/Component/Cache/Tests/Simple/ArrayCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/ArrayCacheTest.php index 26c3e14d0965c..587304a5db1c4 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/ArrayCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/ArrayCacheTest.php @@ -15,6 +15,7 @@ /** * @group time-sensitive + * @group legacy */ class ArrayCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/ChainCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/ChainCacheTest.php index e6f7c7cc63229..806bb7633b222 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/ChainCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/ChainCacheTest.php @@ -19,6 +19,7 @@ /** * @group time-sensitive + * @group legacy */ class ChainCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/DoctrineCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/DoctrineCacheTest.php index af4331d69b5a0..5d78c00cac841 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/DoctrineCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/DoctrineCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class DoctrineCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/FilesystemCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/FilesystemCacheTest.php index 620305a58a44e..9f423ba641c93 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/FilesystemCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/FilesystemCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class FilesystemCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php index f83f0a2e34527..692259296f21d 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTest.php @@ -14,6 +14,9 @@ use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\Simple\MemcachedCache; +/** + * @group legacy + */ class MemcachedCacheTest extends CacheTestCase { protected $skippedTests = [ diff --git a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php index 13865a6098e17..d68131a1db7bd 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php @@ -14,6 +14,9 @@ use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\Simple\MemcachedCache; +/** + * @group legacy + */ class MemcachedCacheTextModeTest extends MemcachedCacheTest { public function createSimpleCache($defaultLifetime = 0) diff --git a/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php index 31f42c32b6a8c..cf0dde92b33f4 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class NullCacheTest extends TestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php index 665db09f672a0..fbdf03be7ee50 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PdoCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class PdoCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/PdoDbalCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PdoDbalCacheTest.php index ce1a9ae4f8c6e..af5c42340b4fc 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PdoDbalCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PdoDbalCacheTest.php @@ -17,6 +17,7 @@ /** * @group time-sensitive + * @group legacy */ class PdoDbalCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php index ba4bde3139517..5272604dc32cf 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php @@ -17,6 +17,7 @@ /** * @group time-sensitive + * @group legacy */ class PhpArrayCacheTest extends CacheTestCase { @@ -127,35 +128,3 @@ public function testStoredFile() $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); } } - -class PhpArrayCacheWrapper extends PhpArrayCache -{ - protected $data = []; - - public function set($key, $value, $ttl = null) - { - (\Closure::bind(function () use ($key, $value) { - $this->data[$key] = $value; - $this->warmUp($this->data); - list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class))(); - - return true; - } - - public function setMultiple($values, $ttl = null) - { - if (!\is_array($values) && !$values instanceof \Traversable) { - return parent::setMultiple($values, $ttl); - } - (\Closure::bind(function () use ($values) { - foreach ($values as $key => $value) { - $this->data[$key] = $value; - } - $this->warmUp($this->data); - list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class))(); - - return true; - } -} diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php index abee5e7872164..90aa7bb6ef835 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php @@ -17,6 +17,7 @@ /** * @group time-sensitive + * @group legacy */ class PhpArrayCacheWithFallbackTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php new file mode 100644 index 0000000000000..1e102fe1ff2e3 --- /dev/null +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWrapper.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\PhpArrayCache; + +class PhpArrayCacheWrapper extends PhpArrayCache +{ + protected $data = []; + + public function set($key, $value, $ttl = null) + { + (\Closure::bind(function () use ($key, $value) { + $this->data[$key] = $value; + $this->warmUp($this->data); + list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); + }, $this, PhpArrayCache::class))(); + + return true; + } + + public function setMultiple($values, $ttl = null) + { + if (!\is_array($values) && !$values instanceof \Traversable) { + return parent::setMultiple($values, $ttl); + } + (\Closure::bind(function () use ($values) { + foreach ($values as $key => $value) { + $this->data[$key] = $value; + } + $this->warmUp($this->data); + list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6)); + }, $this, PhpArrayCache::class))(); + + return true; + } +} diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpFilesCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpFilesCacheTest.php index 3a68dd39842e7..7e40df7de5fbd 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpFilesCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpFilesCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class PhpFilesCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php index 65d48a978c503..9fff36e402dee 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php @@ -13,6 +13,9 @@ use Symfony\Component\Cache\Simple\Psr6Cache; +/** + * @group legacy + */ abstract class Psr6CacheTest extends CacheTestCase { protected $skippedTests = [ diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php index 46da9354d6db5..e5c7a6a4c7e9a 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithAdapterTest.php @@ -15,6 +15,7 @@ /** * @group time-sensitive + * @group legacy */ class Psr6CacheWithAdapterTest extends Psr6CacheTest { diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php index a8c4164dcbb1d..f987d405396c6 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php @@ -15,6 +15,7 @@ /** * @group time-sensitive + * @group legacy */ class Psr6CacheWithoutAdapterTest extends Psr6CacheTest { diff --git a/src/Symfony/Component/Cache/Tests/Simple/RedisArrayCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/RedisArrayCacheTest.php index bda39d990bcb3..b52f5f9acde9f 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/RedisArrayCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/RedisArrayCacheTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Cache\Tests\Simple; +/** + * @group legacy + */ class RedisArrayCacheTest extends AbstractRedisCacheTest { public static function setupBeforeClass() diff --git a/src/Symfony/Component/Cache/Tests/Simple/RedisCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/RedisCacheTest.php index 407d916c7317c..ddb674b285dda 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/RedisCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/RedisCacheTest.php @@ -13,6 +13,9 @@ use Symfony\Component\Cache\Simple\RedisCache; +/** + * @group legacy + */ class RedisCacheTest extends AbstractRedisCacheTest { public static function setupBeforeClass() diff --git a/src/Symfony/Component/Cache/Tests/Simple/RedisClusterCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/RedisClusterCacheTest.php index 99d4e518fb409..33c7acae0b822 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/RedisClusterCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/RedisClusterCacheTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Cache\Tests\Simple; +/** + * @group legacy + */ class RedisClusterCacheTest extends AbstractRedisCacheTest { public static function setupBeforeClass() diff --git a/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php index e684caf36e8f9..c2e8a477b4771 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php @@ -16,6 +16,7 @@ /** * @group time-sensitive + * @group legacy */ class TraceableCacheTest extends CacheTestCase { diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index c11af6d8f19af..f9b5e18381795 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -24,7 +24,6 @@ "php": "^7.1.3", "psr/cache": "~1.0", "psr/log": "~1.0", - "psr/simple-cache": "^1.0", "symfony/contracts": "^1.0", "symfony/var-exporter": "^4.2" }, @@ -33,6 +32,7 @@ "doctrine/cache": "~1.6", "doctrine/dbal": "~2.5", "predis/predis": "~1.1", + "psr/simple-cache": "^1.0", "symfony/config": "~4.2", "symfony/dependency-injection": "~3.4|~4.1", "symfony/var-dumper": "^4.1.1" 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