summaryrefslogtreecommitdiff
path: root/vendor/symfony/cache
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/cache')
-rw-r--r--vendor/symfony/cache/Adapter/AbstractAdapter.php120
-rw-r--r--vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php305
-rw-r--r--vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php149
-rw-r--r--vendor/symfony/cache/Adapter/Psr16Adapter.php81
-rw-r--r--vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php209
-rw-r--r--vendor/symfony/cache/Adapter/SimpleCacheAdapter.php63
-rw-r--r--vendor/symfony/cache/CHANGELOG.md7
-rw-r--r--vendor/symfony/cache/DependencyInjection/CachePoolPass.php10
-rw-r--r--vendor/symfony/cache/Exception/CacheException.php10
-rw-r--r--vendor/symfony/cache/Exception/InvalidArgumentException.php10
-rw-r--r--vendor/symfony/cache/Exception/LogicException.php10
-rw-r--r--vendor/symfony/cache/LockRegistry.php11
-rw-r--r--vendor/symfony/cache/Psr16Cache.php263
-rw-r--r--vendor/symfony/cache/Simple/AbstractCache.php19
-rw-r--r--vendor/symfony/cache/Simple/ApcuCache.php5
-rw-r--r--vendor/symfony/cache/Simple/ArrayCache.php10
-rw-r--r--vendor/symfony/cache/Simple/ChainCache.php18
-rw-r--r--vendor/symfony/cache/Simple/DoctrineCache.php7
-rw-r--r--vendor/symfony/cache/Simple/FilesystemCache.php7
-rw-r--r--vendor/symfony/cache/Simple/MemcachedCache.php7
-rw-r--r--vendor/symfony/cache/Simple/NullCache.php10
-rw-r--r--vendor/symfony/cache/Simple/PdoCache.php7
-rw-r--r--vendor/symfony/cache/Simple/PhpArrayCache.php24
-rw-r--r--vendor/symfony/cache/Simple/PhpFilesCache.php7
-rw-r--r--vendor/symfony/cache/Simple/Psr6Cache.php251
-rw-r--r--vendor/symfony/cache/Simple/RedisCache.php7
-rw-r--r--vendor/symfony/cache/Simple/TraceableCache.php13
-rw-r--r--vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php29
-rw-r--r--vendor/symfony/cache/Tests/Adapter/FilesystemTagAwareAdapterTest.php28
-rw-r--r--vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Adapter/PredisTagAwareAdapterTest.php34
-rw-r--r--vendor/symfony/cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php34
-rw-r--r--vendor/symfony/cache/Tests/Adapter/PredisTagAwareRedisClusterAdapterTest.php34
-rw-r--r--vendor/symfony/cache/Tests/Adapter/Psr16AdapterTest.php31
-rw-r--r--vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php25
-rw-r--r--vendor/symfony/cache/Tests/Adapter/RedisTagAwareAdapterTest.php35
-rw-r--r--vendor/symfony/cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php34
-rw-r--r--vendor/symfony/cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php35
-rw-r--r--vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php6
-rw-r--r--vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php122
-rw-r--r--vendor/symfony/cache/Tests/DependencyInjection/CachePoolPassTest.php22
-rw-r--r--vendor/symfony/cache/Tests/Psr16CacheTest.php168
-rw-r--r--vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/CacheTestCase.php9
-rw-r--r--vendor/symfony/cache/Tests/Simple/ChainCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/NullCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/PdoCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php33
-rw-r--r--vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/PhpArrayCacheWrapper.php46
-rw-r--r--vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/Psr6CacheWithAdapterTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/RedisCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php3
-rw-r--r--vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php1
-rw-r--r--vendor/symfony/cache/Tests/Traits/TagAwareTestTrait.php160
-rw-r--r--vendor/symfony/cache/Traits/AbstractAdapterTrait.php139
-rw-r--r--vendor/symfony/cache/Traits/AbstractTrait.php7
-rw-r--r--vendor/symfony/cache/Traits/ArrayTrait.php5
-rw-r--r--vendor/symfony/cache/Traits/ContractsTrait.php19
-rw-r--r--vendor/symfony/cache/Traits/FilesystemCommonTrait.php4
-rw-r--r--vendor/symfony/cache/Traits/RedisTrait.php63
-rw-r--r--vendor/symfony/cache/composer.json9
-rw-r--r--vendor/symfony/cache/phpunit.xml.dist3
74 files changed, 2128 insertions, 683 deletions
diff --git a/vendor/symfony/cache/Adapter/AbstractAdapter.php b/vendor/symfony/cache/Adapter/AbstractAdapter.php
index 6897fbceee..883a94ba9b 100644
--- a/vendor/symfony/cache/Adapter/AbstractAdapter.php
+++ b/vendor/symfony/cache/Adapter/AbstractAdapter.php
@@ -11,14 +11,13 @@
namespace Symfony\Component\Cache\Adapter;
-use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\ResettableInterface;
-use Symfony\Component\Cache\Traits\AbstractTrait;
+use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Contracts\Cache\CacheInterface;
@@ -27,15 +26,12 @@ use Symfony\Contracts\Cache\CacheInterface;
*/
abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
{
- use AbstractTrait;
+ use AbstractAdapterTrait;
use ContractsTrait;
private static $apcuSupported;
private static $phpFilesSupported;
- private $createCacheItem;
- private $mergeByLifetime;
-
protected function __construct(string $namespace = '', int $defaultLifetime = 0)
{
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
@@ -132,7 +128,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
if (!\is_string($dsn)) {
throw new InvalidArgumentException(sprintf('The %s() method expect argument #1 to be string, %s given.', __METHOD__, \gettype($dsn)));
}
- if (0 === strpos($dsn, 'redis:')) {
+ if (0 === strpos($dsn, 'redis:') || 0 === strpos($dsn, 'rediss:')) {
return RedisAdapter::createConnection($dsn, $options);
}
if (0 === strpos($dsn, 'memcached:')) {
@@ -145,81 +141,6 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
/**
* {@inheritdoc}
*/
- public function getItem($key)
- {
- if ($this->deferred) {
- $this->commit();
- }
- $id = $this->getId($key);
-
- $f = $this->createCacheItem;
- $isHit = false;
- $value = null;
-
- try {
- foreach ($this->doFetch([$id]) as $value) {
- $isHit = true;
- }
- } catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
- }
-
- return $f($key, $value, $isHit);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getItems(array $keys = [])
- {
- if ($this->deferred) {
- $this->commit();
- }
- $ids = [];
-
- foreach ($keys as $key) {
- $ids[] = $this->getId($key);
- }
- try {
- $items = $this->doFetch($ids);
- } catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]);
- $items = [];
- }
- $ids = array_combine($ids, $keys);
-
- return $this->generateItems($items, $ids);
- }
-
- /**
- * {@inheritdoc}
- */
- public function save(CacheItemInterface $item)
- {
- if (!$item instanceof CacheItem) {
- return false;
- }
- $this->deferred[$item->getKey()] = $item;
-
- return $this->commit();
- }
-
- /**
- * {@inheritdoc}
- */
- public function saveDeferred(CacheItemInterface $item)
- {
- if (!$item instanceof CacheItem) {
- return false;
- }
- $this->deferred[$item->getKey()] = $item;
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
public function commit()
{
$ok = true;
@@ -243,7 +164,8 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
$ok = false;
$v = $values[$id];
$type = \is_object($v) ? \get_class($v) : \gettype($v);
- CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]);
+ $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
}
} else {
foreach ($values as $id => $v) {
@@ -265,39 +187,11 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
}
$ok = false;
$type = \is_object($v) ? \get_class($v) : \gettype($v);
- CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]);
+ $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
}
}
return $ok;
}
-
- public function __destruct()
- {
- if ($this->deferred) {
- $this->commit();
- }
- }
-
- private function generateItems($items, &$keys)
- {
- $f = $this->createCacheItem;
-
- try {
- foreach ($items as $id => $value) {
- if (!isset($keys[$id])) {
- $id = key($keys);
- }
- $key = $keys[$id];
- unset($keys[$id]);
- yield $key => $f($key, $value, true);
- }
- } catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]);
- }
-
- foreach ($keys as $key) {
- yield $key => $f($key, null, false);
- }
- }
}
diff --git a/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php b/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php
new file mode 100644
index 0000000000..2eb5ce8c6e
--- /dev/null
+++ b/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php
@@ -0,0 +1,305 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\Log\LoggerAwareInterface;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Component\Cache\Traits\AbstractAdapterTrait;
+use Symfony\Component\Cache\Traits\ContractsTrait;
+use Symfony\Contracts\Cache\TagAwareCacheInterface;
+
+/**
+ * Abstract for native TagAware adapters.
+ *
+ * To keep info on tags, the tags are both serialized as part of cache value and provided as tag ids
+ * to Adapters on operations when needed for storage to doSave(), doDelete() & doInvalidate().
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author André Rømcke <andre.romcke+symfony@gmail.com>
+ *
+ * @internal
+ * @experimental in 4.3
+ */
+abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface
+{
+ use AbstractAdapterTrait;
+ use ContractsTrait;
+
+ private const TAGS_PREFIX = "\0tags\0";
+
+ protected function __construct(string $namespace = '', int $defaultLifetime = 0)
+ {
+ $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
+ if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
+ throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace));
+ }
+ $this->createCacheItem = \Closure::bind(
+ static function ($key, $value, $isHit) use ($defaultLifetime) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->defaultLifetime = $defaultLifetime;
+ $item->isTaggable = true;
+ // If structure does not match what we expect return item as is (no value and not a hit)
+ if (!\is_array($value) || !\array_key_exists('value', $value)) {
+ return $item;
+ }
+ $item->isHit = $isHit;
+ // Extract value, tags and meta data from the cache value
+ $item->value = $value['value'];
+ $item->metadata[CacheItem::METADATA_TAGS] = $value['tags'] ?? [];
+ if (isset($value['meta'])) {
+ // For compactness these values are packed, & expiry is offset to reduce size
+ $v = \unpack('Ve/Nc', $value['meta']);
+ $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
+ $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
+ }
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ $getId = \Closure::fromCallable([$this, 'getId']);
+ $tagPrefix = self::TAGS_PREFIX;
+ $this->mergeByLifetime = \Closure::bind(
+ static function ($deferred, &$expiredIds) use ($getId, $tagPrefix) {
+ $byLifetime = [];
+ $now = microtime(true);
+ $expiredIds = [];
+
+ foreach ($deferred as $key => $item) {
+ $key = (string) $key;
+ if (null === $item->expiry) {
+ $ttl = 0 < $item->defaultLifetime ? $item->defaultLifetime : 0;
+ } elseif (0 >= $ttl = (int) ($item->expiry - $now)) {
+ $expiredIds[] = $getId($key);
+ continue;
+ }
+ // Store Value and Tags on the cache value
+ if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) {
+ $value = ['value' => $item->value, 'tags' => $metadata[CacheItem::METADATA_TAGS]];
+ unset($metadata[CacheItem::METADATA_TAGS]);
+ } else {
+ $value = ['value' => $item->value, 'tags' => []];
+ }
+
+ if ($metadata) {
+ // For compactness, expiry and creation duration are packed, using magic numbers as separators
+ $value['meta'] = \pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - CacheItem::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME]);
+ }
+
+ // Extract tag changes, these should be removed from values in doSave()
+ $value['tag-operations'] = ['add' => [], 'remove' => []];
+ $oldTags = $item->metadata[CacheItem::METADATA_TAGS] ?? [];
+ foreach (\array_diff($value['tags'], $oldTags) as $addedTag) {
+ $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag);
+ }
+ foreach (\array_diff($oldTags, $value['tags']) as $removedTag) {
+ $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag);
+ }
+
+ $byLifetime[$ttl][$getId($key)] = $value;
+ }
+
+ return $byLifetime;
+ },
+ null,
+ CacheItem::class
+ );
+ }
+
+ /**
+ * Persists several cache items immediately.
+ *
+ * @param array $values The values to cache, indexed by their cache identifier
+ * @param int $lifetime The lifetime of the cached values, 0 for persisting until manual cleaning
+ * @param array[] $addTagData Hash where key is tag id, and array value is list of cache id's to add to tag
+ * @param array[] $removeTagData Hash where key is tag id, and array value is list of cache id's to remove to tag
+ *
+ * @return array The identifiers that failed to be cached or a boolean stating if caching succeeded or not
+ */
+ abstract protected function doSave(array $values, ?int $lifetime, array $addTagData = [], array $removeTagData = []): array;
+
+ /**
+ * Removes multiple items from the pool and their corresponding tags.
+ *
+ * @param array $ids An array of identifiers that should be removed from the pool
+ * @param array $tagData Optional array of tag identifiers => key identifiers that should be removed from the pool
+ *
+ * @return bool True if the items were successfully removed, false otherwise
+ */
+ abstract protected function doDelete(array $ids, array $tagData = []): bool;
+
+ /**
+ * Invalidates cached items using tags.
+ *
+ * @param string[] $tagIds An array of tags to invalidate, key is tag and value is tag id
+ *
+ * @return bool True on success
+ */
+ abstract protected function doInvalidate(array $tagIds): bool;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ $ok = true;
+ $byLifetime = $this->mergeByLifetime;
+ $byLifetime = $byLifetime($this->deferred, $expiredIds);
+ $retry = $this->deferred = [];
+
+ if ($expiredIds) {
+ // Tags are not cleaned up in this case, however that is done on invalidateTags().
+ $this->doDelete($expiredIds);
+ }
+ foreach ($byLifetime as $lifetime => $values) {
+ try {
+ $values = $this->extractTagData($values, $addTagData, $removeTagData);
+ $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
+ } catch (\Exception $e) {
+ }
+ if (true === $e || [] === $e) {
+ continue;
+ }
+ if (\is_array($e) || 1 === \count($values)) {
+ foreach (\is_array($e) ? $e : array_keys($values) as $id) {
+ $ok = false;
+ $v = $values[$id];
+ $type = \is_object($v) ? \get_class($v) : \gettype($v);
+ $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
+ }
+ } else {
+ foreach ($values as $id => $v) {
+ $retry[$lifetime][] = $id;
+ }
+ }
+ }
+
+ // When bulk-save failed, retry each item individually
+ foreach ($retry as $lifetime => $ids) {
+ foreach ($ids as $id) {
+ try {
+ $v = $byLifetime[$lifetime][$id];
+ $values = $this->extractTagData([$id => $v], $addTagData, $removeTagData);
+ $e = $this->doSave($values, $lifetime, $addTagData, $removeTagData);
+ } catch (\Exception $e) {
+ }
+ if (true === $e || [] === $e) {
+ continue;
+ }
+ $ok = false;
+ $type = \is_object($v) ? \get_class($v) : \gettype($v);
+ $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Overloaded in order to deal with tags for adjusted doDelete() signature.
+ */
+ public function deleteItems(array $keys)
+ {
+ if (!$keys) {
+ return true;
+ }
+
+ $ids = [];
+ $tagData = [];
+
+ foreach ($keys as $key) {
+ $ids[$key] = $this->getId($key);
+ unset($this->deferred[$key]);
+ }
+
+ foreach ($this->doFetch($ids) as $id => $value) {
+ foreach ($value['tags'] ?? [] as $tag) {
+ $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id;
+ }
+ }
+
+ try {
+ if ($this->doDelete(\array_values($ids), $tagData)) {
+ return true;
+ }
+ } catch (\Exception $e) {
+ }
+
+ $ok = true;
+
+ // When bulk-delete failed, retry each item individually
+ foreach ($ids as $key => $id) {
+ try {
+ $e = null;
+ if ($this->doDelete([$id])) {
+ continue;
+ }
+ } catch (\Exception $e) {
+ }
+ $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
+ $ok = false;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function invalidateTags(array $tags)
+ {
+ if (empty($tags)) {
+ return false;
+ }
+
+ $tagIds = [];
+ foreach (\array_unique($tags) as $tag) {
+ $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag);
+ }
+
+ if ($this->doInvalidate($tagIds)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Extracts tags operation data from $values set in mergeByLifetime, and returns values without it.
+ */
+ private function extractTagData(array $values, ?array &$addTagData, ?array &$removeTagData): array
+ {
+ $addTagData = $removeTagData = [];
+ foreach ($values as $id => $value) {
+ foreach ($value['tag-operations']['add'] as $tag => $tagId) {
+ $addTagData[$tagId][] = $id;
+ }
+
+ foreach ($value['tag-operations']['remove'] as $tag => $tagId) {
+ $removeTagData[$tagId][] = $id;
+ }
+
+ unset($values[$id]['tag-operations']);
+ }
+
+ return $values;
+ }
+}
diff --git a/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php b/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php
new file mode 100644
index 0000000000..f96c670ae9
--- /dev/null
+++ b/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php
@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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 Symfony\Component\Cache\Exception\LogicException;
+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\Component\Filesystem\Filesystem;
+
+/**
+ * Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author André Rømcke <andre.romcke+symfony@gmail.com>
+ *
+ * @experimental in 4.3
+ */
+class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements PruneableInterface
+{
+ use FilesystemTrait {
+ doSave as doSaveCache;
+ doDelete as doDeleteCache;
+ }
+
+ /**
+ * Folder used for tag symlinks.
+ */
+ private const TAG_FOLDER = 'tags';
+
+ /**
+ * @var Filesystem|null
+ */
+ private $fs;
+
+ public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null)
+ {
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ parent::__construct('', $defaultLifetime);
+ $this->init($namespace, $directory);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], array $removeTagData = []): array
+ {
+ $failed = $this->doSaveCache($values, $lifetime);
+
+ $fs = $this->getFilesystem();
+ // Add Tags as symlinks
+ foreach ($addTagData as $tagId => $ids) {
+ $tagFolder = $this->getTagFolder($tagId);
+ foreach ($ids as $id) {
+ if ($failed && \in_array($id, $failed, true)) {
+ continue;
+ }
+
+ $file = $this->getFile($id);
+ $fs->symlink($file, $this->getFile($id, true, $tagFolder));
+ }
+ }
+
+ // Unlink removed Tags
+ $files = [];
+ foreach ($removeTagData as $tagId => $ids) {
+ $tagFolder = $this->getTagFolder($tagId);
+ foreach ($ids as $id) {
+ if ($failed && \in_array($id, $failed, true)) {
+ continue;
+ }
+
+ $files[] = $this->getFile($id, false, $tagFolder);
+ }
+ }
+ $fs->remove($files);
+
+ return $failed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids, array $tagData = []): bool
+ {
+ $ok = $this->doDeleteCache($ids);
+
+ // Remove tags
+ $files = [];
+ $fs = $this->getFilesystem();
+ foreach ($tagData as $tagId => $idMap) {
+ $tagFolder = $this->getTagFolder($tagId);
+ foreach ($idMap as $id) {
+ $files[] = $this->getFile($id, false, $tagFolder);
+ }
+ }
+ $fs->remove($files);
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doInvalidate(array $tagIds): bool
+ {
+ foreach ($tagIds as $tagId) {
+ $tagsFolder = $this->getTagFolder($tagId);
+ if (!file_exists($tagsFolder)) {
+ continue;
+ }
+
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tagsFolder, \FilesystemIterator::SKIP_DOTS)) as $itemLink) {
+ if (!$itemLink->isLink()) {
+ throw new LogicException('Expected a (sym)link when iterating over tag folder, non link found: '.$itemLink);
+ }
+
+ $valueFile = $itemLink->getRealPath();
+ if ($valueFile && \file_exists($valueFile)) {
+ @unlink($valueFile);
+ }
+
+ @unlink((string) $itemLink);
+ }
+ }
+
+ return true;
+ }
+
+ private function getFilesystem(): Filesystem
+ {
+ return $this->fs ?? $this->fs = new Filesystem();
+ }
+
+ private function getTagFolder(string $tagId): string
+ {
+ return $this->getFile($tagId, false, $this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
+ }
+}
diff --git a/vendor/symfony/cache/Adapter/Psr16Adapter.php b/vendor/symfony/cache/Adapter/Psr16Adapter.php
new file mode 100644
index 0000000000..a14ee082be
--- /dev/null
+++ b/vendor/symfony/cache/Adapter/Psr16Adapter.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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 <p@tchwork.com>
+ */
+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/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php b/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
new file mode 100644
index 0000000000..4e09387213
--- /dev/null
+++ b/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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 Predis;
+use Predis\Connection\Aggregate\ClusterInterface;
+use Predis\Response\Status;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\LogicException;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\Traits\RedisTrait;
+
+/**
+ * Stores tag id <> cache id relationship as a Redis Set, lookup on invalidation using sPOP.
+ *
+ * Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even
+ * if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache
+ * relationship survives eviction (cache cleanup when Redis runs out of memory).
+ *
+ * Requirements:
+ * - Server: Redis 3.2+
+ * - Client: PHP Redis 3.1.3+ OR Predis
+ * - Redis Server(s) configured with any `volatile-*` eviction policy, OR `noeviction` if it will NEVER fill up memory
+ *
+ * Design limitations:
+ * - Max 2 billion cache keys per cache tag
+ * E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 2 billion cache items as well
+ *
+ * @see https://redis.io/topics/lru-cache#eviction-policies Documentation for Redis eviction policies.
+ * @see https://redis.io/topics/data-types#sets Documentation for Redis Set datatype.
+ * @see https://redis.io/commands/spop Documentation for sPOP operation, capable of retriving AND emptying a Set at once.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author André Rømcke <andre.romcke+symfony@gmail.com>
+ *
+ * @experimental in 4.3
+ */
+class RedisTagAwareAdapter extends AbstractTagAwareAdapter
+{
+ use RedisTrait;
+
+ /**
+ * Redis "Set" can hold more than 4 billion members, here we limit ourselves to PHP's > 2 billion max int (32Bit).
+ */
+ private const POP_MAX_LIMIT = 2147483647 - 1;
+
+ /**
+ * Limits for how many keys are deleted in batch.
+ */
+ private const BULK_DELETE_LIMIT = 10000;
+
+ /**
+ * On cache items without a lifetime set, we set it to 100 days. This is to make sure cache items are
+ * preferred to be evicted over tag Sets, if eviction policy is configured according to requirements.
+ */
+ private const DEFAULT_CACHE_TTL = 8640000;
+
+ /**
+ * @var bool|null
+ */
+ private $redisServerSupportSPOP = null;
+
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient The redis client
+ * @param string $namespace The default namespace
+ * @param int $defaultLifetime The default lifetime
+ * @param MarshallerInterface|null $marshaller
+ *
+ * @throws \Symfony\Component\Cache\Exception\LogicException If phpredis with version lower than 3.1.3.
+ */
+ public function __construct($redisClient, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
+ {
+ $this->init($redisClient, $namespace, $defaultLifetime, $marshaller);
+
+ // Make sure php-redis is 3.1.3 or higher configured for Redis classes
+ if (!$this->redis instanceof Predis\Client && \version_compare(\phpversion('redis'), '3.1.3', '<')) {
+ throw new LogicException('RedisTagAwareAdapter requires php-redis 3.1.3 or higher, alternatively use predis/predis');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], array $delTagData = []): array
+ {
+ // serialize values
+ if (!$serialized = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+
+ // While pipeline isn't supported on RedisCluster, other setups will at least benefit from doing this in one op
+ $results = $this->pipeline(static function () use ($serialized, $lifetime, $addTagData, $delTagData) {
+ // Store cache items, force a ttl if none is set, as there is no MSETEX we need to set each one
+ foreach ($serialized as $id => $value) {
+ yield 'setEx' => [
+ $id,
+ 0 >= $lifetime ? self::DEFAULT_CACHE_TTL : $lifetime,
+ $value,
+ ];
+ }
+
+ // Add and Remove Tags
+ foreach ($addTagData as $tagId => $ids) {
+ yield 'sAdd' => array_merge([$tagId], $ids);
+ }
+
+ foreach ($delTagData as $tagId => $ids) {
+ yield 'sRem' => array_merge([$tagId], $ids);
+ }
+ });
+
+ foreach ($results as $id => $result) {
+ // Skip results of SADD/SREM operations, they'll be 1 or 0 depending on if set value already existed or not
+ if (\is_numeric($result)) {
+ continue;
+ }
+ // setEx results
+ if (true !== $result && (!$result instanceof Status || $result !== Status::get('OK'))) {
+ $failed[] = $id;
+ }
+ }
+
+ return $failed;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids, array $tagData = []): bool
+ {
+ if (!$ids) {
+ return true;
+ }
+
+ $predisCluster = $this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface;
+ $this->pipeline(static function () use ($ids, $tagData, $predisCluster) {
+ if ($predisCluster) {
+ foreach ($ids as $id) {
+ yield 'del' => [$id];
+ }
+ } else {
+ yield 'del' => $ids;
+ }
+
+ foreach ($tagData as $tagId => $idList) {
+ yield 'sRem' => \array_merge([$tagId], $idList);
+ }
+ })->rewind();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doInvalidate(array $tagIds): bool
+ {
+ if (!$this->redisServerSupportSPOP()) {
+ return false;
+ }
+
+ // Pop all tag info at once to avoid race conditions
+ $tagIdSets = $this->pipeline(static function () use ($tagIds) {
+ foreach ($tagIds as $tagId) {
+ // Client: Predis or PHP Redis 3.1.3+ (https://github.com/phpredis/phpredis/commit/d2e203a6)
+ // Server: Redis 3.2 or higher (https://redis.io/commands/spop)
+ yield 'sPop' => [$tagId, self::POP_MAX_LIMIT];
+ }
+ });
+
+ // Flatten generator result from pipeline, ignore keys (tag ids)
+ $ids = \array_unique(\array_merge(...\iterator_to_array($tagIdSets, false)));
+
+ // Delete cache in chunks to avoid overloading the connection
+ foreach (\array_chunk($ids, self::BULK_DELETE_LIMIT) as $chunkIds) {
+ $this->doDelete($chunkIds);
+ }
+
+ return true;
+ }
+
+ private function redisServerSupportSPOP(): bool
+ {
+ if (null !== $this->redisServerSupportSPOP) {
+ return $this->redisServerSupportSPOP;
+ }
+
+ foreach ($this->getHosts() as $host) {
+ $info = $host->info('Server');
+ $info = isset($info['Server']) ? $info['Server'] : $info;
+ if (version_compare($info['redis_version'], '3.2', '<')) {
+ CacheItem::log($this->logger, 'Redis server needs to be version 3.2 or higher, your Redis server was detected as '.$info['redis_version']);
+
+ return $this->redisServerSupportSPOP = false;
+ }
+ }
+
+ return $this->redisServerSupportSPOP = true;
+ }
+}
diff --git a/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php b/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php
index 5a836a3dbf..d0d42e57f0 100644
--- a/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php
+++ b/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php
@@ -11,68 +11,11 @@
namespace Symfony\Component\Cache\Adapter;
-use Psr\SimpleCache\CacheInterface;
-use Symfony\Component\Cache\PruneableInterface;
-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 <p@tchwork.com>
+ * @deprecated since Symfony 4.3, use Psr16Adapter instead.
*/
-class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface
+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/vendor/symfony/cache/CHANGELOG.md b/vendor/symfony/cache/CHANGELOG.md
index 9016bc5dbf..37dd2e11a0 100644
--- a/vendor/symfony/cache/CHANGELOG.md
+++ b/vendor/symfony/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/vendor/symfony/cache/DependencyInjection/CachePoolPass.php b/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
index b1af39755e..5d7a2369c2 100644
--- a/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
+++ b/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
@@ -68,14 +68,20 @@ class CachePoolPass implements CompilerPassInterface
if ($pool->isAbstract()) {
continue;
}
+ $class = $adapter->getClass();
while ($adapter instanceof ChildDefinition) {
$adapter = $container->findDefinition($adapter->getParent());
+ $class = $class ?: $adapter->getClass();
if ($t = $adapter->getTag($this->cachePoolTag)) {
$tags[0] += $t[0];
}
}
$name = $tags[0]['name'] ?? $id;
if (!isset($tags[0]['namespace'])) {
+ if (null !== $class) {
+ $seed .= '.'.$class;
+ }
+
$tags[0]['namespace'] = $this->getNamespace($seed, $name);
}
if (isset($tags[0]['clearer'])) {
@@ -136,6 +142,10 @@ class CachePoolPass implements CompilerPassInterface
$clearer->addTag($this->cacheSystemClearerTag);
}
}
+
+ if ($container->hasDefinition('console.command.cache_pool_list')) {
+ $container->getDefinition('console.command.cache_pool_list')->replaceArgument(0, array_keys($pools));
+ }
}
private function getNamespace($seed, $id)
diff --git a/vendor/symfony/cache/Exception/CacheException.php b/vendor/symfony/cache/Exception/CacheException.php
index e87b2db8fe..d2e975b2bc 100644
--- a/vendor/symfony/cache/Exception/CacheException.php
+++ b/vendor/symfony/cache/Exception/CacheException.php
@@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
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/vendor/symfony/cache/Exception/InvalidArgumentException.php b/vendor/symfony/cache/Exception/InvalidArgumentException.php
index 828bf3ed77..7f9584a264 100644
--- a/vendor/symfony/cache/Exception/InvalidArgumentException.php
+++ b/vendor/symfony/cache/Exception/InvalidArgumentException.php
@@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
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/vendor/symfony/cache/Exception/LogicException.php b/vendor/symfony/cache/Exception/LogicException.php
index d299673eb2..9ffa7ed695 100644
--- a/vendor/symfony/cache/Exception/LogicException.php
+++ b/vendor/symfony/cache/Exception/LogicException.php
@@ -14,6 +14,12 @@ namespace Symfony\Component\Cache\Exception;
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/vendor/symfony/cache/LockRegistry.php b/vendor/symfony/cache/LockRegistry.php
index ef49805ea0..676fba5dca 100644
--- a/vendor/symfony/cache/LockRegistry.php
+++ b/vendor/symfony/cache/LockRegistry.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache;
+use Psr\Log\LoggerInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
@@ -33,19 +34,23 @@ final class LockRegistry
*/
private static $files = [
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractTagAwareAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AdapterInterface.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ApcuAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ArrayAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ChainAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'DoctrineAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemTagAwareAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'MemcachedAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'NullAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PdoAdapter.php',
__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.'RedisTagAwareAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
__DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapterInterface.php',
@@ -74,7 +79,7 @@ final class LockRegistry
return $previousFiles;
}
- public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null)
+ public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
{
$key = self::$files ? crc32($item->getKey()) % \count(self::$files) : -1;
@@ -86,6 +91,7 @@ final class LockRegistry
try {
// race to get the lock in non-blocking mode
if (flock($lock, LOCK_EX | LOCK_NB)) {
+ $logger && $logger->info('Lock acquired, now computing item "{key}"', ['key' => $item->getKey()]);
self::$lockedFiles[$key] = true;
$value = $callback($item, $save);
@@ -102,6 +108,7 @@ final class LockRegistry
return $value;
}
// if we failed the race, retry locking in blocking mode to wait for the winner
+ $logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
flock($lock, LOCK_SH);
} finally {
flock($lock, LOCK_UN);
@@ -113,6 +120,7 @@ final class LockRegistry
try {
$value = $pool->get($item->getKey(), $signalingCallback, 0);
+ $logger && $logger->info('Item "{key}" retrieved after lock was released', ['key' => $item->getKey()]);
$save = false;
return $value;
@@ -120,6 +128,7 @@ final class LockRegistry
if ($signalingException !== $e) {
throw $e;
}
+ $logger && $logger->info('Item "{key}" not found while lock was released, now retrying', ['key' => $item->getKey()]);
}
}
}
diff --git a/vendor/symfony/cache/Psr16Cache.php b/vendor/symfony/cache/Psr16Cache.php
new file mode 100644
index 0000000000..589ffa0d8b
--- /dev/null
+++ b/vendor/symfony/cache/Psr16Cache.php
@@ -0,0 +1,263 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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 <p@tchwork.com>
+ */
+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/vendor/symfony/cache/Simple/AbstractCache.php b/vendor/symfony/cache/Simple/AbstractCache.php
index 7a2a3cb36e..312a7dbfd0 100644
--- a/vendor/symfony/cache/Simple/AbstractCache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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;
@@ -52,7 +56,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
return $value;
}
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
}
return $default;
@@ -86,7 +90,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
try {
$values = $this->doFetch($ids);
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => $keys, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
$values = [];
}
$ids = array_combine($ids, $keys);
@@ -125,7 +129,8 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) {
$keys[] = substr($id, \strlen($this->namespace));
}
- CacheItem::log($this->logger, 'Failed to save values', ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
+ $message = 'Failed to save values'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
return false;
}
@@ -171,7 +176,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re
yield $key => $value;
}
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => array_values($keys), 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
}
foreach ($keys as $key) {
diff --git a/vendor/symfony/cache/Simple/ApcuCache.php b/vendor/symfony/cache/Simple/ApcuCache.php
index 0877c394bb..c22771e822 100644
--- a/vendor/symfony/cache/Simple/ApcuCache.php
+++ b/vendor/symfony/cache/Simple/ApcuCache.php
@@ -13,6 +13,11 @@ namespace Symfony\Component\Cache\Simple;
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/vendor/symfony/cache/Simple/ArrayCache.php b/vendor/symfony/cache/Simple/ArrayCache.php
index e36dacb829..3df5b4990c 100644
--- a/vendor/symfony/cache/Simple/ArrayCache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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/vendor/symfony/cache/Simple/ChainCache.php b/vendor/symfony/cache/Simple/ChainCache.php
index 18e9462ba0..a0122fdee9 100644
--- a/vendor/symfony/cache/Simple/ChainCache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf
}
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/vendor/symfony/cache/Simple/DoctrineCache.php b/vendor/symfony/cache/Simple/DoctrineCache.php
index 0ba701d7cd..6a6d003153 100644
--- a/vendor/symfony/cache/Simple/DoctrineCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/FilesystemCache.php b/vendor/symfony/cache/Simple/FilesystemCache.php
index 8e04d53355..8891abd94c 100644
--- a/vendor/symfony/cache/Simple/FilesystemCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/MemcachedCache.php b/vendor/symfony/cache/Simple/MemcachedCache.php
index 8e418b071e..e1934119aa 100644
--- a/vendor/symfony/cache/Simple/MemcachedCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/NullCache.php b/vendor/symfony/cache/Simple/NullCache.php
index fa986aebd1..d1ca6f7187 100644
--- a/vendor/symfony/cache/Simple/NullCache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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/vendor/symfony/cache/Simple/PdoCache.php b/vendor/symfony/cache/Simple/PdoCache.php
index 521e9b8f2d..07849e93fe 100644
--- a/vendor/symfony/cache/Simple/PdoCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/PhpArrayCache.php b/vendor/symfony/cache/Simple/PhpArrayCache.php
index 6ba8527885..566609359d 100644
--- a/vendor/symfony/cache/Simple/PhpArrayCache.php
+++ b/vendor/symfony/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 <galopintitouan@gmail.com>
- * @author Nicolas Grekas <p@tchwork.com>
+ * @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 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt
*
* @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/vendor/symfony/cache/Simple/PhpFilesCache.php b/vendor/symfony/cache/Simple/PhpFilesCache.php
index 37432c5af8..060244a086 100644
--- a/vendor/symfony/cache/Simple/PhpFilesCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/Psr6Cache.php b/vendor/symfony/cache/Simple/Psr6Cache.php
index fceb9ba70f..090f48c172 100644
--- a/vendor/symfony/cache/Simple/Psr6Cache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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/vendor/symfony/cache/Simple/RedisCache.php b/vendor/symfony/cache/Simple/RedisCache.php
index df2a96e86b..2933bf15b3 100644
--- a/vendor/symfony/cache/Simple/RedisCache.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Simple/TraceableCache.php b/vendor/symfony/cache/Simple/TraceableCache.php
index 2db335ac96..ad9bfcf09c 100644
--- a/vendor/symfony/cache/Simple/TraceableCache.php
+++ b/vendor/symfony/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 <p@tchwork.com>
+ * @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/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
index 0eceb6e572..2b66d2bea0 100644
--- a/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
+++ b/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
@@ -59,6 +59,26 @@ abstract class AdapterTestCase extends CachePoolTest
$this->assertFalse($isHit);
}
+ public function testRecursiveGet()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool(0, __FUNCTION__);
+
+ $v = $cache->get('k1', function () use (&$counter, $cache) {
+ $v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
+ $v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
+
+ return $v;
+ });
+
+ $this->assertSame(1, $counter);
+ $this->assertSame(1, $v);
+ $this->assertSame(1, $cache->get('k2', function () { return 2; }));
+ }
+
public function testGetMetadata()
{
if (isset($this->skippedTests[__FUNCTION__])) {
@@ -215,14 +235,9 @@ abstract class AdapterTestCase extends CachePoolTest
}
}
-class NotUnserializable implements \Serializable
+class NotUnserializable
{
- public function serialize()
- {
- return serialize(123);
- }
-
- public function unserialize($ser)
+ public function __wakeup()
{
throw new \Exception(__CLASS__);
}
diff --git a/vendor/symfony/cache/Tests/Adapter/FilesystemTagAwareAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/FilesystemTagAwareAdapterTest.php
new file mode 100644
index 0000000000..83a7ea52dd
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/FilesystemTagAwareAdapterTest.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\FilesystemTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+
+/**
+ * @group time-sensitive
+ */
+class FilesystemTagAwareAdapterTest extends FilesystemAdapterTest
+{
+ use TagAwareTestTrait;
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ return new FilesystemTagAwareAdapter('', $defaultLifetime);
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php
index cee80ac196..3a5904b107 100644
--- a/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php
+++ b/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php
@@ -23,6 +23,7 @@ class PhpArrayAdapterTest extends AdapterTestCase
{
protected $skippedTests = [
'testGet' => 'PhpArrayAdapter is read-only.',
+ 'testRecursiveGet' => 'PhpArrayAdapter is read-only.',
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',
'testClear' => 'PhpArrayAdapter is read-only.',
diff --git a/vendor/symfony/cache/Tests/Adapter/PredisTagAwareAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareAdapterTest.php
new file mode 100644
index 0000000000..e321a1c9b8
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareAdapterTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+
+class PredisTagAwareAdapterTest extends PredisAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(\Predis\Client::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php
new file mode 100644
index 0000000000..a8a72e1de4
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareClusterAdapterTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+
+class PredisTagAwareClusterAdapterTest extends PredisClusterAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(\Predis\Client::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/PredisTagAwareRedisClusterAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareRedisClusterAdapterTest.php
new file mode 100644
index 0000000000..5b82a80ecb
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/PredisTagAwareRedisClusterAdapterTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+
+class PredisTagAwareRedisClusterAdapterTest extends PredisRedisClusterAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(\Predis\Client::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/Psr16AdapterTest.php b/vendor/symfony/cache/Tests/Adapter/Psr16AdapterTest.php
new file mode 100644
index 0000000000..19907ddf78
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/Psr16AdapterTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php
index c83abaf91b..4d9bc319eb 100644
--- a/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php
+++ b/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php
@@ -31,30 +31,33 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
return $adapter;
}
- public function testCreateConnection()
+ /**
+ * @dataProvider provideValidSchemes
+ */
+ public function testCreateConnection($dsnScheme)
{
- $redis = RedisAdapter::createConnection('redis:?host[h1]&host[h2]&host[/foo:]');
+ $redis = RedisAdapter::createConnection($dsnScheme.':?host[h1]&host[h2]&host[/foo:]');
$this->assertInstanceOf(\RedisArray::class, $redis);
$this->assertSame(['h1:6379', 'h2:6379', '/foo'], $redis->_hosts());
@$redis = null; // some versions of phpredis connect on destruct, let's silence the warning
$redisHost = getenv('REDIS_HOST');
- $redis = RedisAdapter::createConnection('redis://'.$redisHost);
+ $redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost);
$this->assertInstanceOf(\Redis::class, $redis);
$this->assertTrue($redis->isConnected());
$this->assertSame(0, $redis->getDbNum());
- $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2');
+ $redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'/2');
$this->assertSame(2, $redis->getDbNum());
- $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]);
+ $redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['timeout' => 3]);
$this->assertEquals(3, $redis->getTimeout());
- $redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4');
+ $redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'?timeout=4');
$this->assertEquals(4, $redis->getTimeout());
- $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]);
+ $redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['read_timeout' => 5]);
$this->assertEquals(5, $redis->getReadTimeout());
}
@@ -87,6 +90,14 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
RedisAdapter::createConnection($dsn);
}
+ public function provideValidSchemes()
+ {
+ return [
+ ['redis'],
+ ['rediss'],
+ ];
+ }
+
public function provideInvalidCreateConnection()
{
return [
diff --git a/vendor/symfony/cache/Tests/Adapter/RedisTagAwareAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareAdapterTest.php
new file mode 100644
index 0000000000..95e5fe7e3a
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareAdapterTest.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+use Symfony\Component\Cache\Traits\RedisProxy;
+
+class RedisTagAwareAdapterTest extends RedisAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(RedisProxy::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php
new file mode 100644
index 0000000000..5855cc3adf
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareArrayAdapterTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+
+class RedisTagAwareArrayAdapterTest extends RedisArrayAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(\RedisArray::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php
new file mode 100644
index 0000000000..ef17c1d69e
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Adapter/RedisTagAwareClusterAdapterTest.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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\RedisTagAwareAdapter;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
+use Symfony\Component\Cache\Traits\RedisClusterProxy;
+
+class RedisTagAwareClusterAdapterTest extends RedisClusterAdapterTest
+{
+ use TagAwareTestTrait;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
+ }
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ $this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
+ $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+
+ return $adapter;
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php
index 3028af47c6..b11f72d5a3 100644
--- a/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php b/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php
index 7b8895b700..a339790862 100644
--- a/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php
+++ b/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php
@@ -14,13 +14,15 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
-use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group time-sensitive
*/
class TagAwareAdapterTest extends AdapterTestCase
{
+ use TagAwareTestTrait;
+
public function createCachePool($defaultLifetime = 0)
{
return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime));
@@ -32,53 +34,9 @@ class TagAwareAdapterTest extends AdapterTestCase
}
/**
- * @expectedException \Psr\Cache\InvalidArgumentException
+ * Test feature specific to TagAwareAdapter as it implicit needs to save deferred when also saving expiry info.
*/
- public function testInvalidTag()
- {
- $pool = $this->createCachePool();
- $item = $pool->getItem('foo');
- $item->tag(':');
- }
-
- public function testInvalidateTags()
- {
- $pool = $this->createCachePool();
-
- $i0 = $pool->getItem('i0');
- $i1 = $pool->getItem('i1');
- $i2 = $pool->getItem('i2');
- $i3 = $pool->getItem('i3');
- $foo = $pool->getItem('foo');
-
- $pool->save($i0->tag('bar'));
- $pool->save($i1->tag('foo'));
- $pool->save($i2->tag('foo')->tag('bar'));
- $pool->save($i3->tag('foo')->tag('baz'));
- $pool->save($foo);
-
- $pool->invalidateTags(['bar']);
-
- $this->assertFalse($pool->getItem('i0')->isHit());
- $this->assertTrue($pool->getItem('i1')->isHit());
- $this->assertFalse($pool->getItem('i2')->isHit());
- $this->assertTrue($pool->getItem('i3')->isHit());
- $this->assertTrue($pool->getItem('foo')->isHit());
-
- $pool->invalidateTags(['foo']);
-
- $this->assertFalse($pool->getItem('i1')->isHit());
- $this->assertFalse($pool->getItem('i3')->isHit());
- $this->assertTrue($pool->getItem('foo')->isHit());
-
- $anotherPoolInstance = $this->createCachePool();
-
- $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
- $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
- $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
- }
-
- public function testInvalidateCommits()
+ public function testInvalidateCommitsSeperatePools()
{
$pool1 = $this->createCachePool();
@@ -94,76 +52,6 @@ class TagAwareAdapterTest extends AdapterTestCase
$this->assertTrue($foo->isHit());
}
- public function testTagsAreCleanedOnSave()
- {
- $pool = $this->createCachePool();
-
- $i = $pool->getItem('k');
- $pool->save($i->tag('foo'));
-
- $i = $pool->getItem('k');
- $pool->save($i->tag('bar'));
-
- $pool->invalidateTags(['foo']);
- $this->assertTrue($pool->getItem('k')->isHit());
- }
-
- public function testTagsAreCleanedOnDelete()
- {
- $pool = $this->createCachePool();
-
- $i = $pool->getItem('k');
- $pool->save($i->tag('foo'));
- $pool->deleteItem('k');
-
- $pool->save($pool->getItem('k'));
- $pool->invalidateTags(['foo']);
-
- $this->assertTrue($pool->getItem('k')->isHit());
- }
-
- public function testTagItemExpiry()
- {
- $pool = $this->createCachePool(10);
-
- $item = $pool->getItem('foo');
- $item->tag(['baz']);
- $item->expiresAfter(100);
-
- $pool->save($item);
- $pool->invalidateTags(['baz']);
- $this->assertFalse($pool->getItem('foo')->isHit());
-
- sleep(20);
-
- $this->assertFalse($pool->getItem('foo')->isHit());
- }
-
- /**
- * @group legacy
- */
- public function testGetPreviousTags()
- {
- $pool = $this->createCachePool();
-
- $i = $pool->getItem('k');
- $pool->save($i->tag('foo'));
-
- $i = $pool->getItem('k');
- $this->assertSame(['foo' => 'foo'], $i->getPreviousTags());
- }
-
- public function testGetMetadata()
- {
- $pool = $this->createCachePool();
-
- $i = $pool->getItem('k');
- $pool->save($i->tag('foo'));
-
- $i = $pool->getItem('k');
- $this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]);
- }
-
public function testPrune()
{
$cache = new TagAwareAdapter($this->getPruneableMock());
diff --git a/vendor/symfony/cache/Tests/DependencyInjection/CachePoolPassTest.php b/vendor/symfony/cache/Tests/DependencyInjection/CachePoolPassTest.php
index f307aa5386..4681b3dc81 100644
--- a/vendor/symfony/cache/Tests/DependencyInjection/CachePoolPassTest.php
+++ b/vendor/symfony/cache/Tests/DependencyInjection/CachePoolPassTest.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Cache\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\DependencyInjection\CachePoolPass;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -48,6 +49,27 @@ class CachePoolPassTest extends TestCase
$this->assertSame('z3X945Jbf5', $cachePool->getArgument(0));
}
+ public function testNamespaceArgumentIsSeededWithAdapterClassName()
+ {
+ $container = new ContainerBuilder();
+ $container->setParameter('kernel.container_class', 'app');
+ $container->setParameter('kernel.project_dir', 'foo');
+ $adapter = new Definition();
+ $adapter->setAbstract(true);
+ $adapter->addTag('cache.pool');
+ $adapter->setClass(RedisAdapter::class);
+ $container->setDefinition('app.cache_adapter', $adapter);
+ $container->setAlias('app.cache_adapter_alias', 'app.cache_adapter');
+ $cachePool = new ChildDefinition('app.cache_adapter_alias');
+ $cachePool->addArgument(null);
+ $cachePool->addTag('cache.pool');
+ $container->setDefinition('app.cache_pool', $cachePool);
+
+ $this->cachePoolPass->process($container);
+
+ $this->assertSame('xmOJ8gqF-Y', $cachePool->getArgument(0));
+ }
+
public function testNamespaceArgumentIsNotReplacedIfArrayAdapterIsUsed()
{
$container = new ContainerBuilder();
diff --git a/vendor/symfony/cache/Tests/Psr16CacheTest.php b/vendor/symfony/cache/Tests/Psr16CacheTest.php
new file mode 100644
index 0000000000..e56d99e441
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Psr16CacheTest.php
@@ -0,0 +1,168 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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
+{
+ public function __wakeup()
+ {
+ throw new \Exception(__CLASS__);
+ }
+}
diff --git a/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php b/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php
index dd5e1509c1..a9f5d98b92 100644
--- a/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
+/**
+ * @group legacy
+ */
abstract class AbstractRedisCacheTest extends CacheTestCase
{
protected $skippedTests = [
diff --git a/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php b/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php
index f37b95a093..b322094603 100644
--- a/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\ApcuCache;
+/**
+ * @group legacy
+ */
class ApcuCacheTest extends CacheTestCase
{
protected $skippedTests = [
diff --git a/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php b/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php
index 26c3e14d09..587304a5db 100644
--- a/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php
@@ -15,6 +15,7 @@ use Symfony\Component\Cache\Simple\ArrayCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class ArrayCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/CacheTestCase.php b/vendor/symfony/cache/Tests/Simple/CacheTestCase.php
index 3c8824869b..d4b3d07f62 100644
--- a/vendor/symfony/cache/Tests/Simple/CacheTestCase.php
+++ b/vendor/symfony/cache/Tests/Simple/CacheTestCase.php
@@ -132,14 +132,9 @@ abstract class CacheTestCase extends SimpleCacheTest
}
}
-class NotUnserializable implements \Serializable
+class NotUnserializable
{
- public function serialize()
- {
- return serialize(123);
- }
-
- public function unserialize($ser)
+ public function __wakeup()
{
throw new \Exception(__CLASS__);
}
diff --git a/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php b/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php
index e6f7c7cc63..806bb7633b 100644
--- a/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php
@@ -19,6 +19,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class ChainCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php b/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php
index af4331d69b..5d78c00cac 100644
--- a/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class DoctrineCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php b/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php
index 620305a58a..9f423ba641 100644
--- a/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class FilesystemCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php b/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php
index f83f0a2e34..692259296f 100644
--- a/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php
@@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Simple\MemcachedCache;
+/**
+ * @group legacy
+ */
class MemcachedCacheTest extends CacheTestCase
{
protected $skippedTests = [
diff --git a/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php b/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php
index 13865a6098..d68131a1db 100644
--- a/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php
+++ b/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php
@@ -14,6 +14,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
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/vendor/symfony/cache/Tests/Simple/NullCacheTest.php b/vendor/symfony/cache/Tests/Simple/NullCacheTest.php
index 31f42c32b6..cf0dde92b3 100644
--- a/vendor/symfony/cache/Tests/Simple/NullCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/NullCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\NullCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class NullCacheTest extends TestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php b/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php
index 665db09f67..fbdf03be7e 100644
--- a/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
+ * @group legacy
*/
class PdoCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php b/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php
index ce1a9ae4f8..af5c42340b 100644
--- a/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php
@@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
+ * @group legacy
*/
class PdoDbalCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php
index ba4bde3139..5272604dc3 100644
--- a/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php
@@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
+ * @group legacy
*/
class PhpArrayCacheTest extends CacheTestCase
{
@@ -127,35 +128,3 @@ class PhpArrayCacheTest extends CacheTestCase
$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/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
index abee5e7872..90aa7bb6ef 100644
--- a/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
+++ b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php
@@ -17,6 +17,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
+ * @group legacy
*/
class PhpArrayCacheWithFallbackTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWrapper.php b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWrapper.php
new file mode 100644
index 0000000000..1e102fe1ff
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWrapper.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * 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/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php b/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php
index 3a68dd3984..7e40df7de5 100644
--- a/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\PhpFilesCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class PhpFilesCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php b/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php
index 65d48a978c..9fff36e402 100644
--- a/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\Psr6Cache;
+/**
+ * @group legacy
+ */
abstract class Psr6CacheTest extends CacheTestCase
{
protected $skippedTests = [
diff --git a/vendor/symfony/cache/Tests/Simple/Psr6CacheWithAdapterTest.php b/vendor/symfony/cache/Tests/Simple/Psr6CacheWithAdapterTest.php
index 46da9354d6..e5c7a6a4c7 100644
--- a/vendor/symfony/cache/Tests/Simple/Psr6CacheWithAdapterTest.php
+++ b/vendor/symfony/cache/Tests/Simple/Psr6CacheWithAdapterTest.php
@@ -15,6 +15,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
/**
* @group time-sensitive
+ * @group legacy
*/
class Psr6CacheWithAdapterTest extends Psr6CacheTest
{
diff --git a/vendor/symfony/cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php b/vendor/symfony/cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php
index a8c4164dcb..f987d40539 100644
--- a/vendor/symfony/cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php
+++ b/vendor/symfony/cache/Tests/Simple/Psr6CacheWithoutAdapterTest.php
@@ -15,6 +15,7 @@ use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
/**
* @group time-sensitive
+ * @group legacy
*/
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
{
diff --git a/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php b/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php
index bda39d990b..b52f5f9acd 100644
--- a/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php b/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php
index 407d916c73..ddb674b285 100644
--- a/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php
@@ -13,6 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
+/**
+ * @group legacy
+ */
class RedisCacheTest extends AbstractRedisCacheTest
{
public static function setupBeforeClass()
diff --git a/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php b/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php
index 99d4e518fb..33c7acae0b 100644
--- a/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php
+++ b/vendor/symfony/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/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php b/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php
index e684caf36e..c2e8a477b4 100644
--- a/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php
+++ b/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php
@@ -16,6 +16,7 @@ use Symfony\Component\Cache\Simple\TraceableCache;
/**
* @group time-sensitive
+ * @group legacy
*/
class TraceableCacheTest extends CacheTestCase
{
diff --git a/vendor/symfony/cache/Tests/Traits/TagAwareTestTrait.php b/vendor/symfony/cache/Tests/Traits/TagAwareTestTrait.php
new file mode 100644
index 0000000000..38cc4dc9cc
--- /dev/null
+++ b/vendor/symfony/cache/Tests/Traits/TagAwareTestTrait.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Traits;
+
+use Symfony\Component\Cache\CacheItem;
+
+/**
+ * Common assertions for TagAware adapters.
+ *
+ * @method \Symfony\Component\Cache\Adapter\TagAwareAdapterInterface createCachePool() Must be implemented by TestCase
+ */
+trait TagAwareTestTrait
+{
+ /**
+ * @expectedException \Psr\Cache\InvalidArgumentException
+ */
+ public function testInvalidTag()
+ {
+ $pool = $this->createCachePool();
+ $item = $pool->getItem('foo');
+ $item->tag(':');
+ }
+
+ public function testInvalidateTags()
+ {
+ $pool = $this->createCachePool();
+
+ $i0 = $pool->getItem('i0');
+ $i1 = $pool->getItem('i1');
+ $i2 = $pool->getItem('i2');
+ $i3 = $pool->getItem('i3');
+ $foo = $pool->getItem('foo');
+
+ $pool->save($i0->tag('bar'));
+ $pool->save($i1->tag('foo'));
+ $pool->save($i2->tag('foo')->tag('bar'));
+ $pool->save($i3->tag('foo')->tag('baz'));
+ $pool->save($foo);
+
+ $pool->invalidateTags(['bar']);
+
+ $this->assertFalse($pool->getItem('i0')->isHit());
+ $this->assertTrue($pool->getItem('i1')->isHit());
+ $this->assertFalse($pool->getItem('i2')->isHit());
+ $this->assertTrue($pool->getItem('i3')->isHit());
+ $this->assertTrue($pool->getItem('foo')->isHit());
+
+ $pool->invalidateTags(['foo']);
+
+ $this->assertFalse($pool->getItem('i1')->isHit());
+ $this->assertFalse($pool->getItem('i3')->isHit());
+ $this->assertTrue($pool->getItem('foo')->isHit());
+
+ $anotherPoolInstance = $this->createCachePool();
+
+ $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
+ $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
+ $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
+ }
+
+ public function testInvalidateCommits()
+ {
+ $pool = $this->createCachePool();
+
+ $foo = $pool->getItem('foo');
+ $foo->tag('tag');
+
+ $pool->saveDeferred($foo->set('foo'));
+ $pool->invalidateTags(['tag']);
+
+ // ??: This seems to contradict a bit logic in deleteItems, where it does unset($this->deferred[$key]); on key matches
+
+ $foo = $pool->getItem('foo');
+
+ $this->assertTrue($foo->isHit());
+ }
+
+ public function testTagsAreCleanedOnSave()
+ {
+ $pool = $this->createCachePool();
+
+ $i = $pool->getItem('k');
+ $pool->save($i->tag('foo'));
+
+ $i = $pool->getItem('k');
+ $pool->save($i->tag('bar'));
+
+ $pool->invalidateTags(['foo']);
+ $this->assertTrue($pool->getItem('k')->isHit());
+ }
+
+ public function testTagsAreCleanedOnDelete()
+ {
+ $pool = $this->createCachePool();
+
+ $i = $pool->getItem('k');
+ $pool->save($i->tag('foo'));
+ $pool->deleteItem('k');
+
+ $pool->save($pool->getItem('k'));
+ $pool->invalidateTags(['foo']);
+
+ $this->assertTrue($pool->getItem('k')->isHit());
+ }
+
+ public function testTagItemExpiry()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $pool = $this->createCachePool(10);
+
+ $item = $pool->getItem('foo');
+ $item->tag(['baz']);
+ $item->expiresAfter(100);
+
+ $pool->save($item);
+ $pool->invalidateTags(['baz']);
+ $this->assertFalse($pool->getItem('foo')->isHit());
+
+ sleep(20);
+
+ $this->assertFalse($pool->getItem('foo')->isHit());
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testGetPreviousTags()
+ {
+ $pool = $this->createCachePool();
+
+ $i = $pool->getItem('k');
+ $pool->save($i->tag('foo'));
+
+ $i = $pool->getItem('k');
+ $this->assertSame(['foo' => 'foo'], $i->getPreviousTags());
+ }
+
+ public function testGetMetadata()
+ {
+ $pool = $this->createCachePool();
+
+ $i = $pool->getItem('k');
+ $pool->save($i->tag('foo'));
+
+ $i = $pool->getItem('k');
+ $this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]);
+ }
+}
diff --git a/vendor/symfony/cache/Traits/AbstractAdapterTrait.php b/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
new file mode 100644
index 0000000000..eb464c319e
--- /dev/null
+++ b/vendor/symfony/cache/Traits/AbstractAdapterTrait.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Psr\Cache\CacheItemInterface;
+use Symfony\Component\Cache\CacheItem;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+trait AbstractAdapterTrait
+{
+ use AbstractTrait;
+
+ /**
+ * @var \Closure needs to be set by class, signature is function(string <key>, mixed <value>, bool <isHit>)
+ */
+ private $createCacheItem;
+
+ /**
+ * @var \Closure needs to be set by class, signature is function(array <deferred>, string <namespace>, array <&expiredIds>)
+ */
+ private $mergeByLifetime;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $id = $this->getId($key);
+
+ $f = $this->createCacheItem;
+ $isHit = false;
+ $value = null;
+
+ try {
+ foreach ($this->doFetch([$id]) as $value) {
+ $isHit = true;
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
+ }
+
+ return $f($key, $value, $isHit);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $ids = [];
+
+ foreach ($keys as $key) {
+ $ids[] = $this->getId($key);
+ }
+ try {
+ $items = $this->doFetch($ids);
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
+ $items = [];
+ }
+ $ids = array_combine($ids, $keys);
+
+ return $this->generateItems($items, $ids);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return $this->commit();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return true;
+ }
+
+ public function __destruct()
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ }
+
+ private function generateItems($items, &$keys)
+ {
+ $f = $this->createCacheItem;
+
+ try {
+ foreach ($items as $id => $value) {
+ if (!isset($keys[$id])) {
+ $id = key($keys);
+ }
+ $key = $keys[$id];
+ unset($keys[$id]);
+ yield $key => $f($key, $value, true);
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
+ }
+
+ foreach ($keys as $key) {
+ yield $key => $f($key, null, false);
+ }
+ }
+}
diff --git a/vendor/symfony/cache/Traits/AbstractTrait.php b/vendor/symfony/cache/Traits/AbstractTrait.php
index 2553ea75cb..1d6c189c81 100644
--- a/vendor/symfony/cache/Traits/AbstractTrait.php
+++ b/vendor/symfony/cache/Traits/AbstractTrait.php
@@ -94,7 +94,7 @@ trait AbstractTrait
try {
return $this->doHave($id);
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
return false;
}
@@ -122,7 +122,7 @@ trait AbstractTrait
try {
return $this->doClear($this->namespace) || $cleared;
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
return false;
}
@@ -166,7 +166,8 @@ trait AbstractTrait
}
} catch (\Exception $e) {
}
- CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]);
+ $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
$ok = false;
}
diff --git a/vendor/symfony/cache/Traits/ArrayTrait.php b/vendor/symfony/cache/Traits/ArrayTrait.php
index e585c3d48c..8ae9cad59b 100644
--- a/vendor/symfony/cache/Traits/ArrayTrait.php
+++ b/vendor/symfony/cache/Traits/ArrayTrait.php
@@ -128,7 +128,8 @@ trait ArrayTrait
$serialized = serialize($value);
} catch (\Exception $e) {
$type = \is_object($value) ? \get_class($value) : \gettype($value);
- CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]);
+ $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
+ CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e]);
return;
}
@@ -150,7 +151,7 @@ trait ArrayTrait
try {
$value = unserialize($value);
} catch (\Exception $e) {
- CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
+ CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
$value = false;
}
if (false === $value) {
diff --git a/vendor/symfony/cache/Traits/ContractsTrait.php b/vendor/symfony/cache/Traits/ContractsTrait.php
index bd7be08dd5..d9514d3965 100644
--- a/vendor/symfony/cache/Traits/ContractsTrait.php
+++ b/vendor/symfony/cache/Traits/ContractsTrait.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache\Traits;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
@@ -31,6 +32,7 @@ trait ContractsTrait
}
private $callbackWrapper = [LockRegistry::class, 'compute'];
+ private $computing = [];
/**
* Wraps the callback passed to ->get() in a callable.
@@ -40,7 +42,7 @@ trait ContractsTrait
public function setCallbackWrapper(?callable $callbackWrapper): callable
{
$previousWrapper = $this->callbackWrapper;
- $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata) {
+ $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
return $callback($item, $save);
};
@@ -68,27 +70,28 @@ trait ContractsTrait
CacheItem::class
);
- return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata) {
+ return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
// don't wrap nor save recursive calls
- if (null === $callbackWrapper = $this->callbackWrapper) {
+ if (isset($this->computing[$key])) {
$value = $callback($item, $save);
$save = false;
return $value;
}
- $this->callbackWrapper = null;
+
+ $this->computing[$key] = $key;
$startTime = microtime(true);
try {
- $value = $callbackWrapper($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
+ $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
$setMetadata($item, $startTime, $metadata);
- });
+ }, $this->logger ?? null);
$setMetadata($item, $startTime, $metadata);
return $value;
} finally {
- $this->callbackWrapper = $callbackWrapper;
+ unset($this->computing[$key]);
}
- }, $beta, $metadata);
+ }, $beta, $metadata, $this->logger ?? null);
}
}
diff --git a/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
index 3f684acd68..37e1fd1f06 100644
--- a/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
+++ b/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
@@ -101,11 +101,11 @@ trait FilesystemCommonTrait
}
}
- private function getFile($id, $mkdir = false)
+ private function getFile($id, $mkdir = false, string $directory = null)
{
// Use MD5 to favor speed over security, which is not an issue here
$hash = str_replace('/', '-', base64_encode(hash('md5', static::class.$id, true)));
- $dir = $this->directory.strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);
+ $dir = ($directory ?? $this->directory).strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);
if ($mkdir && !file_exists($dir)) {
@mkdir($dir, 0777, true);
diff --git a/vendor/symfony/cache/Traits/RedisTrait.php b/vendor/symfony/cache/Traits/RedisTrait.php
index 350a54360e..b2faca651d 100644
--- a/vendor/symfony/cache/Traits/RedisTrait.php
+++ b/vendor/symfony/cache/Traits/RedisTrait.php
@@ -80,15 +80,19 @@ trait RedisTrait
*/
public static function createConnection($dsn, array $options = [])
{
- if (0 !== strpos($dsn, 'redis:')) {
- throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis:".', $dsn));
+ if (0 === strpos($dsn, 'redis:')) {
+ $scheme = 'redis';
+ } elseif (0 === strpos($dsn, 'rediss:')) {
+ $scheme = 'rediss';
+ } else {
+ throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis:" or "rediss".', $dsn));
}
if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) {
throw new CacheException(sprintf('Cannot find the "redis" extension nor the "predis/predis" package: %s', $dsn));
}
- $params = preg_replace_callback('#^redis:(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
+ $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
if (isset($m[2])) {
$auth = $m[2];
}
@@ -317,33 +321,13 @@ trait RedisTrait
protected function doClear($namespace)
{
$cleared = true;
- $hosts = [$this->redis];
- $evalArgs = [[$namespace], 0];
-
if ($this->redis instanceof \Predis\Client) {
$evalArgs = [0, $namespace];
-
- $connection = $this->redis->getConnection();
- if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
- $hosts = [];
- foreach ($connection as $c) {
- $hosts[] = new \Predis\Client($c);
- }
- }
- } elseif ($this->redis instanceof \RedisArray) {
- $hosts = [];
- foreach ($this->redis->_hosts() as $host) {
- $hosts[] = $this->redis->_instance($host);
- }
- } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
- $hosts = [];
- foreach ($this->redis->_masters() as $host) {
- $hosts[] = $h = new \Redis();
- $h->connect($host[0], $host[1]);
- }
+ } else {
+ $evalArgs = [[$namespace], 0];
}
- foreach ($hosts as $host) {
+ foreach ($this->getHosts() as $host) {
if (!isset($namespace[0])) {
$cleared = $host->flushDb() && $cleared;
continue;
@@ -475,4 +459,31 @@ trait RedisTrait
yield $id => $results[$k];
}
}
+
+ private function getHosts(): array
+ {
+ $hosts = [$this->redis];
+ if ($this->redis instanceof \Predis\Client) {
+ $connection = $this->redis->getConnection();
+ if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
+ $hosts = [];
+ foreach ($connection as $c) {
+ $hosts[] = new \Predis\Client($c);
+ }
+ }
+ } elseif ($this->redis instanceof \RedisArray) {
+ $hosts = [];
+ foreach ($this->redis->_hosts() as $host) {
+ $hosts[] = $this->redis->_instance($host);
+ }
+ } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
+ $hosts = [];
+ foreach ($this->redis->_masters() as $host) {
+ $hosts[] = $h = new \Redis();
+ $h->connect($host[0], $host[1]);
+ }
+ }
+
+ return $hosts;
+ }
}
diff --git a/vendor/symfony/cache/composer.json b/vendor/symfony/cache/composer.json
index 8f9e669a33..05bed1cf75 100644
--- a/vendor/symfony/cache/composer.json
+++ b/vendor/symfony/cache/composer.json
@@ -18,14 +18,14 @@
"provide": {
"psr/cache-implementation": "1.0",
"psr/simple-cache-implementation": "1.0",
- "symfony/cache-contracts-implementation": "1.0"
+ "symfony/cache-implementation": "1.0"
},
"require": {
"php": "^7.1.3",
"psr/cache": "~1.0",
"psr/log": "~1.0",
- "psr/simple-cache": "^1.0",
- "symfony/contracts": "^1.0",
+ "symfony/cache-contracts": "^1.1",
+ "symfony/service-contracts": "^1.1",
"symfony/var-exporter": "^4.2"
},
"require-dev": {
@@ -33,6 +33,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"
@@ -51,7 +52,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/vendor/symfony/cache/phpunit.xml.dist b/vendor/symfony/cache/phpunit.xml.dist
index c35458ca44..591046cf1c 100644
--- a/vendor/symfony/cache/phpunit.xml.dist
+++ b/vendor/symfony/cache/phpunit.xml.dist
@@ -40,7 +40,8 @@
<element key="1"><string>Doctrine\Common\Cache</string></element>
<element key="2"><string>Symfony\Component\Cache</string></element>
<element key="3"><string>Symfony\Component\Cache\Tests\Fixtures</string></element>
- <element key="4"><string>Symfony\Component\Cache\Traits</string></element>
+ <element key="4"><string>Symfony\Component\Cache\Tests\Traits</string></element>
+ <element key="5"><string>Symfony\Component\Cache\Traits</string></element>
</array>
</element>
</array>