From 05e38eadbeb3de19e5b26003c2b401e00bb71df4 Mon Sep 17 00:00:00 2001 From: polo Date: Sun, 18 Oct 2026 00:08:23 +0200 Subject: =?UTF-8?q?sortie=20de=20vendor=20du=20d=C3=A9p=C3=B4t,=20oubli=20?= =?UTF-8?q?dans=20config-template.ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/symfony/cache/Adapter/AbstractAdapter.php | 191 ---------- .../cache/Adapter/AbstractTagAwareAdapter.php | 320 ----------------- vendor/symfony/cache/Adapter/AdapterInterface.php | 35 -- vendor/symfony/cache/Adapter/ApcuAdapter.php | 116 ------ vendor/symfony/cache/Adapter/ArrayAdapter.php | 359 ------------------- vendor/symfony/cache/Adapter/ChainAdapter.php | 291 --------------- .../cache/Adapter/CouchbaseBucketAdapter.php | 237 ------------ .../cache/Adapter/CouchbaseCollectionAdapter.php | 198 ---------- .../symfony/cache/Adapter/DoctrineDbalAdapter.php | 383 -------------------- vendor/symfony/cache/Adapter/FilesystemAdapter.php | 29 -- .../cache/Adapter/FilesystemTagAwareAdapter.php | 267 -------------- vendor/symfony/cache/Adapter/MemcachedAdapter.php | 329 ----------------- vendor/symfony/cache/Adapter/NullAdapter.php | 105 ------ .../symfony/cache/Adapter/ParameterNormalizer.php | 35 -- vendor/symfony/cache/Adapter/PdoAdapter.php | 398 --------------------- vendor/symfony/cache/Adapter/PhpArrayAdapter.php | 389 -------------------- vendor/symfony/cache/Adapter/PhpFilesAdapter.php | 314 ---------------- vendor/symfony/cache/Adapter/ProxyAdapter.php | 206 ----------- vendor/symfony/cache/Adapter/Psr16Adapter.php | 71 ---- vendor/symfony/cache/Adapter/RedisAdapter.php | 25 -- .../symfony/cache/Adapter/RedisTagAwareAdapter.php | 310 ---------------- vendor/symfony/cache/Adapter/TagAwareAdapter.php | 370 ------------------- .../cache/Adapter/TagAwareAdapterInterface.php | 31 -- vendor/symfony/cache/Adapter/TraceableAdapter.php | 250 ------------- .../cache/Adapter/TraceableTagAwareAdapter.php | 35 -- 25 files changed, 5294 deletions(-) delete mode 100644 vendor/symfony/cache/Adapter/AbstractAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/AdapterInterface.php delete mode 100644 vendor/symfony/cache/Adapter/ApcuAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/ArrayAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/ChainAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/CouchbaseBucketAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/CouchbaseCollectionAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/FilesystemAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/MemcachedAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/NullAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/ParameterNormalizer.php delete mode 100644 vendor/symfony/cache/Adapter/PdoAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/PhpArrayAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/PhpFilesAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/ProxyAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/Psr16Adapter.php delete mode 100644 vendor/symfony/cache/Adapter/RedisAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/TagAwareAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php delete mode 100644 vendor/symfony/cache/Adapter/TraceableAdapter.php delete mode 100644 vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php (limited to 'vendor/symfony/cache/Adapter') diff --git a/vendor/symfony/cache/Adapter/AbstractAdapter.php b/vendor/symfony/cache/Adapter/AbstractAdapter.php deleted file mode 100644 index 5d6336e..0000000 --- a/vendor/symfony/cache/Adapter/AbstractAdapter.php +++ /dev/null @@ -1,191 +0,0 @@ - - * - * 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 Psr\Log\LoggerInterface; -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\CacheInterface; - -/** - * @author Nicolas Grekas - */ -abstract class AbstractAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface -{ - use AbstractAdapterTrait; - use ContractsTrait; - - /** - * @internal - */ - protected const NS_SEPARATOR = ':'; - - private static bool $apcuSupported; - - protected function __construct(string $namespace = '', int $defaultLifetime = 0) - { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; - $this->defaultLifetime = $defaultLifetime; - 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)); - } - self::$createCacheItem ??= \Closure::bind( - static function ($key, $value, $isHit) { - $item = new CacheItem(); - $item->key = $key; - $item->value = $value; - $item->isHit = $isHit; - $item->unpack(); - - return $item; - }, - null, - CacheItem::class - ); - self::$mergeByLifetime ??= \Closure::bind( - static function ($deferred, $namespace, &$expiredIds, $getId, $defaultLifetime) { - $byLifetime = []; - $now = microtime(true); - $expiredIds = []; - - foreach ($deferred as $key => $item) { - $key = (string) $key; - if (null === $item->expiry) { - $ttl = 0 < $defaultLifetime ? $defaultLifetime : 0; - } elseif (!$item->expiry) { - $ttl = 0; - } elseif (0 >= $ttl = (int) (0.1 + $item->expiry - $now)) { - $expiredIds[] = $getId($key); - continue; - } - $byLifetime[$ttl][$getId($key)] = $item->pack(); - } - - return $byLifetime; - }, - null, - CacheItem::class - ); - } - - /** - * Returns the best possible adapter that your runtime supports. - * - * Using ApcuAdapter makes system caches compatible with read-only filesystems. - */ - public static function createSystemCache(string $namespace, int $defaultLifetime, string $version, string $directory, ?LoggerInterface $logger = null): AdapterInterface - { - $opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory, true); - if (null !== $logger) { - $opcache->setLogger($logger); - } - - if (!self::$apcuSupported ??= ApcuAdapter::isSupported()) { - return $opcache; - } - - if ('cli' === \PHP_SAPI && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) { - return $opcache; - } - - $apcu = new ApcuAdapter($namespace, intdiv($defaultLifetime, 5), $version); - if (null !== $logger) { - $apcu->setLogger($logger); - } - - return new ChainAdapter([$apcu, $opcache]); - } - - public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): mixed - { - if (str_starts_with($dsn, 'redis:') || str_starts_with($dsn, 'rediss:')) { - return RedisAdapter::createConnection($dsn, $options); - } - if (str_starts_with($dsn, 'memcached:')) { - return MemcachedAdapter::createConnection($dsn, $options); - } - if (str_starts_with($dsn, 'couchbase:')) { - if (class_exists('CouchbaseBucket') && CouchbaseBucketAdapter::isSupported()) { - return CouchbaseBucketAdapter::createConnection($dsn, $options); - } - - return CouchbaseCollectionAdapter::createConnection($dsn, $options); - } - if (preg_match('/^(mysql|oci|pgsql|sqlsrv|sqlite):/', $dsn)) { - return PdoAdapter::createConnection($dsn, $options); - } - - throw new InvalidArgumentException('Unsupported DSN: it does not start with "redis[s]:", "memcached:", "couchbase:", "mysql:", "oci:", "pgsql:", "sqlsrv:" nor "sqlite:".'); - } - - public function commit(): bool - { - $ok = true; - $byLifetime = (self::$mergeByLifetime)($this->deferred, $this->namespace, $expiredIds, $this->getId(...), $this->defaultLifetime); - $retry = $this->deferred = []; - - if ($expiredIds) { - try { - $this->doDelete($expiredIds); - } catch (\Exception $e) { - $ok = false; - CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]); - } - } - foreach ($byLifetime as $lifetime => $values) { - try { - $e = $this->doSave($values, $lifetime); - } 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 = get_debug_type($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, 'cache-adapter' => get_debug_type($this)]); - } - } 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]; - $e = $this->doSave([$id => $v], $lifetime); - } catch (\Exception $e) { - } - if (true === $e || [] === $e) { - continue; - } - $ok = false; - $type = get_debug_type($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, 'cache-adapter' => get_debug_type($this)]); - } - } - - return $ok; - } -} diff --git a/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php b/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php deleted file mode 100644 index ef62b4f..0000000 --- a/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php +++ /dev/null @@ -1,320 +0,0 @@ - - * - * 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 - * @author André Rømcke - * - * @internal - */ -abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, LoggerAwareInterface, ResettableInterface -{ - use AbstractAdapterTrait; - use ContractsTrait; - - private const TAGS_PREFIX = "\1tags\1"; - - protected function __construct(string $namespace = '', int $defaultLifetime = 0) - { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; - $this->defaultLifetime = $defaultLifetime; - 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)); - } - self::$createCacheItem ??= \Closure::bind( - static function ($key, $value, $isHit) { - $item = new CacheItem(); - $item->key = $key; - $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] = isset($value['tags']) ? array_combine($value['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 - ); - self::$mergeByLifetime ??= \Closure::bind( - static function ($deferred, &$expiredIds, $getId, $tagPrefix, $defaultLifetime) { - $byLifetime = []; - $now = microtime(true); - $expiredIds = []; - - foreach ($deferred as $key => $item) { - $key = (string) $key; - if (null === $item->expiry) { - $ttl = 0 < $defaultLifetime ? $defaultLifetime : 0; - } elseif (!$item->expiry) { - $ttl = 0; - } elseif (0 >= $ttl = (int) (0.1 + $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) (0.1 + $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_key($value['tags'], $oldTags) as $addedTag) { - $value['tag-operations']['add'][] = $getId($tagPrefix.$addedTag); - } - foreach (array_diff_key($oldTags, $value['tags']) as $removedTag) { - $value['tag-operations']['remove'][] = $getId($tagPrefix.$removedTag); - } - $value['tags'] = array_keys($value['tags']); - - $byLifetime[$ttl][$getId($key)] = $value; - $item->metadata = $item->newMetadata; - } - - 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 - */ - abstract protected function doDelete(array $ids): bool; - - /** - * Removes relations between tags and deleted items. - * - * @param array $tagData Array of tag => key identifiers that should be removed from the pool - */ - abstract protected function doDeleteTagRelations(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 - */ - abstract protected function doInvalidate(array $tagIds): bool; - - /** - * Delete items and yields the tags they were bound to. - */ - protected function doDeleteYieldTags(array $ids): iterable - { - foreach ($this->doFetch($ids) as $id => $value) { - yield $id => \is_array($value) && \is_array($value['tags'] ?? null) ? $value['tags'] : []; - } - - $this->doDelete($ids); - } - - public function commit(): bool - { - $ok = true; - $byLifetime = (self::$mergeByLifetime)($this->deferred, $expiredIds, $this->getId(...), self::TAGS_PREFIX, $this->defaultLifetime); - $retry = $this->deferred = []; - - if ($expiredIds) { - // Tags are not cleaned up in this case, however that is done on invalidateTags(). - try { - $this->doDelete($expiredIds); - } catch (\Exception $e) { - $ok = false; - CacheItem::log($this->logger, 'Failed to delete expired items: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]); - } - } - 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 = get_debug_type($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, 'cache-adapter' => get_debug_type($this)]); - } - } 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 = get_debug_type($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, 'cache-adapter' => get_debug_type($this)]); - } - } - - return $ok; - } - - public function deleteItems(array $keys): bool - { - if (!$keys) { - return true; - } - - $ok = true; - $ids = []; - $tagData = []; - - foreach ($keys as $key) { - $ids[$key] = $this->getId($key); - unset($this->deferred[$key]); - } - - try { - foreach ($this->doDeleteYieldTags(array_values($ids)) as $id => $tags) { - foreach ($tags as $tag) { - $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id; - } - } - } catch (\Exception) { - $ok = false; - } - - try { - if ((!$tagData || $this->doDeleteTagRelations($tagData)) && $ok) { - return true; - } - } catch (\Exception) { - } - - // 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, 'cache-adapter' => get_debug_type($this)]); - $ok = false; - } - - return $ok; - } - - public function invalidateTags(array $tags): bool - { - if (!$tags) { - return false; - } - - $tagIds = []; - foreach (array_unique($tags) as $tag) { - $tagIds[] = $this->getId(self::TAGS_PREFIX.$tag); - } - - try { - if ($this->doInvalidate($tagIds)) { - return true; - } - } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to invalidate tags: '.$e->getMessage(), ['exception' => $e, 'cache-adapter' => get_debug_type($this)]); - } - - 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/AdapterInterface.php b/vendor/symfony/cache/Adapter/AdapterInterface.php deleted file mode 100644 index e556720..0000000 --- a/vendor/symfony/cache/Adapter/AdapterInterface.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * 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\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\CacheItem; - -// Help opcache.preload discover always-needed symbols -class_exists(CacheItem::class); - -/** - * Interface for adapters managing instances of Symfony's CacheItem. - * - * @author Kévin Dunglas - */ -interface AdapterInterface extends CacheItemPoolInterface -{ - public function getItem(mixed $key): CacheItem; - - /** - * @return iterable - */ - public function getItems(array $keys = []): iterable; - - public function clear(string $prefix = ''): bool; -} diff --git a/vendor/symfony/cache/Adapter/ApcuAdapter.php b/vendor/symfony/cache/Adapter/ApcuAdapter.php deleted file mode 100644 index 03b512f..0000000 --- a/vendor/symfony/cache/Adapter/ApcuAdapter.php +++ /dev/null @@ -1,116 +0,0 @@ - - * - * 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\CacheItem; -use Symfony\Component\Cache\Exception\CacheException; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; - -/** - * @author Nicolas Grekas - */ -class ApcuAdapter extends AbstractAdapter -{ - /** - * @throws CacheException if APCu is not enabled - */ - public function __construct( - string $namespace = '', - int $defaultLifetime = 0, - ?string $version = null, - private ?MarshallerInterface $marshaller = null, - ) { - if (!static::isSupported()) { - throw new CacheException('APCu is not enabled.'); - } - if ('cli' === \PHP_SAPI) { - ini_set('apc.use_request_time', 0); - } - parent::__construct($namespace, $defaultLifetime); - - if (null !== $version) { - CacheItem::validateKey($version); - - if (!apcu_exists($version.'@'.$namespace)) { - $this->doClear($namespace); - apcu_add($version.'@'.$namespace, null); - } - } - } - - public static function isSupported(): bool - { - return \function_exists('apcu_fetch') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOL); - } - - protected function doFetch(array $ids): iterable - { - $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); - try { - $values = []; - foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) { - if (null !== $v || $ok) { - $values[$k] = null !== $this->marshaller ? $this->marshaller->unmarshall($v) : $v; - } - } - - return $values; - } catch (\Error $e) { - throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); - } finally { - ini_set('unserialize_callback_func', $unserializeCallbackHandler); - } - } - - protected function doHave(string $id): bool - { - return apcu_exists($id); - } - - protected function doClear(string $namespace): bool - { - return isset($namespace[0]) && class_exists(\APCUIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) - ? apcu_delete(new \APCUIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) - : apcu_clear_cache(); - } - - protected function doDelete(array $ids): bool - { - foreach ($ids as $id) { - apcu_delete($id); - } - - return true; - } - - protected function doSave(array $values, int $lifetime): array|bool - { - if (null !== $this->marshaller && (!$values = $this->marshaller->marshall($values, $failed))) { - return $failed; - } - - try { - if (false === $failures = apcu_store($values, null, $lifetime)) { - $failures = $values; - } - - return array_keys($failures); - } catch (\Throwable $e) { - if (1 === \count($values)) { - // Workaround https://github.com/krakjoe/apcu/issues/170 - apcu_delete(array_key_first($values)); - } - - throw $e; - } - } -} diff --git a/vendor/symfony/cache/Adapter/ArrayAdapter.php b/vendor/symfony/cache/Adapter/ArrayAdapter.php deleted file mode 100644 index 0f1c49d..0000000 --- a/vendor/symfony/cache/Adapter/ArrayAdapter.php +++ /dev/null @@ -1,359 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Contracts\Cache\CacheInterface; - -/** - * An in-memory cache storage. - * - * Acts as a least-recently-used (LRU) storage when configured with a maximum number of items. - * - * @author Nicolas Grekas - */ -class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface -{ - use LoggerAwareTrait; - - private array $values = []; - private array $tags = []; - private array $expiries = []; - - private static \Closure $createCacheItem; - - /** - * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise - */ - public function __construct( - private int $defaultLifetime = 0, - private bool $storeSerialized = true, - private float $maxLifetime = 0, - private int $maxItems = 0, - ) { - if (0 > $maxLifetime) { - throw new InvalidArgumentException(sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime)); - } - - if (0 > $maxItems) { - throw new InvalidArgumentException(sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems)); - } - - self::$createCacheItem ??= \Closure::bind( - static function ($key, $value, $isHit, $tags) { - $item = new CacheItem(); - $item->key = $key; - $item->value = $value; - $item->isHit = $isHit; - if (null !== $tags) { - $item->metadata[CacheItem::METADATA_TAGS] = $tags; - } - - return $item; - }, - null, - CacheItem::class - ); - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - $item = $this->getItem($key); - $metadata = $item->getMetadata(); - - // ArrayAdapter works in memory, we don't care about stampede protection - if (\INF === $beta || !$item->isHit()) { - $save = true; - $item->set($callback($item, $save)); - if ($save) { - $this->save($item); - } - } - - return $item->get(); - } - - public function delete(string $key): bool - { - return $this->deleteItem($key); - } - - public function hasItem(mixed $key): bool - { - if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) { - if ($this->maxItems) { - // Move the item last in the storage - $value = $this->values[$key]; - unset($this->values[$key]); - $this->values[$key] = $value; - } - - return true; - } - \assert('' !== CacheItem::validateKey($key)); - - return isset($this->expiries[$key]) && !$this->deleteItem($key); - } - - public function getItem(mixed $key): CacheItem - { - if (!$isHit = $this->hasItem($key)) { - $value = null; - - if (!$this->maxItems) { - // Track misses in non-LRU mode only - $this->values[$key] = null; - } - } else { - $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key]; - } - - return (self::$createCacheItem)($key, $value, $isHit, $this->tags[$key] ?? null); - } - - public function getItems(array $keys = []): iterable - { - \assert(self::validateKeys($keys)); - - return $this->generateItems($keys, microtime(true), self::$createCacheItem); - } - - public function deleteItem(mixed $key): bool - { - \assert('' !== CacheItem::validateKey($key)); - unset($this->values[$key], $this->tags[$key], $this->expiries[$key]); - - return true; - } - - public function deleteItems(array $keys): bool - { - foreach ($keys as $key) { - $this->deleteItem($key); - } - - return true; - } - - public function save(CacheItemInterface $item): bool - { - if (!$item instanceof CacheItem) { - return false; - } - $item = (array) $item; - $key = $item["\0*\0key"]; - $value = $item["\0*\0value"]; - $expiry = $item["\0*\0expiry"]; - - $now = microtime(true); - - if (null !== $expiry) { - if (!$expiry) { - $expiry = \PHP_INT_MAX; - } elseif ($expiry <= $now) { - $this->deleteItem($key); - - return true; - } - } - if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) { - return false; - } - if (null === $expiry && 0 < $this->defaultLifetime) { - $expiry = $this->defaultLifetime; - $expiry = $now + ($expiry > ($this->maxLifetime ?: $expiry) ? $this->maxLifetime : $expiry); - } elseif ($this->maxLifetime && (null === $expiry || $expiry > $now + $this->maxLifetime)) { - $expiry = $now + $this->maxLifetime; - } - - if ($this->maxItems) { - unset($this->values[$key], $this->tags[$key]); - - // Iterate items and vacuum expired ones while we are at it - foreach ($this->values as $k => $v) { - if ($this->expiries[$k] > $now && \count($this->values) < $this->maxItems) { - break; - } - - unset($this->values[$k], $this->tags[$k], $this->expiries[$k]); - } - } - - $this->values[$key] = $value; - $this->expiries[$key] = $expiry ?? \PHP_INT_MAX; - - if (null === $this->tags[$key] = $item["\0*\0newMetadata"][CacheItem::METADATA_TAGS] ?? null) { - unset($this->tags[$key]); - } - - return true; - } - - public function saveDeferred(CacheItemInterface $item): bool - { - return $this->save($item); - } - - public function commit(): bool - { - return true; - } - - public function clear(string $prefix = ''): bool - { - if ('' !== $prefix) { - $now = microtime(true); - - foreach ($this->values as $key => $value) { - if (!isset($this->expiries[$key]) || $this->expiries[$key] <= $now || str_starts_with($key, $prefix)) { - unset($this->values[$key], $this->tags[$key], $this->expiries[$key]); - } - } - - if ($this->values) { - return true; - } - } - - $this->values = $this->tags = $this->expiries = []; - - return true; - } - - /** - * Returns all cached values, with cache miss as null. - */ - public function getValues(): array - { - if (!$this->storeSerialized) { - return $this->values; - } - - $values = $this->values; - foreach ($values as $k => $v) { - if (null === $v || 'N;' === $v) { - continue; - } - if (!\is_string($v) || !isset($v[2]) || ':' !== $v[1]) { - $values[$k] = serialize($v); - } - } - - return $values; - } - - public function reset(): void - { - $this->clear(); - } - - private function generateItems(array $keys, float $now, \Closure $f): \Generator - { - foreach ($keys as $i => $key) { - if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) { - $value = null; - - if (!$this->maxItems) { - // Track misses in non-LRU mode only - $this->values[$key] = null; - } - } else { - if ($this->maxItems) { - // Move the item last in the storage - $value = $this->values[$key]; - unset($this->values[$key]); - $this->values[$key] = $value; - } - - $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key]; - } - unset($keys[$i]); - - yield $key => $f($key, $value, $isHit, $this->tags[$key] ?? null); - } - - foreach ($keys as $key) { - yield $key => $f($key, null, false); - } - } - - private function freeze($value, string $key): string|int|float|bool|array|\UnitEnum|null - { - if (null === $value) { - return 'N;'; - } - if (\is_string($value)) { - // Serialize strings if they could be confused with serialized objects or arrays - if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { - return serialize($value); - } - } elseif (!\is_scalar($value)) { - try { - $serialized = serialize($value); - } catch (\Exception $e) { - unset($this->values[$key], $this->tags[$key]); - $type = get_debug_type($value); - $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage()); - CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]); - - return null; - } - // Keep value serialized if it contains any objects or any internal references - if ('C' === $serialized[0] || 'O' === $serialized[0] || preg_match('/;[OCRr]:[1-9]/', $serialized)) { - return $serialized; - } - } - - return $value; - } - - private function unfreeze(string $key, bool &$isHit): mixed - { - if ('N;' === $value = $this->values[$key]) { - return null; - } - if (\is_string($value) && isset($value[2]) && ':' === $value[1]) { - try { - $value = unserialize($value); - } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]); - $value = false; - } - if (false === $value) { - $value = null; - $isHit = false; - - if (!$this->maxItems) { - $this->values[$key] = null; - } - } - } - - return $value; - } - - private function validateKeys(array $keys): bool - { - foreach ($keys as $key) { - if (!\is_string($key) || !isset($this->expiries[$key])) { - CacheItem::validateKey($key); - } - } - - return true; - } -} diff --git a/vendor/symfony/cache/Adapter/ChainAdapter.php b/vendor/symfony/cache/Adapter/ChainAdapter.php deleted file mode 100644 index 1418cff..0000000 --- a/vendor/symfony/cache/Adapter/ChainAdapter.php +++ /dev/null @@ -1,291 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; -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\ContractsTrait; -use Symfony\Contracts\Cache\CacheInterface; -use Symfony\Contracts\Service\ResetInterface; - -/** - * Chains several adapters together. - * - * Cached items are fetched from the first adapter having them in its data store. - * They are saved and deleted in all adapters at once. - * - * @author Kévin Dunglas - */ -class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface -{ - use ContractsTrait; - - private array $adapters = []; - private int $adapterCount; - - private static \Closure $syncItem; - - /** - * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items - * @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones - */ - public function __construct( - array $adapters, - private int $defaultLifetime = 0, - ) { - if (!$adapters) { - throw new InvalidArgumentException('At least one adapter must be specified.'); - } - - foreach ($adapters as $adapter) { - if (!$adapter instanceof CacheItemPoolInterface) { - throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class)); - } - if ('cli' === \PHP_SAPI && $adapter instanceof ApcuAdapter && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) { - continue; // skip putting APCu in the chain when the backend is disabled - } - - if ($adapter instanceof AdapterInterface) { - $this->adapters[] = $adapter; - } else { - $this->adapters[] = new ProxyAdapter($adapter); - } - } - $this->adapterCount = \count($this->adapters); - - self::$syncItem ??= \Closure::bind( - static function ($sourceItem, $item, $defaultLifetime, $sourceMetadata = null) { - $sourceItem->isTaggable = false; - $sourceMetadata ??= $sourceItem->metadata; - - $item->value = $sourceItem->value; - $item->isHit = $sourceItem->isHit; - $item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata; - - if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) { - $item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY]))); - } elseif (0 < $defaultLifetime) { - $item->expiresAfter($defaultLifetime); - } - - return $item; - }, - null, - CacheItem::class - ); - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - $doSave = true; - $callback = static function (CacheItem $item, bool &$save) use ($callback, &$doSave) { - $value = $callback($item, $save); - $doSave = $save; - - return $value; - }; - - $wrap = function (?CacheItem $item = null, bool &$save = true) use ($key, $callback, $beta, &$wrap, &$doSave, &$metadata) { - static $lastItem; - static $i = 0; - $adapter = $this->adapters[$i]; - if (isset($this->adapters[++$i])) { - $callback = $wrap; - $beta = \INF === $beta ? \INF : 0; - } - if ($adapter instanceof CacheInterface) { - $value = $adapter->get($key, $callback, $beta, $metadata); - } else { - $value = $this->doGet($adapter, $key, $callback, $beta, $metadata); - } - if (null !== $item) { - (self::$syncItem)($lastItem ??= $item, $item, $this->defaultLifetime, $metadata); - } - $save = $doSave; - - return $value; - }; - - return $wrap(); - } - - public function getItem(mixed $key): CacheItem - { - $syncItem = self::$syncItem; - $misses = []; - - foreach ($this->adapters as $i => $adapter) { - $item = $adapter->getItem($key); - - if ($item->isHit()) { - while (0 <= --$i) { - $this->adapters[$i]->save($syncItem($item, $misses[$i], $this->defaultLifetime)); - } - - return $item; - } - - $misses[$i] = $item; - } - - return $item; - } - - public function getItems(array $keys = []): iterable - { - return $this->generateItems($this->adapters[0]->getItems($keys), 0); - } - - private function generateItems(iterable $items, int $adapterIndex): \Generator - { - $missing = []; - $misses = []; - $nextAdapterIndex = $adapterIndex + 1; - $nextAdapter = $this->adapters[$nextAdapterIndex] ?? null; - - foreach ($items as $k => $item) { - if (!$nextAdapter || $item->isHit()) { - yield $k => $item; - } else { - $missing[] = $k; - $misses[$k] = $item; - } - } - - if ($missing) { - $syncItem = self::$syncItem; - $adapter = $this->adapters[$adapterIndex]; - $items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex); - - foreach ($items as $k => $item) { - if ($item->isHit()) { - $adapter->save($syncItem($item, $misses[$k], $this->defaultLifetime)); - } - - yield $k => $item; - } - } - } - - public function hasItem(mixed $key): bool - { - foreach ($this->adapters as $adapter) { - if ($adapter->hasItem($key)) { - return true; - } - } - - return false; - } - - public function clear(string $prefix = ''): bool - { - $cleared = true; - $i = $this->adapterCount; - - while ($i--) { - if ($this->adapters[$i] instanceof AdapterInterface) { - $cleared = $this->adapters[$i]->clear($prefix) && $cleared; - } else { - $cleared = $this->adapters[$i]->clear() && $cleared; - } - } - - return $cleared; - } - - public function deleteItem(mixed $key): bool - { - $deleted = true; - $i = $this->adapterCount; - - while ($i--) { - $deleted = $this->adapters[$i]->deleteItem($key) && $deleted; - } - - return $deleted; - } - - public function deleteItems(array $keys): bool - { - $deleted = true; - $i = $this->adapterCount; - - while ($i--) { - $deleted = $this->adapters[$i]->deleteItems($keys) && $deleted; - } - - return $deleted; - } - - public function save(CacheItemInterface $item): bool - { - $saved = true; - $i = $this->adapterCount; - - while ($i--) { - $saved = $this->adapters[$i]->save($item) && $saved; - } - - return $saved; - } - - public function saveDeferred(CacheItemInterface $item): bool - { - $saved = true; - $i = $this->adapterCount; - - while ($i--) { - $saved = $this->adapters[$i]->saveDeferred($item) && $saved; - } - - return $saved; - } - - public function commit(): bool - { - $committed = true; - $i = $this->adapterCount; - - while ($i--) { - $committed = $this->adapters[$i]->commit() && $committed; - } - - return $committed; - } - - public function prune(): bool - { - $pruned = true; - - foreach ($this->adapters as $adapter) { - if ($adapter instanceof PruneableInterface) { - $pruned = $adapter->prune() && $pruned; - } - } - - return $pruned; - } - - public function reset(): void - { - foreach ($this->adapters as $adapter) { - if ($adapter instanceof ResetInterface) { - $adapter->reset(); - } - } - } -} diff --git a/vendor/symfony/cache/Adapter/CouchbaseBucketAdapter.php b/vendor/symfony/cache/Adapter/CouchbaseBucketAdapter.php deleted file mode 100644 index 106d7fd..0000000 --- a/vendor/symfony/cache/Adapter/CouchbaseBucketAdapter.php +++ /dev/null @@ -1,237 +0,0 @@ - - * - * 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\CacheException; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; - -trigger_deprecation('symfony/cache', '7.1', 'The "%s" class is deprecated, use "%s" instead.', CouchbaseBucketAdapter::class, CouchbaseCollectionAdapter::class); - -/** - * @author Antonio Jose Cerezo Aranda - * - * @deprecated since Symfony 7.1, use {@see CouchbaseCollectionAdapter} instead - */ -class CouchbaseBucketAdapter extends AbstractAdapter -{ - private const THIRTY_DAYS_IN_SECONDS = 2592000; - private const MAX_KEY_LENGTH = 250; - private const KEY_NOT_FOUND = 13; - private const VALID_DSN_OPTIONS = [ - 'operationTimeout', - 'configTimeout', - 'configNodeTimeout', - 'n1qlTimeout', - 'httpTimeout', - 'configDelay', - 'htconfigIdleTimeout', - 'durabilityInterval', - 'durabilityTimeout', - ]; - - private MarshallerInterface $marshaller; - - public function __construct( - private \CouchbaseBucket $bucket, - string $namespace = '', - int $defaultLifetime = 0, - ?MarshallerInterface $marshaller = null, - ) { - if (!static::isSupported()) { - throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.'); - } - - $this->maxIdLength = static::MAX_KEY_LENGTH; - - parent::__construct($namespace, $defaultLifetime); - $this->enableVersioning(); - $this->marshaller = $marshaller ?? new DefaultMarshaller(); - } - - public static function createConnection(#[\SensitiveParameter] array|string $servers, array $options = []): \CouchbaseBucket - { - if (\is_string($servers)) { - $servers = [$servers]; - } - - if (!static::isSupported()) { - throw new CacheException('Couchbase >= 2.6.0 < 3.0.0 is required.'); - } - - set_error_handler(static fn ($type, $msg, $file, $line) => throw new \ErrorException($msg, 0, $type, $file, $line)); - - $dsnPattern = '/^(?couchbase(?:s)?)\:\/\/(?:(?[^\:]+)\:(?[^\@]{6,})@)?' - .'(?[^\:]+(?:\:\d+)?)(?:\/(?[^\?]+))(?:\?(?.*))?$/i'; - - $newServers = []; - $protocol = 'couchbase'; - try { - $options = self::initOptions($options); - $username = $options['username']; - $password = $options['password']; - - foreach ($servers as $dsn) { - if (!str_starts_with($dsn, 'couchbase:')) { - throw new InvalidArgumentException('Invalid Couchbase DSN: it does not start with "couchbase:".'); - } - - preg_match($dsnPattern, $dsn, $matches); - - $username = $matches['username'] ?: $username; - $password = $matches['password'] ?: $password; - $protocol = $matches['protocol'] ?: $protocol; - - if (isset($matches['options'])) { - $optionsInDsn = self::getOptions($matches['options']); - - foreach ($optionsInDsn as $parameter => $value) { - $options[$parameter] = $value; - } - } - - $newServers[] = $matches['host']; - } - - $connectionString = $protocol.'://'.implode(',', $newServers); - - $client = new \CouchbaseCluster($connectionString); - $client->authenticateAs($username, $password); - - $bucket = $client->openBucket($matches['bucketName']); - - unset($options['username'], $options['password']); - foreach ($options as $option => $value) { - if ($value) { - $bucket->$option = $value; - } - } - - return $bucket; - } finally { - restore_error_handler(); - } - } - - public static function isSupported(): bool - { - return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '2.6.0', '>=') && version_compare(phpversion('couchbase'), '3.0', '<'); - } - - private static function getOptions(string $options): array - { - $results = []; - $optionsInArray = explode('&', $options); - - foreach ($optionsInArray as $option) { - [$key, $value] = explode('=', $option); - - if (\in_array($key, static::VALID_DSN_OPTIONS, true)) { - $results[$key] = $value; - } - } - - return $results; - } - - private static function initOptions(array $options): array - { - $options['username'] ??= ''; - $options['password'] ??= ''; - $options['operationTimeout'] ??= 0; - $options['configTimeout'] ??= 0; - $options['configNodeTimeout'] ??= 0; - $options['n1qlTimeout'] ??= 0; - $options['httpTimeout'] ??= 0; - $options['configDelay'] ??= 0; - $options['htconfigIdleTimeout'] ??= 0; - $options['durabilityInterval'] ??= 0; - $options['durabilityTimeout'] ??= 0; - - return $options; - } - - protected function doFetch(array $ids): iterable - { - $resultsCouchbase = $this->bucket->get($ids); - - $results = []; - foreach ($resultsCouchbase as $key => $value) { - if (null !== $value->error) { - continue; - } - $results[$key] = $this->marshaller->unmarshall($value->value); - } - - return $results; - } - - protected function doHave(string $id): bool - { - return false !== $this->bucket->get($id); - } - - protected function doClear(string $namespace): bool - { - if ('' === $namespace) { - $this->bucket->manager()->flush(); - - return true; - } - - return false; - } - - protected function doDelete(array $ids): bool - { - $results = $this->bucket->remove(array_values($ids)); - - foreach ($results as $key => $result) { - if (null !== $result->error && static::KEY_NOT_FOUND !== $result->error->getCode()) { - continue; - } - unset($results[$key]); - } - - return 0 === \count($results); - } - - protected function doSave(array $values, int $lifetime): array|bool - { - if (!$values = $this->marshaller->marshall($values, $failed)) { - return $failed; - } - - $lifetime = $this->normalizeExpiry($lifetime); - - $ko = []; - foreach ($values as $key => $value) { - $result = $this->bucket->upsert($key, $value, ['expiry' => $lifetime]); - - if (null !== $result->error) { - $ko[$key] = $result; - } - } - - return [] === $ko ? true : $ko; - } - - private function normalizeExpiry(int $expiry): int - { - if ($expiry && $expiry > static::THIRTY_DAYS_IN_SECONDS) { - $expiry += time(); - } - - return $expiry; - } -} diff --git a/vendor/symfony/cache/Adapter/CouchbaseCollectionAdapter.php b/vendor/symfony/cache/Adapter/CouchbaseCollectionAdapter.php deleted file mode 100644 index 9646bc3..0000000 --- a/vendor/symfony/cache/Adapter/CouchbaseCollectionAdapter.php +++ /dev/null @@ -1,198 +0,0 @@ - - * - * 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 Couchbase\Bucket; -use Couchbase\Cluster; -use Couchbase\ClusterOptions; -use Couchbase\Collection; -use Couchbase\DocumentNotFoundException; -use Couchbase\UpsertOptions; -use Symfony\Component\Cache\Exception\CacheException; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; - -/** - * @author Antonio Jose Cerezo Aranda - */ -class CouchbaseCollectionAdapter extends AbstractAdapter -{ - private const MAX_KEY_LENGTH = 250; - - private MarshallerInterface $marshaller; - - public function __construct( - private Collection $connection, - string $namespace = '', - int $defaultLifetime = 0, - ?MarshallerInterface $marshaller = null, - ) { - if (!static::isSupported()) { - throw new CacheException('Couchbase >= 3.0.5 < 4.0.0 is required.'); - } - - $this->maxIdLength = static::MAX_KEY_LENGTH; - - parent::__construct($namespace, $defaultLifetime); - $this->enableVersioning(); - $this->marshaller = $marshaller ?? new DefaultMarshaller(); - } - - public static function createConnection(#[\SensitiveParameter] array|string $dsn, array $options = []): Bucket|Collection - { - if (\is_string($dsn)) { - $dsn = [$dsn]; - } - - if (!static::isSupported()) { - throw new CacheException('Couchbase >= 3.0.5 < 4.0.0 is required.'); - } - - set_error_handler(static fn ($type, $msg, $file, $line) => throw new \ErrorException($msg, 0, $type, $file, $line)); - - $pathPattern = '/^(?:\/(?[^\/\?]+))(?:(?:\/(?[^\/]+))(?:\/(?[^\/\?]+)))?(?:\/)?$/'; - $newServers = []; - $protocol = 'couchbase'; - try { - $username = $options['username'] ?? ''; - $password = $options['password'] ?? ''; - - foreach ($dsn as $server) { - if (!str_starts_with($server, 'couchbase:')) { - throw new InvalidArgumentException('Invalid Couchbase DSN: it does not start with "couchbase:".'); - } - - $params = parse_url($server); - - $username = isset($params['user']) ? rawurldecode($params['user']) : $username; - $password = isset($params['pass']) ? rawurldecode($params['pass']) : $password; - $protocol = $params['scheme'] ?? $protocol; - - if (isset($params['query'])) { - $optionsInDsn = self::getOptions($params['query']); - - foreach ($optionsInDsn as $parameter => $value) { - $options[$parameter] = $value; - } - } - - $newServers[] = $params['host']; - } - - $option = isset($params['query']) ? '?'.$params['query'] : ''; - $connectionString = $protocol.'://'.implode(',', $newServers).$option; - - $clusterOptions = new ClusterOptions(); - $clusterOptions->credentials($username, $password); - - $client = new Cluster($connectionString, $clusterOptions); - - preg_match($pathPattern, $params['path'] ?? '', $matches); - $bucket = $client->bucket($matches['bucketName']); - $collection = $bucket->defaultCollection(); - if (!empty($matches['scopeName'])) { - $scope = $bucket->scope($matches['scopeName']); - $collection = $scope->collection($matches['collectionName']); - } - - return $collection; - } finally { - restore_error_handler(); - } - } - - public static function isSupported(): bool - { - return \extension_loaded('couchbase') && version_compare(phpversion('couchbase'), '3.0.5', '>=') && version_compare(phpversion('couchbase'), '4.0', '<'); - } - - private static function getOptions(string $options): array - { - $results = []; - $optionsInArray = explode('&', $options); - - foreach ($optionsInArray as $option) { - [$key, $value] = explode('=', $option); - - $results[$key] = $value; - } - - return $results; - } - - protected function doFetch(array $ids): array - { - $results = []; - foreach ($ids as $id) { - try { - $resultCouchbase = $this->connection->get($id); - } catch (DocumentNotFoundException) { - continue; - } - - $content = $resultCouchbase->value ?? $resultCouchbase->content(); - - $results[$id] = $this->marshaller->unmarshall($content); - } - - return $results; - } - - protected function doHave($id): bool - { - return $this->connection->exists($id)->exists(); - } - - protected function doClear($namespace): bool - { - return false; - } - - protected function doDelete(array $ids): bool - { - $idsErrors = []; - foreach ($ids as $id) { - try { - $result = $this->connection->remove($id); - - if (null === $result->mutationToken()) { - $idsErrors[] = $id; - } - } catch (DocumentNotFoundException) { - } - } - - return 0 === \count($idsErrors); - } - - protected function doSave(array $values, $lifetime): array|bool - { - if (!$values = $this->marshaller->marshall($values, $failed)) { - return $failed; - } - - $upsertOptions = new UpsertOptions(); - $upsertOptions->expiry($lifetime); - - $ko = []; - foreach ($values as $key => $value) { - try { - $this->connection->upsert($key, $value, $upsertOptions); - } catch (\Exception) { - $ko[$key] = ''; - } - } - - return [] === $ko ? true : $ko; - } -} diff --git a/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php b/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php deleted file mode 100644 index ae2bea7..0000000 --- a/vendor/symfony/cache/Adapter/DoctrineDbalAdapter.php +++ /dev/null @@ -1,383 +0,0 @@ - - * - * 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 Doctrine\DBAL\ArrayParameterType; -use Doctrine\DBAL\Configuration; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\DriverManager; -use Doctrine\DBAL\Exception as DBALException; -use Doctrine\DBAL\Exception\TableNotFoundException; -use Doctrine\DBAL\ParameterType; -use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory; -use Doctrine\DBAL\Schema\Schema; -use Doctrine\DBAL\Tools\DsnParser; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\PruneableInterface; - -class DoctrineDbalAdapter extends AbstractAdapter implements PruneableInterface -{ - private const MAX_KEY_LENGTH = 255; - - private MarshallerInterface $marshaller; - private Connection $conn; - private string $platformName; - private string $table = 'cache_items'; - private string $idCol = 'item_id'; - private string $dataCol = 'item_data'; - private string $lifetimeCol = 'item_lifetime'; - private string $timeCol = 'item_time'; - - /** - * You can either pass an existing database Doctrine DBAL Connection or - * a DSN string that will be used to connect to the database. - * - * The cache table is created automatically when possible. - * Otherwise, use the createTable() method. - * - * List of available options: - * * db_table: The name of the table [default: cache_items] - * * db_id_col: The column where to store the cache id [default: item_id] - * * db_data_col: The column where to store the cache data [default: item_data] - * * db_lifetime_col: The column where to store the lifetime [default: item_lifetime] - * * db_time_col: The column where to store the timestamp [default: item_time] - * - * @throws InvalidArgumentException When namespace contains invalid characters - */ - public function __construct( - Connection|string $connOrDsn, - private string $namespace = '', - int $defaultLifetime = 0, - array $options = [], - ?MarshallerInterface $marshaller = null, - ) { - if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) { - throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); - } - - if ($connOrDsn instanceof Connection) { - $this->conn = $connOrDsn; - } else { - if (!class_exists(DriverManager::class)) { - throw new InvalidArgumentException('Failed to parse DSN. Try running "composer require doctrine/dbal".'); - } - $params = (new DsnParser([ - 'db2' => 'ibm_db2', - 'mssql' => 'pdo_sqlsrv', - 'mysql' => 'pdo_mysql', - 'mysql2' => 'pdo_mysql', - 'postgres' => 'pdo_pgsql', - 'postgresql' => 'pdo_pgsql', - 'pgsql' => 'pdo_pgsql', - 'sqlite' => 'pdo_sqlite', - 'sqlite3' => 'pdo_sqlite', - ]))->parse($connOrDsn); - - $config = new Configuration(); - $config->setSchemaManagerFactory(new DefaultSchemaManagerFactory()); - - $this->conn = DriverManager::getConnection($params, $config); - } - - $this->maxIdLength = self::MAX_KEY_LENGTH; - $this->table = $options['db_table'] ?? $this->table; - $this->idCol = $options['db_id_col'] ?? $this->idCol; - $this->dataCol = $options['db_data_col'] ?? $this->dataCol; - $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol; - $this->timeCol = $options['db_time_col'] ?? $this->timeCol; - $this->marshaller = $marshaller ?? new DefaultMarshaller(); - - parent::__construct($namespace, $defaultLifetime); - } - - /** - * Creates the table to store cache items which can be called once for setup. - * - * Cache ID are saved in a column of maximum length 255. Cache data is - * saved in a BLOB. - * - * @throws DBALException When the table already exists - */ - public function createTable(): void - { - $schema = new Schema(); - $this->addTableToSchema($schema); - - foreach ($schema->toSql($this->conn->getDatabasePlatform()) as $sql) { - $this->conn->executeStatement($sql); - } - } - - public function configureSchema(Schema $schema, Connection $forConnection, \Closure $isSameDatabase): void - { - if ($schema->hasTable($this->table)) { - return; - } - - if ($forConnection !== $this->conn && !$isSameDatabase($this->conn->executeStatement(...))) { - return; - } - - $this->addTableToSchema($schema); - } - - public function prune(): bool - { - $deleteSql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ?"; - $params = [time()]; - $paramTypes = [ParameterType::INTEGER]; - - if ('' !== $this->namespace) { - $deleteSql .= " AND $this->idCol LIKE ?"; - $params[] = sprintf('%s%%', $this->namespace); - $paramTypes[] = ParameterType::STRING; - } - - try { - $this->conn->executeStatement($deleteSql, $params, $paramTypes); - } catch (TableNotFoundException) { - } - - return true; - } - - protected function doFetch(array $ids): iterable - { - $now = time(); - $expired = []; - - $sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN (?)"; - $result = $this->conn->executeQuery($sql, [ - $now, - $ids, - ], [ - ParameterType::INTEGER, - ArrayParameterType::STRING, - ])->iterateNumeric(); - - foreach ($result as $row) { - if (null === $row[1]) { - $expired[] = $row[0]; - } else { - yield $row[0] => $this->marshaller->unmarshall(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]); - } - } - - if ($expired) { - $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ? AND $this->idCol IN (?)"; - $this->conn->executeStatement($sql, [ - $now, - $expired, - ], [ - ParameterType::INTEGER, - ArrayParameterType::STRING, - ]); - } - } - - protected function doHave(string $id): bool - { - $sql = "SELECT 1 FROM $this->table WHERE $this->idCol = ? AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ?)"; - $result = $this->conn->executeQuery($sql, [ - $id, - time(), - ], [ - ParameterType::STRING, - ParameterType::INTEGER, - ]); - - return (bool) $result->fetchOne(); - } - - protected function doClear(string $namespace): bool - { - if ('' === $namespace) { - $sql = $this->conn->getDatabasePlatform()->getTruncateTableSQL($this->table); - } else { - $sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'"; - } - - try { - $this->conn->executeStatement($sql); - } catch (TableNotFoundException) { - } - - return true; - } - - protected function doDelete(array $ids): bool - { - $sql = "DELETE FROM $this->table WHERE $this->idCol IN (?)"; - try { - $this->conn->executeStatement($sql, [array_values($ids)], [ArrayParameterType::STRING]); - } catch (TableNotFoundException) { - } - - return true; - } - - protected function doSave(array $values, int $lifetime): array|bool - { - if (!$values = $this->marshaller->marshall($values, $failed)) { - return $failed; - } - - $platformName = $this->getPlatformName(); - $insertSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?)"; - - switch ($platformName) { - case 'mysql': - $sql = $insertSql." ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)"; - break; - case 'oci': - // DUAL is Oracle specific dummy table - $sql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?"; - break; - case 'sqlsrv': - // MERGE is only available since SQL Server 2008 and must be terminated by semicolon - // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx - $sql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;"; - break; - case 'sqlite': - $sql = 'INSERT OR REPLACE'.substr($insertSql, 6); - break; - case 'pgsql': - $sql = $insertSql." ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)"; - break; - default: - $platformName = null; - $sql = "UPDATE $this->table SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ? WHERE $this->idCol = ?"; - break; - } - - $now = time(); - $lifetime = $lifetime ?: null; - try { - $stmt = $this->conn->prepare($sql); - } catch (TableNotFoundException) { - if (!$this->conn->isTransactionActive() || \in_array($platformName, ['pgsql', 'sqlite', 'sqlsrv'], true)) { - $this->createTable(); - } - $stmt = $this->conn->prepare($sql); - } - - if ('sqlsrv' === $platformName || 'oci' === $platformName) { - $bind = static function ($id, $data) use ($stmt) { - $stmt->bindValue(1, $id); - $stmt->bindValue(2, $id); - $stmt->bindValue(3, $data, ParameterType::LARGE_OBJECT); - $stmt->bindValue(6, $data, ParameterType::LARGE_OBJECT); - }; - $stmt->bindValue(4, $lifetime, ParameterType::INTEGER); - $stmt->bindValue(5, $now, ParameterType::INTEGER); - $stmt->bindValue(7, $lifetime, ParameterType::INTEGER); - $stmt->bindValue(8, $now, ParameterType::INTEGER); - } elseif (null !== $platformName) { - $bind = static function ($id, $data) use ($stmt) { - $stmt->bindValue(1, $id); - $stmt->bindValue(2, $data, ParameterType::LARGE_OBJECT); - }; - $stmt->bindValue(3, $lifetime, ParameterType::INTEGER); - $stmt->bindValue(4, $now, ParameterType::INTEGER); - } else { - $stmt->bindValue(2, $lifetime, ParameterType::INTEGER); - $stmt->bindValue(3, $now, ParameterType::INTEGER); - - $insertStmt = $this->conn->prepare($insertSql); - $insertStmt->bindValue(3, $lifetime, ParameterType::INTEGER); - $insertStmt->bindValue(4, $now, ParameterType::INTEGER); - - $bind = static function ($id, $data) use ($stmt, $insertStmt) { - $stmt->bindValue(1, $data, ParameterType::LARGE_OBJECT); - $stmt->bindValue(4, $id); - $insertStmt->bindValue(1, $id); - $insertStmt->bindValue(2, $data, ParameterType::LARGE_OBJECT); - }; - } - - foreach ($values as $id => $data) { - $bind($id, $data); - try { - $rowCount = $stmt->executeStatement(); - } catch (TableNotFoundException) { - if (!$this->conn->isTransactionActive() || \in_array($platformName, ['pgsql', 'sqlite', 'sqlsrv'], true)) { - $this->createTable(); - } - $rowCount = $stmt->executeStatement(); - } - if (null === $platformName && 0 === $rowCount) { - try { - $insertStmt->executeStatement(); - } catch (DBALException) { - // A concurrent write won, let it be - } - } - } - - return $failed; - } - - /** - * @internal - */ - protected function getId(mixed $key): string - { - if ('pgsql' !== $this->platformName ??= $this->getPlatformName()) { - return parent::getId($key); - } - - if (str_contains($key, "\0") || str_contains($key, '%') || !preg_match('//u', $key)) { - $key = rawurlencode($key); - } - - return parent::getId($key); - } - - private function getPlatformName(): string - { - if (isset($this->platformName)) { - return $this->platformName; - } - - $platform = $this->conn->getDatabasePlatform(); - - return $this->platformName = match (true) { - $platform instanceof \Doctrine\DBAL\Platforms\AbstractMySQLPlatform => 'mysql', - $platform instanceof \Doctrine\DBAL\Platforms\SqlitePlatform => 'sqlite', - $platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform => 'pgsql', - $platform instanceof \Doctrine\DBAL\Platforms\OraclePlatform => 'oci', - $platform instanceof \Doctrine\DBAL\Platforms\SQLServerPlatform => 'sqlsrv', - default => $platform::class, - }; - } - - private function addTableToSchema(Schema $schema): void - { - $types = [ - 'mysql' => 'binary', - 'sqlite' => 'text', - ]; - - $table = $schema->createTable($this->table); - $table->addColumn($this->idCol, $types[$this->getPlatformName()] ?? 'string', ['length' => 255]); - $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]); - $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => true, 'notnull' => false]); - $table->addColumn($this->timeCol, 'integer', ['unsigned' => true]); - $table->setPrimaryKey([$this->idCol]); - } -} diff --git a/vendor/symfony/cache/Adapter/FilesystemAdapter.php b/vendor/symfony/cache/Adapter/FilesystemAdapter.php deleted file mode 100644 index 13daa56..0000000 --- a/vendor/symfony/cache/Adapter/FilesystemAdapter.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * 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\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Traits\FilesystemTrait; - -class FilesystemAdapter extends AbstractAdapter implements PruneableInterface -{ - use FilesystemTrait; - - 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); - } -} diff --git a/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php b/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php deleted file mode 100644 index 80edee4..0000000 --- a/vendor/symfony/cache/Adapter/FilesystemTagAwareAdapter.php +++ /dev/null @@ -1,267 +0,0 @@ - - * - * 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\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\Marshaller\TagAwareMarshaller; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Traits\FilesystemTrait; - -/** - * Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls. - * - * @author Nicolas Grekas - * @author André Rømcke - */ -class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements PruneableInterface -{ - use FilesystemTrait { - prune as private doPrune; - doClear as private doClearCache; - doSave as private doSaveCache; - } - - /** - * Folder used for tag symlinks. - */ - private const TAG_FOLDER = 'tags'; - - public function __construct(string $namespace = '', int $defaultLifetime = 0, ?string $directory = null, ?MarshallerInterface $marshaller = null) - { - $this->marshaller = new TagAwareMarshaller($marshaller); - parent::__construct('', $defaultLifetime); - $this->init($namespace, $directory); - } - - public function prune(): bool - { - $ok = $this->doPrune(); - - set_error_handler(static function () {}); - $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - - try { - foreach ($this->scanHashDir($this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR) as $dir) { - $dir .= \DIRECTORY_SEPARATOR; - $keepDir = false; - for ($i = 0; $i < 38; ++$i) { - if (!is_dir($dir.$chars[$i])) { - continue; - } - for ($j = 0; $j < 38; ++$j) { - if (!is_dir($d = $dir.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j])) { - continue; - } - foreach (scandir($d, \SCANDIR_SORT_NONE) ?: [] as $link) { - if ('.' === $link || '..' === $link) { - continue; - } - if ('_' !== $dir[-2] && realpath($d.\DIRECTORY_SEPARATOR.$link)) { - $keepDir = true; - } else { - unlink($d.\DIRECTORY_SEPARATOR.$link); - } - } - $keepDir ?: rmdir($d); - } - $keepDir ?: rmdir($dir.$chars[$i]); - } - $keepDir ?: rmdir($dir); - } - } finally { - restore_error_handler(); - } - - return $ok; - } - - protected function doClear(string $namespace): bool - { - $ok = $this->doClearCache($namespace); - - if ('' !== $namespace) { - return $ok; - } - - set_error_handler(static function () {}); - $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - - $this->tmpSuffix ??= str_replace('/', '-', base64_encode(random_bytes(6))); - - try { - foreach ($this->scanHashDir($this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR) as $dir) { - if (rename($dir, $renamed = substr_replace($dir, $this->tmpSuffix.'_', -9))) { - $dir = $renamed.\DIRECTORY_SEPARATOR; - } else { - $dir .= \DIRECTORY_SEPARATOR; - $renamed = null; - } - - for ($i = 0; $i < 38; ++$i) { - if (!is_dir($dir.$chars[$i])) { - continue; - } - for ($j = 0; $j < 38; ++$j) { - if (!is_dir($d = $dir.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j])) { - continue; - } - foreach (scandir($d, \SCANDIR_SORT_NONE) ?: [] as $link) { - if ('.' !== $link && '..' !== $link && (null !== $renamed || !realpath($d.\DIRECTORY_SEPARATOR.$link))) { - unlink($d.\DIRECTORY_SEPARATOR.$link); - } - } - null === $renamed ?: rmdir($d); - } - null === $renamed ?: rmdir($dir.$chars[$i]); - } - null === $renamed ?: rmdir($renamed); - } - } finally { - restore_error_handler(); - } - - return $ok; - } - - protected function doSave(array $values, int $lifetime, array $addTagData = [], array $removeTagData = []): array - { - $failed = $this->doSaveCache($values, $lifetime); - - // 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); - - if (!@symlink($file, $tagLink = $this->getFile($id, true, $tagFolder)) && !is_link($tagLink)) { - @unlink($file); - $failed[] = $id; - } - } - } - - // Unlink removed Tags - foreach ($removeTagData as $tagId => $ids) { - $tagFolder = $this->getTagFolder($tagId); - foreach ($ids as $id) { - if ($failed && \in_array($id, $failed, true)) { - continue; - } - - @unlink($this->getFile($id, false, $tagFolder)); - } - } - - return $failed; - } - - protected function doDeleteYieldTags(array $ids): iterable - { - foreach ($ids as $id) { - $file = $this->getFile($id); - if (!is_file($file) || !$h = @fopen($file, 'r')) { - continue; - } - - if (!@unlink($file)) { - fclose($h); - continue; - } - - $meta = explode("\n", fread($h, 4096), 3)[2] ?? ''; - - // detect the compact format used in marshall() using magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F - if (13 < \strlen($meta) && "\x9D" === $meta[0] && "\0" === $meta[5] && "\x5F" === $meta[9]) { - $meta[9] = "\0"; - $tagLen = unpack('Nlen', $meta, 9)['len']; - $meta = substr($meta, 13, $tagLen); - - if (0 < $tagLen -= \strlen($meta)) { - $meta .= fread($h, $tagLen); - } - - try { - yield $id => '' === $meta ? [] : $this->marshaller->unmarshall($meta); - } catch (\Exception) { - yield $id => []; - } - } - - fclose($h); - } - } - - protected function doDeleteTagRelations(array $tagData): bool - { - foreach ($tagData as $tagId => $idList) { - $tagFolder = $this->getTagFolder($tagId); - foreach ($idList as $id) { - @unlink($this->getFile($id, false, $tagFolder)); - } - } - - return true; - } - - protected function doInvalidate(array $tagIds): bool - { - foreach ($tagIds as $tagId) { - if (!is_dir($tagFolder = $this->getTagFolder($tagId))) { - continue; - } - - $this->tmpSuffix ??= str_replace('/', '-', base64_encode(random_bytes(6))); - - set_error_handler(static function () {}); - - try { - if (rename($tagFolder, $renamed = substr_replace($tagFolder, $this->tmpSuffix.'_', -10))) { - $tagFolder = $renamed.\DIRECTORY_SEPARATOR; - } else { - $renamed = null; - } - - foreach ($this->scanHashDir($tagFolder) as $itemLink) { - unlink(realpath($itemLink) ?: $itemLink); - unlink($itemLink); - } - - if (null === $renamed) { - continue; - } - - $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - - for ($i = 0; $i < 38; ++$i) { - for ($j = 0; $j < 38; ++$j) { - rmdir($tagFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]); - } - rmdir($tagFolder.$chars[$i]); - } - rmdir($renamed); - } finally { - restore_error_handler(); - } - } - - return true; - } - - 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/MemcachedAdapter.php b/vendor/symfony/cache/Adapter/MemcachedAdapter.php deleted file mode 100644 index 033d987..0000000 --- a/vendor/symfony/cache/Adapter/MemcachedAdapter.php +++ /dev/null @@ -1,329 +0,0 @@ - - * - * 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\CacheException; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; - -/** - * @author Rob Frawley 2nd - * @author Nicolas Grekas - */ -class MemcachedAdapter extends AbstractAdapter -{ - /** - * We are replacing characters that are illegal in Memcached keys with reserved characters from - * {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached. - * Note: don’t use {@see AbstractAdapter::NS_SEPARATOR}. - */ - private const RESERVED_MEMCACHED = " \n\r\t\v\f\0"; - private const RESERVED_PSR6 = '@()\{}/'; - private const MAX_KEY_LENGTH = 250; - - private MarshallerInterface $marshaller; - private \Memcached $client; - private \Memcached $lazyClient; - - /** - * Using a MemcachedAdapter with a TagAwareAdapter for storing tags is discouraged. - * Using a RedisAdapter is recommended instead. If you cannot do otherwise, be aware that: - * - the Memcached::OPT_BINARY_PROTOCOL must be enabled - * (that's the default when using MemcachedAdapter::createConnection()); - * - tags eviction by Memcached's LRU algorithm will break by-tags invalidation; - * your Memcached memory should be large enough to never trigger LRU. - * - * Using a MemcachedAdapter as a pure items store is fine. - */ - public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null) - { - if (!static::isSupported()) { - throw new CacheException('Memcached > 3.1.5 is required.'); - } - $this->maxIdLength = self::MAX_KEY_LENGTH; - - if ('Memcached' === $client::class) { - $opt = $client->getOption(\Memcached::OPT_SERIALIZER); - if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { - throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - } - $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); - $this->client = $client; - } else { - $this->lazyClient = $client; - } - - parent::__construct($namespace, $defaultLifetime); - $this->enableVersioning(); - $this->marshaller = $marshaller ?? new DefaultMarshaller(); - } - - public static function isSupported(): bool - { - return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '3.1.6', '>='); - } - - /** - * Creates a Memcached instance. - * - * By default, the binary protocol, no block, and libketama compatible options are enabled. - * - * Examples for servers: - * - 'memcached://user:pass@localhost?weight=33' - * - [['localhost', 11211, 33]] - * - * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs - * - * @throws \ErrorException When invalid options or servers are provided - */ - public static function createConnection(#[\SensitiveParameter] array|string $servers, array $options = []): \Memcached - { - if (\is_string($servers)) { - $servers = [$servers]; - } - if (!static::isSupported()) { - throw new CacheException('Memcached > 3.1.5 is required.'); - } - set_error_handler(static fn ($type, $msg, $file, $line) => throw new \ErrorException($msg, 0, $type, $file, $line)); - try { - $client = new \Memcached($options['persistent_id'] ?? null); - $username = $options['username'] ?? null; - $password = $options['password'] ?? null; - - // parse any DSN in $servers - foreach ($servers as $i => $dsn) { - if (\is_array($dsn)) { - continue; - } - if (!str_starts_with($dsn, 'memcached:')) { - throw new InvalidArgumentException('Invalid Memcached DSN: it does not start with "memcached:".'); - } - $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { - if (!empty($m[2])) { - [$username, $password] = explode(':', $m[2], 2) + [1 => null]; - $username = rawurldecode($username); - $password = null !== $password ? rawurldecode($password) : null; - } - - return 'file:'.($m[1] ?? ''); - }, $dsn); - if (false === $params = parse_url($params)) { - throw new InvalidArgumentException('Invalid Memcached DSN.'); - } - $query = $hosts = []; - if (isset($params['query'])) { - parse_str($params['query'], $query); - - if (isset($query['host'])) { - if (!\is_array($hosts = $query['host'])) { - throw new InvalidArgumentException('Invalid Memcached DSN: query parameter "host" must be an array.'); - } - foreach ($hosts as $host => $weight) { - if (false === $port = strrpos($host, ':')) { - $hosts[$host] = [$host, 11211, (int) $weight]; - } else { - $hosts[$host] = [substr($host, 0, $port), (int) substr($host, 1 + $port), (int) $weight]; - } - } - $hosts = array_values($hosts); - unset($query['host']); - } - if ($hosts && !isset($params['host']) && !isset($params['path'])) { - unset($servers[$i]); - $servers = array_merge($servers, $hosts); - continue; - } - } - if (!isset($params['host']) && !isset($params['path'])) { - throw new InvalidArgumentException('Invalid Memcached DSN: missing host or path.'); - } - if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { - $params['weight'] = $m[1]; - $params['path'] = substr($params['path'], 0, -\strlen($m[0])); - } - $params += [ - 'host' => $params['host'] ?? $params['path'], - 'port' => isset($params['host']) ? 11211 : null, - 'weight' => 0, - ]; - if ($query) { - $params += $query; - $options = $query + $options; - } - - $servers[$i] = [$params['host'], $params['port'], $params['weight']]; - - if ($hosts) { - $servers = array_merge($servers, $hosts); - } - } - - // set client's options - unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']); - $options = array_change_key_case($options, \CASE_UPPER); - $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - $client->setOption(\Memcached::OPT_NO_BLOCK, true); - $client->setOption(\Memcached::OPT_TCP_NODELAY, true); - if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { - $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true); - } - foreach ($options as $name => $value) { - if (\is_int($name)) { - continue; - } - if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) { - $value = \constant('Memcached::'.$name.'_'.strtoupper($value)); - } - unset($options[$name]); - - if (\defined('Memcached::OPT_'.$name)) { - $options[\constant('Memcached::OPT_'.$name)] = $value; - } - } - $client->setOptions($options + [\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP]); - - // set client's servers, taking care of persistent connections - if (!$client->isPristine()) { - $oldServers = []; - foreach ($client->getServerList() as $server) { - $oldServers[] = [$server['host'], $server['port']]; - } - - $newServers = []; - foreach ($servers as $server) { - if (1 < \count($server)) { - $server = array_values($server); - unset($server[2]); - $server[1] = (int) $server[1]; - } - $newServers[] = $server; - } - - if ($oldServers !== $newServers) { - $client->resetServerList(); - $client->addServers($servers); - } - } else { - $client->addServers($servers); - } - - if (null !== $username || null !== $password) { - if (!method_exists($client, 'setSaslAuthData')) { - trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.'); - } - $client->setSaslAuthData($username, $password); - } - - return $client; - } finally { - restore_error_handler(); - } - } - - protected function doSave(array $values, int $lifetime): array|bool - { - if (!$values = $this->marshaller->marshall($values, $failed)) { - return $failed; - } - - if ($lifetime && $lifetime > 30 * 86400) { - $lifetime += time(); - } - - $encodedValues = []; - foreach ($values as $key => $value) { - $encodedValues[self::encodeKey($key)] = $value; - } - - return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)) ? $failed : false; - } - - protected function doFetch(array $ids): iterable - { - try { - $encodedIds = array_map([__CLASS__, 'encodeKey'], $ids); - - $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds)); - - $result = []; - foreach ($encodedResult as $key => $value) { - $result[self::decodeKey($key)] = $this->marshaller->unmarshall($value); - } - - return $result; - } catch (\Error $e) { - throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); - } - } - - protected function doHave(string $id): bool - { - return false !== $this->getClient()->get(self::encodeKey($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); - } - - protected function doDelete(array $ids): bool - { - $ok = true; - $encodedIds = array_map([__CLASS__, 'encodeKey'], $ids); - foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) { - if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { - $ok = false; - } - } - - return $ok; - } - - protected function doClear(string $namespace): bool - { - return '' === $namespace && $this->getClient()->flush(); - } - - private function checkResultCode(mixed $result): mixed - { - $code = $this->client->getResultCode(); - - if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) { - return $result; - } - - throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage())); - } - - private function getClient(): \Memcached - { - if (isset($this->client)) { - return $this->client; - } - - $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER); - if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { - throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - } - if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) { - throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix)); - } - - return $this->client = $this->lazyClient; - } - - private static function encodeKey(string $key): string - { - return strtr($key, self::RESERVED_MEMCACHED, self::RESERVED_PSR6); - } - - private static function decodeKey(string $key): string - { - return strtr($key, self::RESERVED_PSR6, self::RESERVED_MEMCACHED); - } -} diff --git a/vendor/symfony/cache/Adapter/NullAdapter.php b/vendor/symfony/cache/Adapter/NullAdapter.php deleted file mode 100644 index d5d2ef6..0000000 --- a/vendor/symfony/cache/Adapter/NullAdapter.php +++ /dev/null @@ -1,105 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Symfony\Component\Cache\CacheItem; -use Symfony\Contracts\Cache\CacheInterface; - -/** - * @author Titouan Galopin - */ -class NullAdapter implements AdapterInterface, CacheInterface -{ - private static \Closure $createCacheItem; - - public function __construct() - { - self::$createCacheItem ??= \Closure::bind( - static function ($key) { - $item = new CacheItem(); - $item->key = $key; - $item->isHit = false; - - return $item; - }, - null, - CacheItem::class - ); - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - $save = true; - - return $callback((self::$createCacheItem)($key), $save); - } - - public function getItem(mixed $key): CacheItem - { - return (self::$createCacheItem)($key); - } - - public function getItems(array $keys = []): iterable - { - return $this->generateItems($keys); - } - - public function hasItem(mixed $key): bool - { - return false; - } - - public function clear(string $prefix = ''): bool - { - return true; - } - - public function deleteItem(mixed $key): bool - { - return true; - } - - public function deleteItems(array $keys): bool - { - return true; - } - - public function save(CacheItemInterface $item): bool - { - return true; - } - - public function saveDeferred(CacheItemInterface $item): bool - { - return true; - } - - public function commit(): bool - { - return true; - } - - public function delete(string $key): bool - { - return $this->deleteItem($key); - } - - private function generateItems(array $keys): \Generator - { - $f = self::$createCacheItem; - - foreach ($keys as $key) { - yield $key => $f($key); - } - } -} diff --git a/vendor/symfony/cache/Adapter/ParameterNormalizer.php b/vendor/symfony/cache/Adapter/ParameterNormalizer.php deleted file mode 100644 index a689640..0000000 --- a/vendor/symfony/cache/Adapter/ParameterNormalizer.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Adapter; - -/** - * @author Lars Strojny - */ -final class ParameterNormalizer -{ - public static function normalizeDuration(string $duration): int - { - if (is_numeric($duration)) { - return $duration; - } - - if (false !== $time = strtotime($duration, 0)) { - return $time; - } - - try { - return \DateTimeImmutable::createFromFormat('U', 0)->add(new \DateInterval($duration))->getTimestamp(); - } catch (\Exception $e) { - throw new \InvalidArgumentException(sprintf('Cannot parse date interval "%s".', $duration), 0, $e); - } - } -} diff --git a/vendor/symfony/cache/Adapter/PdoAdapter.php b/vendor/symfony/cache/Adapter/PdoAdapter.php deleted file mode 100644 index b18428d..0000000 --- a/vendor/symfony/cache/Adapter/PdoAdapter.php +++ /dev/null @@ -1,398 +0,0 @@ - - * - * 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\InvalidArgumentException; -use Symfony\Component\Cache\Marshaller\DefaultMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\PruneableInterface; - -class PdoAdapter extends AbstractAdapter implements PruneableInterface -{ - private const MAX_KEY_LENGTH = 255; - - private MarshallerInterface $marshaller; - private \PDO $conn; - private string $dsn; - private string $driver; - private string $serverVersion; - private string $table = 'cache_items'; - private string $idCol = 'item_id'; - private string $dataCol = 'item_data'; - private string $lifetimeCol = 'item_lifetime'; - private string $timeCol = 'item_time'; - private ?string $username = null; - private ?string $password = null; - private array $connectionOptions = []; - private string $namespace; - - /** - * You can either pass an existing database connection as PDO instance or - * a DSN string that will be used to lazy-connect to the database when the - * cache is actually used. - * - * List of available options: - * * db_table: The name of the table [default: cache_items] - * * db_id_col: The column where to store the cache id [default: item_id] - * * db_data_col: The column where to store the cache data [default: item_data] - * * db_lifetime_col: The column where to store the lifetime [default: item_lifetime] - * * db_time_col: The column where to store the timestamp [default: item_time] - * * db_username: The username when lazy-connect [default: ''] - * * db_password: The password when lazy-connect [default: ''] - * * db_connection_options: An array of driver-specific connection options [default: []] - * - * @throws InvalidArgumentException When first argument is not PDO nor Connection nor string - * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION - * @throws InvalidArgumentException When namespace contains invalid characters - */ - public function __construct(#[\SensitiveParameter] \PDO|string $connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null) - { - if (\is_string($connOrDsn) && str_contains($connOrDsn, '://')) { - throw new InvalidArgumentException(sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class)); - } - - if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) { - throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); - } - - if ($connOrDsn instanceof \PDO) { - if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { - throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__)); - } - - $this->conn = $connOrDsn; - } else { - $this->dsn = $connOrDsn; - } - - $this->maxIdLength = self::MAX_KEY_LENGTH; - $this->table = $options['db_table'] ?? $this->table; - $this->idCol = $options['db_id_col'] ?? $this->idCol; - $this->dataCol = $options['db_data_col'] ?? $this->dataCol; - $this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol; - $this->timeCol = $options['db_time_col'] ?? $this->timeCol; - $this->username = $options['db_username'] ?? $this->username; - $this->password = $options['db_password'] ?? $this->password; - $this->connectionOptions = $options['db_connection_options'] ?? $this->connectionOptions; - $this->namespace = $namespace; - $this->marshaller = $marshaller ?? new DefaultMarshaller(); - - parent::__construct($namespace, $defaultLifetime); - } - - public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): \PDO|string - { - if ($options['lazy'] ?? true) { - return $dsn; - } - - $pdo = new \PDO($dsn); - $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - return $pdo; - } - - /** - * Creates the table to store cache items which can be called once for setup. - * - * Cache ID are saved in a column of maximum length 255. Cache data is - * saved in a BLOB. - * - * @throws \PDOException When the table already exists - * @throws \DomainException When an unsupported PDO driver is used - */ - public function createTable(): void - { - $sql = match ($driver = $this->getDriver()) { - // We use varbinary for the ID column because it prevents unwanted conversions: - // - character set conversions between server and client - // - trailing space removal - // - case-insensitivity - // - language processing like é == e - 'mysql' => "CREATE TABLE $this->table ($this->idCol VARBINARY(255) NOT NULL PRIMARY KEY, $this->dataCol MEDIUMBLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB", - 'sqlite' => "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", - 'pgsql' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", - 'oci' => "CREATE TABLE $this->table ($this->idCol VARCHAR2(255) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", - 'sqlsrv' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)", - default => throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $driver)), - }; - - $this->getConnection()->exec($sql); - } - - public function prune(): bool - { - $deleteSql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= :time"; - - if ('' !== $this->namespace) { - $deleteSql .= " AND $this->idCol LIKE :namespace"; - } - - $connection = $this->getConnection(); - - try { - $delete = $connection->prepare($deleteSql); - } catch (\PDOException) { - return true; - } - $delete->bindValue(':time', time(), \PDO::PARAM_INT); - - if ('' !== $this->namespace) { - $delete->bindValue(':namespace', sprintf('%s%%', $this->namespace), \PDO::PARAM_STR); - } - try { - return $delete->execute(); - } catch (\PDOException) { - return true; - } - } - - protected function doFetch(array $ids): iterable - { - $connection = $this->getConnection(); - - $now = time(); - $expired = []; - - $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); - $sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN ($sql)"; - $stmt = $connection->prepare($sql); - $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); - foreach ($ids as $id) { - $stmt->bindValue(++$i, $id); - } - $result = $stmt->execute(); - - if (\is_object($result)) { - $result = $result->iterateNumeric(); - } else { - $stmt->setFetchMode(\PDO::FETCH_NUM); - $result = $stmt; - } - - foreach ($result as $row) { - if (null === $row[1]) { - $expired[] = $row[0]; - } else { - yield $row[0] => $this->marshaller->unmarshall(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]); - } - } - - if ($expired) { - $sql = str_pad('', (\count($expired) << 1) - 1, '?,'); - $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ? AND $this->idCol IN ($sql)"; - $stmt = $connection->prepare($sql); - $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); - foreach ($expired as $id) { - $stmt->bindValue(++$i, $id); - } - $stmt->execute(); - } - } - - protected function doHave(string $id): bool - { - $connection = $this->getConnection(); - - $sql = "SELECT 1 FROM $this->table WHERE $this->idCol = :id AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > :time)"; - $stmt = $connection->prepare($sql); - - $stmt->bindValue(':id', $id); - $stmt->bindValue(':time', time(), \PDO::PARAM_INT); - $stmt->execute(); - - return (bool) $stmt->fetchColumn(); - } - - protected function doClear(string $namespace): bool - { - $conn = $this->getConnection(); - - if ('' === $namespace) { - if ('sqlite' === $this->getDriver()) { - $sql = "DELETE FROM $this->table"; - } else { - $sql = "TRUNCATE TABLE $this->table"; - } - } else { - $sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'"; - } - - try { - $conn->exec($sql); - } catch (\PDOException) { - } - - return true; - } - - protected function doDelete(array $ids): bool - { - $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); - $sql = "DELETE FROM $this->table WHERE $this->idCol IN ($sql)"; - try { - $stmt = $this->getConnection()->prepare($sql); - $stmt->execute(array_values($ids)); - } catch (\PDOException) { - } - - return true; - } - - protected function doSave(array $values, int $lifetime): array|bool - { - if (!$values = $this->marshaller->marshall($values, $failed)) { - return $failed; - } - - $conn = $this->getConnection(); - - $driver = $this->getDriver(); - $insertSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)"; - - switch (true) { - case 'mysql' === $driver: - $sql = $insertSql." ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)"; - break; - case 'oci' === $driver: - // DUAL is Oracle specific dummy table - $sql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?"; - break; - case 'sqlsrv' === $driver && version_compare($this->getServerVersion(), '10', '>='): - // MERGE is only available since SQL Server 2008 and must be terminated by semicolon - // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx - $sql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;"; - break; - case 'sqlite' === $driver: - $sql = 'INSERT OR REPLACE'.substr($insertSql, 6); - break; - case 'pgsql' === $driver && version_compare($this->getServerVersion(), '9.5', '>='): - $sql = $insertSql." ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)"; - break; - default: - $driver = null; - $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id"; - break; - } - - $now = time(); - $lifetime = $lifetime ?: null; - try { - $stmt = $conn->prepare($sql); - } catch (\PDOException $e) { - if ($this->isTableMissing($e) && (!$conn->inTransaction() || \in_array($driver, ['pgsql', 'sqlite', 'sqlsrv'], true))) { - $this->createTable(); - } - $stmt = $conn->prepare($sql); - } - - // $id and $data are defined later in the loop. Binding is done by reference, values are read on execution. - if ('sqlsrv' === $driver || 'oci' === $driver) { - $stmt->bindParam(1, $id); - $stmt->bindParam(2, $id); - $stmt->bindParam(3, $data, \PDO::PARAM_LOB); - $stmt->bindValue(4, $lifetime, \PDO::PARAM_INT); - $stmt->bindValue(5, $now, \PDO::PARAM_INT); - $stmt->bindParam(6, $data, \PDO::PARAM_LOB); - $stmt->bindValue(7, $lifetime, \PDO::PARAM_INT); - $stmt->bindValue(8, $now, \PDO::PARAM_INT); - } else { - $stmt->bindParam(':id', $id); - $stmt->bindParam(':data', $data, \PDO::PARAM_LOB); - $stmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT); - $stmt->bindValue(':time', $now, \PDO::PARAM_INT); - } - if (null === $driver) { - $insertStmt = $conn->prepare($insertSql); - - $insertStmt->bindParam(':id', $id); - $insertStmt->bindParam(':data', $data, \PDO::PARAM_LOB); - $insertStmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT); - $insertStmt->bindValue(':time', $now, \PDO::PARAM_INT); - } - - foreach ($values as $id => $data) { - try { - $stmt->execute(); - } catch (\PDOException $e) { - if ($this->isTableMissing($e) && (!$conn->inTransaction() || \in_array($driver, ['pgsql', 'sqlite', 'sqlsrv'], true))) { - $this->createTable(); - } - $stmt->execute(); - } - if (null === $driver && !$stmt->rowCount()) { - try { - $insertStmt->execute(); - } catch (\PDOException) { - // A concurrent write won, let it be - } - } - } - - return $failed; - } - - /** - * @internal - */ - protected function getId(mixed $key): string - { - if ('pgsql' !== $this->getDriver()) { - return parent::getId($key); - } - - if (str_contains($key, "\0") || str_contains($key, '%') || !preg_match('//u', $key)) { - $key = rawurlencode($key); - } - - return parent::getId($key); - } - - private function getConnection(): \PDO - { - if (!isset($this->conn)) { - $this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions); - $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - } - - return $this->conn; - } - - private function getDriver(): string - { - return $this->driver ??= $this->getConnection()->getAttribute(\PDO::ATTR_DRIVER_NAME); - } - - private function getServerVersion(): string - { - return $this->serverVersion ??= $this->getConnection()->getAttribute(\PDO::ATTR_SERVER_VERSION); - } - - private function isTableMissing(\PDOException $exception): bool - { - $driver = $this->getDriver(); - [$sqlState, $code] = $exception->errorInfo ?? [null, $exception->getCode()]; - - return match ($driver) { - 'pgsql' => '42P01' === $sqlState, - 'sqlite' => str_contains($exception->getMessage(), 'no such table:'), - 'oci' => 942 === $code, - 'sqlsrv' => 208 === $code, - 'mysql' => 1146 === $code, - default => false, - }; - } -} diff --git a/vendor/symfony/cache/Adapter/PhpArrayAdapter.php b/vendor/symfony/cache/Adapter/PhpArrayAdapter.php deleted file mode 100644 index f92a238..0000000 --- a/vendor/symfony/cache/Adapter/PhpArrayAdapter.php +++ /dev/null @@ -1,389 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; -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\ContractsTrait; -use Symfony\Component\Cache\Traits\ProxyTrait; -use Symfony\Component\VarExporter\VarExporter; -use Symfony\Contracts\Cache\CacheInterface; - -/** - * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. - * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter. - * - * @author Titouan Galopin - * @author Nicolas Grekas - */ -class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface -{ - use ContractsTrait; - use ProxyTrait; - - private array $keys; - private array $values; - - private static \Closure $createCacheItem; - private static array $valuesCache = []; - - /** - * @param string $file The PHP file were values are cached - * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit - */ - public function __construct( - private string $file, - AdapterInterface $fallbackPool, - ) { - $this->pool = $fallbackPool; - self::$createCacheItem ??= \Closure::bind( - static function ($key, $value, $isHit) { - $item = new CacheItem(); - $item->key = $key; - $item->value = $value; - $item->isHit = $isHit; - - return $item; - }, - null, - CacheItem::class - ); - } - - /** - * This adapter takes advantage of how PHP stores arrays in its latest versions. - * - * @param string $file The PHP file were values are cached - * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit - */ - public static function create(string $file, CacheItemPoolInterface $fallbackPool): CacheItemPoolInterface - { - if (!$fallbackPool instanceof AdapterInterface) { - $fallbackPool = new ProxyAdapter($fallbackPool); - } - - return new static($file, $fallbackPool); - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - if (!isset($this->values)) { - $this->initialize(); - } - if (!isset($this->keys[$key])) { - get_from_pool: - if ($this->pool instanceof CacheInterface) { - return $this->pool->get($key, $callback, $beta, $metadata); - } - - return $this->doGet($this->pool, $key, $callback, $beta, $metadata); - } - $value = $this->values[$this->keys[$key]]; - - if ('N;' === $value) { - return null; - } - try { - if ($value instanceof \Closure) { - return $value(); - } - } catch (\Throwable) { - unset($this->keys[$key]); - goto get_from_pool; - } - - return $value; - } - - public function getItem(mixed $key): CacheItem - { - if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); - } - if (!isset($this->values)) { - $this->initialize(); - } - if (!isset($this->keys[$key])) { - return $this->pool->getItem($key); - } - - $value = $this->values[$this->keys[$key]]; - $isHit = true; - - if ('N;' === $value) { - $value = null; - } elseif ($value instanceof \Closure) { - try { - $value = $value(); - } catch (\Throwable) { - $value = null; - $isHit = false; - } - } - - return (self::$createCacheItem)($key, $value, $isHit); - } - - public function getItems(array $keys = []): iterable - { - foreach ($keys as $key) { - if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); - } - } - if (!isset($this->values)) { - $this->initialize(); - } - - return $this->generateItems($keys); - } - - public function hasItem(mixed $key): bool - { - if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); - } - if (!isset($this->values)) { - $this->initialize(); - } - - return isset($this->keys[$key]) || $this->pool->hasItem($key); - } - - public function deleteItem(mixed $key): bool - { - if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); - } - if (!isset($this->values)) { - $this->initialize(); - } - - return !isset($this->keys[$key]) && $this->pool->deleteItem($key); - } - - public function deleteItems(array $keys): bool - { - $deleted = true; - $fallbackKeys = []; - - foreach ($keys as $key) { - if (!\is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key))); - } - - if (isset($this->keys[$key])) { - $deleted = false; - } else { - $fallbackKeys[] = $key; - } - } - if (!isset($this->values)) { - $this->initialize(); - } - - if ($fallbackKeys) { - $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted; - } - - return $deleted; - } - - public function save(CacheItemInterface $item): bool - { - if (!isset($this->values)) { - $this->initialize(); - } - - return !isset($this->keys[$item->getKey()]) && $this->pool->save($item); - } - - public function saveDeferred(CacheItemInterface $item): bool - { - if (!isset($this->values)) { - $this->initialize(); - } - - return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item); - } - - public function commit(): bool - { - return $this->pool->commit(); - } - - public function clear(string $prefix = ''): bool - { - $this->keys = $this->values = []; - - $cleared = @unlink($this->file) || !file_exists($this->file); - unset(self::$valuesCache[$this->file]); - - if ($this->pool instanceof AdapterInterface) { - return $this->pool->clear($prefix) && $cleared; - } - - return $this->pool->clear() && $cleared; - } - - /** - * Store an array of cached values. - * - * @param array $values The cached values - * - * @return string[] A list of classes to preload on PHP 7.4+ - */ - public function warmUp(array $values): array - { - if (file_exists($this->file)) { - if (!is_file($this->file)) { - throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file)); - } - - if (!is_writable($this->file)) { - throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file)); - } - } else { - $directory = \dirname($this->file); - - if (!is_dir($directory) && !@mkdir($directory, 0777, true)) { - throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); - } - - if (!is_writable($directory)) { - throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory)); - } - } - - $preload = []; - $dumpedValues = ''; - $dumpedMap = []; - $dump = <<<'EOF' - $value) { - CacheItem::validateKey(\is_int($key) ? (string) $key : $key); - $isStaticValue = true; - - if (null === $value) { - $value = "'N;'"; - } elseif (\is_object($value) || \is_array($value)) { - try { - $value = VarExporter::export($value, $isStaticValue, $preload); - } catch (\Exception $e) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); - } - } elseif (\is_string($value)) { - // Wrap "N;" in a closure to not confuse it with an encoded `null` - if ('N;' === $value) { - $isStaticValue = false; - } - $value = var_export($value, true); - } elseif (!\is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); - } else { - $value = var_export($value, true); - } - - if (!$isStaticValue) { - $value = str_replace("\n", "\n ", $value); - $value = "static function () {\n return {$value};\n}"; - } - $hash = hash('xxh128', $value); - - if (null === $id = $dumpedMap[$hash] ?? null) { - $id = $dumpedMap[$hash] = \count($dumpedMap); - $dumpedValues .= "{$id} => {$value},\n"; - } - - $dump .= var_export($key, true)." => {$id},\n"; - } - - $dump .= "\n], [\n\n{$dumpedValues}\n]];\n"; - - $tmpFile = uniqid($this->file, true); - - file_put_contents($tmpFile, $dump); - @chmod($tmpFile, 0666 & ~umask()); - unset($serialized, $value, $dump); - - @rename($tmpFile, $this->file); - unset(self::$valuesCache[$this->file]); - - $this->initialize(); - - return $preload; - } - - /** - * Load the cache file. - */ - private function initialize(): void - { - if (isset(self::$valuesCache[$this->file])) { - $values = self::$valuesCache[$this->file]; - } elseif (!is_file($this->file)) { - $this->keys = $this->values = []; - - return; - } else { - $values = self::$valuesCache[$this->file] = (include $this->file) ?: [[], []]; - } - - if (2 !== \count($values) || !isset($values[0], $values[1])) { - $this->keys = $this->values = []; - } else { - [$this->keys, $this->values] = $values; - } - } - - private function generateItems(array $keys): \Generator - { - $f = self::$createCacheItem; - $fallbackKeys = []; - - foreach ($keys as $key) { - if (isset($this->keys[$key])) { - $value = $this->values[$this->keys[$key]]; - - if ('N;' === $value) { - yield $key => $f($key, null, true); - } elseif ($value instanceof \Closure) { - try { - yield $key => $f($key, $value(), true); - } catch (\Throwable) { - yield $key => $f($key, null, false); - } - } else { - yield $key => $f($key, $value, true); - } - } else { - $fallbackKeys[] = $key; - } - } - - if ($fallbackKeys) { - yield from $this->pool->getItems($fallbackKeys); - } - } -} diff --git a/vendor/symfony/cache/Adapter/PhpFilesAdapter.php b/vendor/symfony/cache/Adapter/PhpFilesAdapter.php deleted file mode 100644 index 917ff16..0000000 --- a/vendor/symfony/cache/Adapter/PhpFilesAdapter.php +++ /dev/null @@ -1,314 +0,0 @@ - - * - * 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\CacheException; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Traits\FilesystemCommonTrait; -use Symfony\Component\VarExporter\VarExporter; - -/** - * @author Piotr Stankowski - * @author Nicolas Grekas - * @author Rob Frawley 2nd - */ -class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface -{ - use FilesystemCommonTrait { - doClear as private doCommonClear; - doDelete as private doCommonDelete; - } - - private \Closure $includeHandler; - private array $values = []; - private array $files = []; - - private static int $startTime; - private static array $valuesCache = []; - - /** - * @param bool $appendOnly Set to `true` to gain extra performance when the items stored in this pool never expire. - * Doing so is encouraged because it fits perfectly OPcache's memory model. - * - * @throws CacheException if OPcache is not enabled - */ - public function __construct( - string $namespace = '', - int $defaultLifetime = 0, - ?string $directory = null, - private bool $appendOnly = false, - ) { - self::$startTime ??= $_SERVER['REQUEST_TIME'] ?? time(); - parent::__construct('', $defaultLifetime); - $this->init($namespace, $directory); - $this->includeHandler = static function ($type, $msg, $file, $line) { - throw new \ErrorException($msg, 0, $type, $file, $line); - }; - } - - public static function isSupported(): bool - { - self::$startTime ??= $_SERVER['REQUEST_TIME'] ?? time(); - - return \function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) || filter_var(\ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOL)); - } - - public function prune(): bool - { - $time = time(); - $pruned = true; - $getExpiry = true; - - set_error_handler($this->includeHandler); - try { - foreach ($this->scanHashDir($this->directory) as $file) { - try { - if (\is_array($expiresAt = include $file)) { - $expiresAt = $expiresAt[0]; - } - } catch (\ErrorException $e) { - $expiresAt = $time; - } - - if ($time >= $expiresAt) { - $pruned = ($this->doUnlink($file) || !file_exists($file)) && $pruned; - } - } - } finally { - restore_error_handler(); - } - - return $pruned; - } - - protected function doFetch(array $ids): iterable - { - if ($this->appendOnly) { - $now = 0; - $missingIds = []; - } else { - $now = time(); - $missingIds = $ids; - $ids = []; - } - $values = []; - - begin: - $getExpiry = false; - - foreach ($ids as $id) { - if (null === $value = $this->values[$id] ?? null) { - $missingIds[] = $id; - } elseif ('N;' === $value) { - $values[$id] = null; - } elseif (!\is_object($value)) { - $values[$id] = $value; - } elseif (!$value instanceof LazyValue) { - $values[$id] = $value(); - } elseif (false === $values[$id] = include $value->file) { - unset($values[$id], $this->values[$id]); - $missingIds[] = $id; - } - if (!$this->appendOnly) { - unset($this->values[$id]); - } - } - - if (!$missingIds) { - return $values; - } - - set_error_handler($this->includeHandler); - try { - $getExpiry = true; - - foreach ($missingIds as $k => $id) { - try { - $file = $this->files[$id] ??= $this->getFile($id); - - if (isset(self::$valuesCache[$file])) { - [$expiresAt, $this->values[$id]] = self::$valuesCache[$file]; - } elseif (\is_array($expiresAt = include $file)) { - if ($this->appendOnly) { - self::$valuesCache[$file] = $expiresAt; - } - - [$expiresAt, $this->values[$id]] = $expiresAt; - } elseif ($now < $expiresAt) { - $this->values[$id] = new LazyValue($file); - } - - if ($now >= $expiresAt) { - unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]); - } - } catch (\ErrorException $e) { - unset($missingIds[$k]); - } - } - } finally { - restore_error_handler(); - } - - $ids = $missingIds; - $missingIds = []; - goto begin; - } - - protected function doHave(string $id): bool - { - if ($this->appendOnly && isset($this->values[$id])) { - return true; - } - - set_error_handler($this->includeHandler); - try { - $file = $this->files[$id] ??= $this->getFile($id); - $getExpiry = true; - - if (isset(self::$valuesCache[$file])) { - [$expiresAt, $value] = self::$valuesCache[$file]; - } elseif (\is_array($expiresAt = include $file)) { - if ($this->appendOnly) { - self::$valuesCache[$file] = $expiresAt; - } - - [$expiresAt, $value] = $expiresAt; - } elseif ($this->appendOnly) { - $value = new LazyValue($file); - } - } catch (\ErrorException) { - return false; - } finally { - restore_error_handler(); - } - if ($this->appendOnly) { - $now = 0; - $this->values[$id] = $value; - } else { - $now = time(); - } - - return $now < $expiresAt; - } - - protected function doSave(array $values, int $lifetime): array|bool - { - $ok = true; - $expiry = $lifetime ? time() + $lifetime : 'PHP_INT_MAX'; - $allowCompile = self::isSupported(); - - foreach ($values as $key => $value) { - unset($this->values[$key]); - $isStaticValue = true; - if (null === $value) { - $value = "'N;'"; - } elseif (\is_object($value) || \is_array($value)) { - try { - $value = VarExporter::export($value, $isStaticValue); - } catch (\Exception $e) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e); - } - } elseif (\is_string($value)) { - // Wrap "N;" in a closure to not confuse it with an encoded `null` - if ('N;' === $value) { - $isStaticValue = false; - } - $value = var_export($value, true); - } elseif (!\is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value))); - } else { - $value = var_export($value, true); - } - - $encodedKey = rawurlencode($key); - - if ($isStaticValue) { - $value = "return [{$expiry}, {$value}];"; - } elseif ($this->appendOnly) { - $value = "return [{$expiry}, static fn () => {$value}];"; - } else { - // We cannot use a closure here because of https://bugs.php.net/76982 - $value = str_replace('\Symfony\Component\VarExporter\Internal\\', '', $value); - $value = "namespace Symfony\Component\VarExporter\Internal;\n\nreturn \$getExpiry ? {$expiry} : {$value};"; - } - - $file = $this->files[$key] = $this->getFile($key, true); - // Since OPcache only compiles files older than the script execution start, set the file's mtime in the past - $ok = $this->write($file, "directory)) { - throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); - } - - return $ok; - } - - protected function doClear(string $namespace): bool - { - $this->values = []; - - return $this->doCommonClear($namespace); - } - - protected function doDelete(array $ids): bool - { - foreach ($ids as $id) { - unset($this->values[$id]); - } - - return $this->doCommonDelete($ids); - } - - protected function doUnlink(string $file): bool - { - unset(self::$valuesCache[$file]); - - if (self::isSupported()) { - @opcache_invalidate($file, true); - } - - return @unlink($file); - } - - private function getFileKey(string $file): string - { - if (!$h = @fopen($file, 'r')) { - return ''; - } - - $encodedKey = substr(fgets($h), 8); - fclose($h); - - return rawurldecode(rtrim($encodedKey)); - } -} - -/** - * @internal - */ -class LazyValue -{ - public string $file; - - public function __construct(string $file) - { - $this->file = $file; - } -} diff --git a/vendor/symfony/cache/Adapter/ProxyAdapter.php b/vendor/symfony/cache/Adapter/ProxyAdapter.php deleted file mode 100644 index c022dd5..0000000 --- a/vendor/symfony/cache/Adapter/ProxyAdapter.php +++ /dev/null @@ -1,206 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Component\Cache\Traits\ContractsTrait; -use Symfony\Component\Cache\Traits\ProxyTrait; -use Symfony\Contracts\Cache\CacheInterface; - -/** - * @author Nicolas Grekas - */ -class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface -{ - use ContractsTrait; - use ProxyTrait; - - private string $namespace = ''; - private int $namespaceLen; - private string $poolHash; - private int $defaultLifetime; - - private static \Closure $createCacheItem; - private static \Closure $setInnerItem; - - public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0) - { - $this->pool = $pool; - $this->poolHash = spl_object_hash($pool); - if ('' !== $namespace) { - \assert('' !== CacheItem::validateKey($namespace)); - $this->namespace = $namespace; - } - $this->namespaceLen = \strlen($namespace); - $this->defaultLifetime = $defaultLifetime; - self::$createCacheItem ??= \Closure::bind( - static function ($key, $innerItem, $poolHash) { - $item = new CacheItem(); - $item->key = $key; - - if (null === $innerItem) { - return $item; - } - - $item->value = $innerItem->get(); - $item->isHit = $innerItem->isHit(); - $item->innerItem = $innerItem; - $item->poolHash = $poolHash; - - if (!$item->unpack() && $innerItem instanceof CacheItem) { - $item->metadata = $innerItem->metadata; - } - $innerItem->set(null); - - return $item; - }, - null, - CacheItem::class - ); - self::$setInnerItem ??= \Closure::bind( - static function (CacheItemInterface $innerItem, CacheItem $item, $expiry = null) { - $innerItem->set($item->pack()); - $innerItem->expiresAt(($expiry ?? $item->expiry) ? \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $expiry ?? $item->expiry)) : null); - }, - null, - CacheItem::class - ); - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - if (!$this->pool instanceof CacheInterface) { - return $this->doGet($this, $key, $callback, $beta, $metadata); - } - - return $this->pool->get($this->getId($key), function ($innerItem, bool &$save) use ($key, $callback) { - $item = (self::$createCacheItem)($key, $innerItem, $this->poolHash); - $item->set($value = $callback($item, $save)); - (self::$setInnerItem)($innerItem, $item); - - return $value; - }, $beta, $metadata); - } - - public function getItem(mixed $key): CacheItem - { - $item = $this->pool->getItem($this->getId($key)); - - return (self::$createCacheItem)($key, $item, $this->poolHash); - } - - public function getItems(array $keys = []): iterable - { - if ($this->namespaceLen) { - foreach ($keys as $i => $key) { - $keys[$i] = $this->getId($key); - } - } - - return $this->generateItems($this->pool->getItems($keys)); - } - - public function hasItem(mixed $key): bool - { - return $this->pool->hasItem($this->getId($key)); - } - - public function clear(string $prefix = ''): bool - { - if ($this->pool instanceof AdapterInterface) { - return $this->pool->clear($this->namespace.$prefix); - } - - return $this->pool->clear(); - } - - public function deleteItem(mixed $key): bool - { - return $this->pool->deleteItem($this->getId($key)); - } - - public function deleteItems(array $keys): bool - { - if ($this->namespaceLen) { - foreach ($keys as $i => $key) { - $keys[$i] = $this->getId($key); - } - } - - return $this->pool->deleteItems($keys); - } - - public function save(CacheItemInterface $item): bool - { - return $this->doSave($item, __FUNCTION__); - } - - public function saveDeferred(CacheItemInterface $item): bool - { - return $this->doSave($item, __FUNCTION__); - } - - public function commit(): bool - { - return $this->pool->commit(); - } - - private function doSave(CacheItemInterface $item, string $method): bool - { - if (!$item instanceof CacheItem) { - return false; - } - $castItem = (array) $item; - - if (null === $castItem["\0*\0expiry"] && 0 < $this->defaultLifetime) { - $castItem["\0*\0expiry"] = microtime(true) + $this->defaultLifetime; - } - - if ($castItem["\0*\0poolHash"] === $this->poolHash && $castItem["\0*\0innerItem"]) { - $innerItem = $castItem["\0*\0innerItem"]; - } elseif ($this->pool instanceof AdapterInterface) { - // this is an optimization specific for AdapterInterface implementations - // so we can save a round-trip to the backend by just creating a new item - $innerItem = (self::$createCacheItem)($this->namespace.$castItem["\0*\0key"], null, $this->poolHash); - } else { - $innerItem = $this->pool->getItem($this->namespace.$castItem["\0*\0key"]); - } - - (self::$setInnerItem)($innerItem, $item, $castItem["\0*\0expiry"]); - - return $this->pool->$method($innerItem); - } - - private function generateItems(iterable $items): \Generator - { - $f = self::$createCacheItem; - - foreach ($items as $key => $item) { - if ($this->namespaceLen) { - $key = substr($key, $this->namespaceLen); - } - - yield $key => $f($key, $item, $this->poolHash); - } - } - - private function getId(mixed $key): string - { - \assert('' !== CacheItem::validateKey($key)); - - return $this->namespace.$key; - } -} diff --git a/vendor/symfony/cache/Adapter/Psr16Adapter.php b/vendor/symfony/cache/Adapter/Psr16Adapter.php deleted file mode 100644 index a72b037..0000000 --- a/vendor/symfony/cache/Adapter/Psr16Adapter.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Adapter; - -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Component\Cache\Traits\ProxyTrait; - -/** - * Turns a PSR-16 cache into a PSR-6 one. - * - * @author Nicolas Grekas - */ -class Psr16Adapter extends AbstractAdapter implements PruneableInterface, ResettableInterface -{ - use ProxyTrait; - - /** - * @internal - */ - protected const NS_SEPARATOR = '_'; - - private object $miss; - - public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0) - { - parent::__construct($namespace, $defaultLifetime); - - $this->pool = $pool; - $this->miss = new \stdClass(); - } - - protected function doFetch(array $ids): iterable - { - foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) { - if ($this->miss !== $value) { - yield $key => $value; - } - } - } - - protected function doHave(string $id): bool - { - return $this->pool->has($id); - } - - protected function doClear(string $namespace): bool - { - return $this->pool->clear(); - } - - protected function doDelete(array $ids): bool - { - return $this->pool->deleteMultiple($ids); - } - - protected function doSave(array $values, int $lifetime): array|bool - { - return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); - } -} diff --git a/vendor/symfony/cache/Adapter/RedisAdapter.php b/vendor/symfony/cache/Adapter/RedisAdapter.php deleted file mode 100644 index e33f2f6..0000000 --- a/vendor/symfony/cache/Adapter/RedisAdapter.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * 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\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\Traits\RedisTrait; - -class RedisAdapter extends AbstractAdapter -{ - use RedisTrait; - - public function __construct(\Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Relay\Relay $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null) - { - $this->init($redis, $namespace, $defaultLifetime, $marshaller); - } -} diff --git a/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php b/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php deleted file mode 100644 index f71622b..0000000 --- a/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php +++ /dev/null @@ -1,310 +0,0 @@ - - * - * 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\Connection\Aggregate\ClusterInterface; -use Predis\Connection\Aggregate\PredisCluster; -use Predis\Connection\Aggregate\ReplicationInterface; -use Predis\Response\ErrorInterface; -use Predis\Response\Status; -use Relay\Relay; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Exception\LogicException; -use Symfony\Component\Cache\Marshaller\DeflateMarshaller; -use Symfony\Component\Cache\Marshaller\MarshallerInterface; -use Symfony\Component\Cache\Marshaller\TagAwareMarshaller; -use Symfony\Component\Cache\Traits\RedisTrait; - -/** - * Stores tag id <> cache id relationship as a Redis Set. - * - * 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). - * - * Redis server 2.8+ with any `volatile-*` eviction policy, OR `noeviction` if you're sure memory will NEVER fill up - * - * Design limitations: - * - Max 4 billion cache keys per cache tag as limited by Redis Set datatype. - * E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 4 billion cache items also. - * - * @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. - * - * @author Nicolas Grekas - * @author André Rømcke - */ -class RedisTagAwareAdapter extends AbstractTagAwareAdapter -{ - use RedisTrait; - - /** - * 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; - - /** - * detected eviction policy used on Redis server. - */ - private string $redisEvictionPolicy; - - public function __construct( - \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, - private string $namespace = '', - int $defaultLifetime = 0, - ?MarshallerInterface $marshaller = null, - ) { - if ($redis instanceof \Predis\ClientInterface && $redis->getConnection() instanceof ClusterInterface && !$redis->getConnection() instanceof PredisCluster) { - throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection()))); - } - - $isRelay = $redis instanceof Relay; - if ($isRelay || \defined('Redis::OPT_COMPRESSION') && \in_array($redis::class, [\Redis::class, \RedisArray::class, \RedisCluster::class], true)) { - $compression = $redis->getOption($isRelay ? Relay::OPT_COMPRESSION : \Redis::OPT_COMPRESSION); - - foreach (\is_array($compression) ? $compression : [$compression] as $c) { - if ($isRelay ? Relay::COMPRESSION_NONE : \Redis::COMPRESSION_NONE !== $c) { - throw new InvalidArgumentException(sprintf('redis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class)); - } - } - } - - $this->init($redis, $namespace, $defaultLifetime, new TagAwareMarshaller($marshaller)); - } - - protected function doSave(array $values, int $lifetime, array $addTagData = [], array $delTagData = []): array - { - $eviction = $this->getRedisEvictionPolicy(); - if ('noeviction' !== $eviction && !str_starts_with($eviction, 'volatile-')) { - throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction)); - } - - // 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, $failed) { - // 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) { - if (!$failed || $ids = array_diff($ids, $failed)) { - yield 'sAdd' => array_merge([$tagId], $ids); - } - } - - foreach ($delTagData as $tagId => $ids) { - if (!$failed || $ids = array_diff($ids, $failed)) { - 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 || Status::get('OK') !== $result)) { - $failed[] = $id; - } - } - - return $failed; - } - - protected function doDeleteYieldTags(array $ids): iterable - { - $lua = <<<'EOLUA' - local v = redis.call('GET', KEYS[1]) - local e = redis.pcall('UNLINK', KEYS[1]) - - if type(e) ~= 'number' then - redis.call('DEL', KEYS[1]) - end - - if not v or v:len() <= 13 or v:byte(1) ~= 0x9D or v:byte(6) ~= 0 or v:byte(10) ~= 0x5F then - return '' - end - - return v:sub(14, 13 + v:byte(13) + v:byte(12) * 256 + v:byte(11) * 65536) -EOLUA; - - $results = $this->pipeline(function () use ($ids, $lua) { - foreach ($ids as $id) { - yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id] : [$lua, [$id], 1]; - } - }); - - foreach ($results as $id => $result) { - if ($result instanceof \RedisException || $result instanceof \Relay\Exception || $result instanceof ErrorInterface) { - CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $result]); - - continue; - } - - try { - yield $id => !\is_string($result) || '' === $result ? [] : $this->marshaller->unmarshall($result); - } catch (\Exception) { - yield $id => []; - } - } - } - - protected function doDeleteTagRelations(array $tagData): bool - { - $results = $this->pipeline(static function () use ($tagData) { - foreach ($tagData as $tagId => $idList) { - array_unshift($idList, $tagId); - yield 'sRem' => $idList; - } - }); - foreach ($results as $result) { - // no-op - } - - return true; - } - - protected function doInvalidate(array $tagIds): bool - { - // This script scans the set of items linked to tag: it empties the set - // and removes the linked items. When the set is still not empty after - // the scan, it means we're in cluster mode and that the linked items - // are on other nodes: we move the links to a temporary set and we - // garbage collect that set from the client side. - - $lua = <<<'EOLUA' - redis.replicate_commands() - - local cursor = '0' - local id = KEYS[1] - repeat - local result = redis.call('SSCAN', id, cursor, 'COUNT', 5000); - cursor = result[1]; - local rems = {} - - for _, v in ipairs(result[2]) do - local ok, _ = pcall(redis.call, 'DEL', ARGV[1]..v) - if ok then - table.insert(rems, v) - end - end - if 0 < #rems then - redis.call('SREM', id, unpack(rems)) - end - until '0' == cursor; - - redis.call('SUNIONSTORE', '{'..id..'}'..id, id) - redis.call('DEL', id) - - return redis.call('SSCAN', '{'..id..'}'..id, '0', 'COUNT', 5000) -EOLUA; - - $results = $this->pipeline(function () use ($tagIds, $lua) { - if ($this->redis instanceof \Predis\ClientInterface) { - $prefix = $this->redis->getOptions()->prefix ? $this->redis->getOptions()->prefix->getPrefix() : ''; - } elseif (\is_array($prefix = $this->redis->getOption($this->redis instanceof Relay ? Relay::OPT_PREFIX : \Redis::OPT_PREFIX) ?? '')) { - $prefix = current($prefix); - } - - foreach ($tagIds as $id) { - yield 'eval' => $this->redis instanceof \Predis\ClientInterface ? [$lua, 1, $id, $prefix] : [$lua, [$id, $prefix], 1]; - } - }); - - $lua = <<<'EOLUA' - redis.replicate_commands() - - local id = KEYS[1] - local cursor = table.remove(ARGV) - redis.call('SREM', '{'..id..'}'..id, unpack(ARGV)) - - return redis.call('SSCAN', '{'..id..'}'..id, cursor, 'COUNT', 5000) -EOLUA; - - $success = true; - foreach ($results as $id => $values) { - if ($values instanceof \RedisException || $values instanceof \Relay\Exception || $values instanceof ErrorInterface) { - CacheItem::log($this->logger, 'Failed to invalidate key "{key}": '.$values->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $values]); - $success = false; - - continue; - } - - [$cursor, $ids] = $values; - - while ($ids || '0' !== $cursor) { - $this->doDelete($ids); - - $evalArgs = [$id, $cursor]; - array_splice($evalArgs, 1, 0, $ids); - - if ($this->redis instanceof \Predis\ClientInterface) { - array_unshift($evalArgs, $lua, 1); - } else { - $evalArgs = [$lua, $evalArgs, 1]; - } - - $results = $this->pipeline(function () use ($evalArgs) { - yield 'eval' => $evalArgs; - }); - - foreach ($results as [$cursor, $ids]) { - // no-op - } - } - } - - return $success; - } - - private function getRedisEvictionPolicy(): string - { - if (isset($this->redisEvictionPolicy)) { - return $this->redisEvictionPolicy; - } - - $hosts = $this->getHosts(); - $host = reset($hosts); - if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) { - // Predis supports info command only on the master in replication environments - $hosts = [$host->getClientFor('master')]; - } - - foreach ($hosts as $host) { - $info = $host->info('Memory'); - - if (false === $info || null === $info || $info instanceof ErrorInterface) { - continue; - } - - $info = $info['Memory'] ?? $info; - - return $this->redisEvictionPolicy = $info['maxmemory_policy'] ?? ''; - } - - return $this->redisEvictionPolicy = ''; - } -} diff --git a/vendor/symfony/cache/Adapter/TagAwareAdapter.php b/vendor/symfony/cache/Adapter/TagAwareAdapter.php deleted file mode 100644 index 34082db..0000000 --- a/vendor/symfony/cache/Adapter/TagAwareAdapter.php +++ /dev/null @@ -1,370 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Psr\Cache\InvalidArgumentException; -use Psr\Log\LoggerAwareInterface; -use Psr\Log\LoggerAwareTrait; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Component\Cache\Traits\ContractsTrait; -use Symfony\Contracts\Cache\TagAwareCacheInterface; - -/** - * Implements simple and robust tag-based invalidation suitable for use with volatile caches. - * - * This adapter works by storing a version for each tags. When saving an item, it is stored together with its tags and - * their corresponding versions. When retrieving an item, those tag versions are compared to the current version of - * each tags. Invalidation is achieved by deleting tags, thereby ensuring that their versions change even when the - * storage is out of space. When versions of non-existing tags are requested for item commits, this adapter assigns a - * new random version to them. - * - * @author Nicolas Grekas - * @author Sergey Belyshkin - */ -class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface, LoggerAwareInterface -{ - use ContractsTrait; - use LoggerAwareTrait; - - public const TAGS_PREFIX = "\1tags\1"; - - private array $deferred = []; - private AdapterInterface $pool; - private AdapterInterface $tags; - private array $knownTagVersions = []; - - private static \Closure $setCacheItemTags; - private static \Closure $setTagVersions; - private static \Closure $getTagsByKey; - private static \Closure $saveTags; - - public function __construct( - AdapterInterface $itemsPool, - ?AdapterInterface $tagsPool = null, - private float $knownTagVersionsTtl = 0.15, - ) { - $this->pool = $itemsPool; - $this->tags = $tagsPool ?? $itemsPool; - self::$setCacheItemTags ??= \Closure::bind( - static function (array $items, array $itemTags) { - foreach ($items as $key => $item) { - $item->isTaggable = true; - - if (isset($itemTags[$key])) { - $tags = array_keys($itemTags[$key]); - $item->metadata[CacheItem::METADATA_TAGS] = array_combine($tags, $tags); - } else { - $item->value = null; - $item->isHit = false; - $item->metadata = []; - } - } - - return $items; - }, - null, - CacheItem::class - ); - self::$setTagVersions ??= \Closure::bind( - static function (array $items, array $tagVersions) { - foreach ($items as $item) { - $item->newMetadata[CacheItem::METADATA_TAGS] = array_intersect_key($tagVersions, $item->newMetadata[CacheItem::METADATA_TAGS] ?? []); - } - }, - null, - CacheItem::class - ); - self::$getTagsByKey ??= \Closure::bind( - static function ($deferred) { - $tagsByKey = []; - foreach ($deferred as $key => $item) { - $tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? []; - $item->metadata = $item->newMetadata; - } - - return $tagsByKey; - }, - null, - CacheItem::class - ); - self::$saveTags ??= \Closure::bind( - static function (AdapterInterface $tagsAdapter, array $tags) { - ksort($tags); - - foreach ($tags as $v) { - $v->expiry = 0; - $tagsAdapter->saveDeferred($v); - } - - return $tagsAdapter->commit(); - }, - null, - CacheItem::class - ); - } - - public function invalidateTags(array $tags): bool - { - $ids = []; - foreach ($tags as $tag) { - \assert('' !== CacheItem::validateKey($tag)); - unset($this->knownTagVersions[$tag]); - $ids[] = $tag.static::TAGS_PREFIX; - } - - return !$tags || $this->tags->deleteItems($ids); - } - - public function hasItem(mixed $key): bool - { - return $this->getItem($key)->isHit(); - } - - public function getItem(mixed $key): CacheItem - { - foreach ($this->getItems([$key]) as $item) { - return $item; - } - } - - public function getItems(array $keys = []): iterable - { - $tagKeys = []; - $commit = false; - - foreach ($keys as $key) { - if ('' !== $key && \is_string($key)) { - $commit = $commit || isset($this->deferred[$key]); - } - } - - if ($commit) { - $this->commit(); - } - - try { - $items = $this->pool->getItems($keys); - } catch (InvalidArgumentException $e) { - $this->pool->getItems($keys); // Should throw an exception - - throw $e; - } - - $bufferedItems = $itemTags = []; - - foreach ($items as $key => $item) { - if (null !== $tags = $item->getMetadata()[CacheItem::METADATA_TAGS] ?? null) { - $itemTags[$key] = $tags; - } - - $bufferedItems[$key] = $item; - - if (null === $tags) { - $key = "\0tags\0".$key; - $tagKeys[$key] = $key; // BC with pools populated before v6.1 - } - } - - if ($tagKeys) { - foreach ($this->pool->getItems($tagKeys) as $key => $item) { - if ($item->isHit()) { - $itemTags[substr($key, \strlen("\0tags\0"))] = $item->get() ?: []; - } - } - } - - $tagVersions = $this->getTagVersions($itemTags, false); - foreach ($itemTags as $key => $tags) { - foreach ($tags as $tag => $version) { - if ($tagVersions[$tag] !== $version) { - unset($itemTags[$key]); - continue 2; - } - } - } - $tagVersions = null; - - return (self::$setCacheItemTags)($bufferedItems, $itemTags); - } - - public function clear(string $prefix = ''): bool - { - if ('' !== $prefix) { - foreach ($this->deferred as $key => $item) { - if (str_starts_with($key, $prefix)) { - unset($this->deferred[$key]); - } - } - } else { - $this->deferred = []; - } - - if ($this->pool instanceof AdapterInterface) { - return $this->pool->clear($prefix); - } - - return $this->pool->clear(); - } - - public function deleteItem(mixed $key): bool - { - return $this->deleteItems([$key]); - } - - public function deleteItems(array $keys): bool - { - foreach ($keys as $key) { - if ('' !== $key && \is_string($key)) { - $keys[] = "\0tags\0".$key; // BC with pools populated before v6.1 - } - } - - return $this->pool->deleteItems($keys); - } - - public function save(CacheItemInterface $item): bool - { - if (!$item instanceof CacheItem) { - return false; - } - $this->deferred[$item->getKey()] = $item; - - return $this->commit(); - } - - public function saveDeferred(CacheItemInterface $item): bool - { - if (!$item instanceof CacheItem) { - return false; - } - $this->deferred[$item->getKey()] = $item; - - return true; - } - - public function commit(): bool - { - if (!$items = $this->deferred) { - return true; - } - - $tagVersions = $this->getTagVersions((self::$getTagsByKey)($items), true); - (self::$setTagVersions)($items, $tagVersions); - - $ok = true; - foreach ($items as $key => $item) { - if ($this->pool->saveDeferred($item)) { - unset($this->deferred[$key]); - } else { - $ok = false; - } - } - $ok = $this->pool->commit() && $ok; - - $tagVersions = array_keys($tagVersions); - (self::$setTagVersions)($items, array_combine($tagVersions, $tagVersions)); - - return $ok; - } - - public function prune(): bool - { - return $this->pool instanceof PruneableInterface && $this->pool->prune(); - } - - public function reset(): void - { - $this->commit(); - $this->knownTagVersions = []; - $this->pool instanceof ResettableInterface && $this->pool->reset(); - $this->tags instanceof ResettableInterface && $this->tags->reset(); - } - - public function __sleep(): array - { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); - } - - public function __wakeup(): void - { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - public function __destruct() - { - $this->commit(); - } - - private function getTagVersions(array $tagsByKey, bool $persistTags): array - { - $tagVersions = []; - $fetchTagVersions = $persistTags; - - foreach ($tagsByKey as $tags) { - $tagVersions += $tags; - if ($fetchTagVersions) { - continue; - } - foreach ($tags as $tag => $version) { - if ($tagVersions[$tag] !== $version) { - $fetchTagVersions = true; - } - } - } - - if (!$tagVersions) { - return []; - } - - $now = microtime(true); - $tags = []; - foreach ($tagVersions as $tag => $version) { - $tags[$tag.static::TAGS_PREFIX] = $tag; - $knownTagVersion = $this->knownTagVersions[$tag] ?? [0, null]; - if ($fetchTagVersions || $now > $knownTagVersion[0] || $knownTagVersion[1] !== $version) { - // reuse previously fetched tag versions until the expiration - $fetchTagVersions = true; - } - } - - if (!$fetchTagVersions) { - return $tagVersions; - } - - $newTags = []; - $newVersion = null; - $expiration = $now + $this->knownTagVersionsTtl; - foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) { - unset($this->knownTagVersions[$tag = $tags[$tag]]); // update FIFO - if (null !== $tagVersions[$tag] = $version->get()) { - $this->knownTagVersions[$tag] = [$expiration, $tagVersions[$tag]]; - } elseif ($persistTags) { - $newTags[$tag] = $version->set($newVersion ??= random_bytes(6)); - $tagVersions[$tag] = $newVersion; - $this->knownTagVersions[$tag] = [$expiration, $newVersion]; - } - } - - if ($newTags) { - (self::$saveTags)($this->tags, $newTags); - } - - while ($now > ($this->knownTagVersions[$tag = array_key_first($this->knownTagVersions)][0] ?? \INF)) { - unset($this->knownTagVersions[$tag]); - } - - return $tagVersions; - } -} diff --git a/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php b/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php deleted file mode 100644 index 9242779..0000000 --- a/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * 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\Cache\InvalidArgumentException; - -/** - * Interface for invalidating cached items using tags. - * - * @author Nicolas Grekas - */ -interface TagAwareAdapterInterface extends AdapterInterface -{ - /** - * Invalidates cached items using tags. - * - * @param string[] $tags An array of tags to invalidate - * - * @throws InvalidArgumentException When $tags is not valid - */ - public function invalidateTags(array $tags): bool; -} diff --git a/vendor/symfony/cache/Adapter/TraceableAdapter.php b/vendor/symfony/cache/Adapter/TraceableAdapter.php deleted file mode 100644 index b5bce14..0000000 --- a/vendor/symfony/cache/Adapter/TraceableAdapter.php +++ /dev/null @@ -1,250 +0,0 @@ - - * - * 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\Cache\CacheItemInterface; -use Symfony\Component\Cache\CacheItem; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; -use Symfony\Contracts\Cache\CacheInterface; -use Symfony\Contracts\Service\ResetInterface; - -/** - * An adapter that collects data about all cache calls. - * - * @author Aaron Scherer - * @author Tobias Nyholm - * @author Nicolas Grekas - */ -class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface -{ - protected AdapterInterface $pool; - private array $calls = []; - - public function __construct(AdapterInterface $pool) - { - $this->pool = $pool; - } - - public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed - { - if (!$this->pool instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class)); - } - - $isHit = true; - $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) { - $isHit = $item->isHit(); - - return $callback($item, $save); - }; - - $event = $this->start(__FUNCTION__); - try { - $value = $this->pool->get($key, $callback, $beta, $metadata); - $event->result[$key] = get_debug_type($value); - } finally { - $event->end = microtime(true); - } - if ($isHit) { - ++$event->hits; - } else { - ++$event->misses; - } - - return $value; - } - - public function getItem(mixed $key): CacheItem - { - $event = $this->start(__FUNCTION__); - try { - $item = $this->pool->getItem($key); - } finally { - $event->end = microtime(true); - } - if ($event->result[$key] = $item->isHit()) { - ++$event->hits; - } else { - ++$event->misses; - } - - return $item; - } - - public function hasItem(mixed $key): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result[$key] = $this->pool->hasItem($key); - } finally { - $event->end = microtime(true); - } - } - - public function deleteItem(mixed $key): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result[$key] = $this->pool->deleteItem($key); - } finally { - $event->end = microtime(true); - } - } - - public function save(CacheItemInterface $item): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result[$item->getKey()] = $this->pool->save($item); - } finally { - $event->end = microtime(true); - } - } - - public function saveDeferred(CacheItemInterface $item): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result[$item->getKey()] = $this->pool->saveDeferred($item); - } finally { - $event->end = microtime(true); - } - } - - public function getItems(array $keys = []): iterable - { - $event = $this->start(__FUNCTION__); - try { - $result = $this->pool->getItems($keys); - } finally { - $event->end = microtime(true); - } - $f = function () use ($result, $event) { - $event->result = []; - foreach ($result as $key => $item) { - if ($event->result[$key] = $item->isHit()) { - ++$event->hits; - } else { - ++$event->misses; - } - yield $key => $item; - } - }; - - return $f(); - } - - public function clear(string $prefix = ''): bool - { - $event = $this->start(__FUNCTION__); - try { - if ($this->pool instanceof AdapterInterface) { - return $event->result = $this->pool->clear($prefix); - } - - return $event->result = $this->pool->clear(); - } finally { - $event->end = microtime(true); - } - } - - public function deleteItems(array $keys): bool - { - $event = $this->start(__FUNCTION__); - $event->result['keys'] = $keys; - try { - return $event->result['result'] = $this->pool->deleteItems($keys); - } finally { - $event->end = microtime(true); - } - } - - public function commit(): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result = $this->pool->commit(); - } finally { - $event->end = microtime(true); - } - } - - public function prune(): bool - { - if (!$this->pool instanceof PruneableInterface) { - return false; - } - $event = $this->start(__FUNCTION__); - try { - return $event->result = $this->pool->prune(); - } finally { - $event->end = microtime(true); - } - } - - public function reset(): void - { - if ($this->pool instanceof ResetInterface) { - $this->pool->reset(); - } - - $this->clearCalls(); - } - - public function delete(string $key): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result[$key] = $this->pool->deleteItem($key); - } finally { - $event->end = microtime(true); - } - } - - public function getCalls(): array - { - return $this->calls; - } - - public function clearCalls(): void - { - $this->calls = []; - } - - public function getPool(): AdapterInterface - { - return $this->pool; - } - - protected function start(string $name): TraceableAdapterEvent - { - $this->calls[] = $event = new TraceableAdapterEvent(); - $event->name = $name; - $event->start = microtime(true); - - return $event; - } -} - -/** - * @internal - */ -class TraceableAdapterEvent -{ - public string $name; - public float $start; - public float $end; - public array|bool $result; - public int $hits = 0; - public int $misses = 0; -} diff --git a/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php b/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php deleted file mode 100644 index c85d199..0000000 --- a/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * 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\Contracts\Cache\TagAwareCacheInterface; - -/** - * @author Robin Chalas - */ -class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface -{ - public function __construct(TagAwareAdapterInterface $pool) - { - parent::__construct($pool); - } - - public function invalidateTags(array $tags): bool - { - $event = $this->start(__FUNCTION__); - try { - return $event->result = $this->pool->invalidateTags($tags); - } finally { - $event->end = microtime(true); - } - } -} -- cgit v1.2.3