diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheInterface.php b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheInterface.php new file mode 100644 index 0000000..4b1686b --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheInterface.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\InvalidArgumentException; + +/** + * Covers most simple to advanced caching needs. + * + * @author Nicolas Grekas
+ */ +interface CacheInterface +{ + /** + * Fetches a value from the pool or computes it if not found. + * + * On cache misses, a callback is called that should return the missing value. + * This callback is given a PSR-6 CacheItemInterface instance corresponding to the + * requested key, that could be used e.g. for expiration control. It could also + * be an ItemInterface instance when its additional features are needed. + * + * @param string $key The key of the item to retrieve from the cache + * @param callable|CallbackInterface $callback Should return the computed value for the given key/item + * @param float|null $beta A float that, as it grows, controls the likeliness of triggering + * early expiration. 0 disables it, INF forces immediate expiration. + * The default (or providing null) is implementation dependent but should + * typically be 1.0, which should provide optimal stampede protection. + * See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration + * @param array &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()} + * + * @return mixed The value corresponding to the provided key + * + * @throws InvalidArgumentException When $key is not valid or when $beta is negative + */ + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null); + + /** + * Removes an item from the pool. + * + * @param string $key The key to delete + * + * @throws InvalidArgumentException When $key is not valid + * + * @return bool True if the item was successfully removed, false if there was any error + */ + public function delete(string $key): bool; +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheTrait.php b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheTrait.php new file mode 100644 index 0000000..7bbdef0 --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CacheTrait.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemPoolInterface; +use Psr\Cache\InvalidArgumentException; +use Psr\Log\LoggerInterface; + +/** + * An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes. + * + * @author Nicolas Grekas
+ */ +trait CacheTrait +{ + /** + * {@inheritdoc} + */ + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) + { + return $this->doGet($this, $key, $callback, $beta, $metadata); + } + + /** + * {@inheritdoc} + */ + public function delete(string $key): bool + { + return $this->deleteItem($key); + } + + private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null, LoggerInterface $logger = null) + { + if (0 > $beta = $beta ?? 1.0) { + throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta)) extends \InvalidArgumentException implements InvalidArgumentException { + }; + } + + $item = $pool->getItem($key); + $recompute = !$item->isHit() || INF === $beta; + $metadata = $item instanceof ItemInterface ? $item->getMetadata() : []; + + if (!$recompute && $metadata) { + $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false; + $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false; + + if ($recompute = $ctime && $expiry && $expiry <= ($now = microtime(true)) - $ctime / 1000 * $beta * log(random_int(1, PHP_INT_MAX) / PHP_INT_MAX)) { + // force applying defaultLifetime to expiry + $item->expiresAt(null); + $this->logger && $this->logger->info('Item "{key}" elected for early recomputation {delta}s before its expiration', [ + 'key' => $key, + 'delta' => sprintf('%.1f', $expiry - $now), + ]); + } + } + + if ($recompute) { + $save = true; + $item->set($callback($item, $save)); + if ($save) { + $pool->save($item); + } + } + + return $item->get(); + } +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/CallbackInterface.php b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CallbackInterface.php new file mode 100644 index 0000000..7dae2aa --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/CallbackInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemInterface; + +/** + * Computes and returns the cached value of an item. + * + * @author Nicolas Grekas
+ */ +interface CallbackInterface +{ + /** + * @param CacheItemInterface|ItemInterface $item The item to compute the value for + * @param bool &$save Should be set to false when the value should not be saved in the pool + * + * @return mixed The computed value for the passed item + */ + public function __invoke(CacheItemInterface $item, bool &$save); +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/ItemInterface.php b/addons/weliam_smartcity/vendor/symfony/cache-contracts/ItemInterface.php new file mode 100644 index 0000000..4884a2f --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/ItemInterface.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheException; +use Psr\Cache\CacheItemInterface; +use Psr\Cache\InvalidArgumentException; + +/** + * Augments PSR-6's CacheItemInterface with support for tags and metadata. + * + * @author Nicolas Grekas
+ */ +interface ItemInterface extends CacheItemInterface +{ + /** + * References the Unix timestamp stating when the item will expire. + */ + const METADATA_EXPIRY = 'expiry'; + + /** + * References the time the item took to be created, in milliseconds. + */ + const METADATA_CTIME = 'ctime'; + + /** + * References the list of tags that were assigned to the item, as string[]. + */ + const METADATA_TAGS = 'tags'; + + /** + * Adds a tag to a cache item. + * + * Tags are strings that follow the same validation rules as keys. + * + * @param string|string[] $tags A tag or array of tags + * + * @return $this + * + * @throws InvalidArgumentException When $tag is not valid + * @throws CacheException When the item comes from a pool that is not tag-aware + */ + public function tag($tags): self; + + /** + * Returns a list of metadata info that were saved alongside with the cached value. + * + * See ItemInterface::METADATA_* consts for keys potentially found in the returned array. + */ + public function getMetadata(): array; +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/LICENSE b/addons/weliam_smartcity/vendor/symfony/cache-contracts/LICENSE new file mode 100644 index 0000000..3f853aa --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/README.md b/addons/weliam_smartcity/vendor/symfony/cache-contracts/README.md new file mode 100644 index 0000000..58c589e --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/README.md @@ -0,0 +1,9 @@ +Symfony Cache Contracts +======================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/master/README.md for more information. diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/TagAwareCacheInterface.php b/addons/weliam_smartcity/vendor/symfony/cache-contracts/TagAwareCacheInterface.php new file mode 100644 index 0000000..7c4cf11 --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/TagAwareCacheInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\InvalidArgumentException; + +/** + * Allows invalidating cached items using tags. + * + * @author Nicolas Grekas
+ */ +interface TagAwareCacheInterface extends CacheInterface +{ + /** + * Invalidates cached items using tags. + * + * When implemented on a PSR-6 pool, invalidation should not apply + * to deferred items. Instead, they should be committed as usual. + * This allows replacing old tagged values by new ones without + * race conditions. + * + * @param string[] $tags An array of tags to invalidate + * + * @return bool True on success + * + * @throws InvalidArgumentException When $tags is not valid + */ + public function invalidateTags(array $tags); +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache-contracts/composer.json b/addons/weliam_smartcity/vendor/symfony/cache-contracts/composer.json new file mode 100644 index 0000000..4e0bd1a --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache-contracts/composer.json @@ -0,0 +1,34 @@ +{ + "name": "symfony/cache-contracts", + "type": "library", + "description": "Generic abstractions related to caching", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3", + "psr/cache": "^1.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\Cache\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + } +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache/.gitignore b/addons/weliam_smartcity/vendor/symfony/cache/.gitignore new file mode 100644 index 0000000..5414c2c --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache/.gitignore @@ -0,0 +1,3 @@ +composer.lock +phpunit.xml +vendor/ diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractAdapter.php new file mode 100644 index 0000000..80f60e5 --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractAdapter.php @@ -0,0 +1,201 @@ + + * + * 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 Psr\Log\NullLogger; +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 +{ + /** + * @internal + */ + protected const NS_SEPARATOR = ':'; + + use AbstractAdapterTrait; + use ContractsTrait; + + private static $apcuSupported; + private static $phpFilesSupported; + + protected function __construct(string $namespace = '', int $defaultLifetime = 0) + { + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + } + $this->createCacheItem = \Closure::bind( + static function ($key, $value, $isHit) use ($defaultLifetime) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $v = $value; + $item->isHit = $isHit; + $item->defaultLifetime = $defaultLifetime; + // Detect wrapped values that encode for their expiry and creation duration + // For compactness, these values are packed in the key of an array using + // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F + if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) { + $item->value = $v[$k]; + $v = unpack('Ve/Nc', substr($k, 1, -1)); + $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET; + $item->metadata[CacheItem::METADATA_CTIME] = $v['c']; + } + + return $item; + }, + null, + CacheItem::class + ); + $getId = \Closure::fromCallable([$this, 'getId']); + $this->mergeByLifetime = \Closure::bind( + static function ($deferred, $namespace, &$expiredIds) use ($getId) { + $byLifetime = []; + $now = microtime(true); + $expiredIds = []; + + foreach ($deferred as $key => $item) { + $key = (string) $key; + if (null === $item->expiry) { + $ttl = 0 < $item->defaultLifetime ? $item->defaultLifetime : 0; + } elseif (0 >= $ttl = (int) ($item->expiry - $now)) { + $expiredIds[] = $getId($key); + continue; + } + if (isset(($metadata = $item->newMetadata)[CacheItem::METADATA_TAGS])) { + unset($metadata[CacheItem::METADATA_TAGS]); + } + // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators + $byLifetime[$ttl][$getId($key)] = $metadata ? ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - CacheItem::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $item->value] : $item->value; + } + + return $byLifetime; + }, + null, + CacheItem::class + ); + } + + /** + * Returns the best possible adapter that your runtime supports. + * + * Using ApcuAdapter makes system caches compatible with read-only filesystems. + * + * @param string $namespace + * @param int $defaultLifetime + * @param string $version + * @param string $directory + * + * @return AdapterInterface + */ + public static function createSystemCache($namespace, $defaultLifetime, $version, $directory, LoggerInterface $logger = null) + { + $opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory, true); + if (null !== $logger) { + $opcache->setLogger($logger); + } + + if (!self::$apcuSupported = self::$apcuSupported ?? ApcuAdapter::isSupported()) { + return $opcache; + } + + $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { + $apcu->setLogger(new NullLogger()); + } elseif (null !== $logger) { + $apcu->setLogger($logger); + } + + return new ChainAdapter([$apcu, $opcache]); + } + + public static function createConnection($dsn, array $options = []) + { + if (!\is_string($dsn)) { + throw new InvalidArgumentException(sprintf('The %s() method expect argument #1 to be string, %s given.', __METHOD__, \gettype($dsn))); + } + if (0 === strpos($dsn, 'redis:') || 0 === strpos($dsn, 'rediss:')) { + return RedisAdapter::createConnection($dsn, $options); + } + if (0 === strpos($dsn, 'memcached:')) { + return MemcachedAdapter::createConnection($dsn, $options); + } + + throw new InvalidArgumentException(sprintf('Unsupported DSN: %s.', $dsn)); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + $ok = true; + $byLifetime = $this->mergeByLifetime; + $byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds); + $retry = $this->deferred = []; + + if ($expiredIds) { + $this->doDelete($expiredIds); + } + 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 = \is_object($v) ? \get_class($v) : \gettype($v); + $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]); + } + } else { + foreach ($values as $id => $v) { + $retry[$lifetime][] = $id; + } + } + } + + // When bulk-save failed, retry each item individually + foreach ($retry as $lifetime => $ids) { + foreach ($ids as $id) { + try { + $v = $byLifetime[$lifetime][$id]; + $e = $this->doSave([$id => $v], $lifetime); + } catch (\Exception $e) { + } + if (true === $e || [] === $e) { + continue; + } + $ok = false; + $type = \is_object($v) ? \get_class($v) : \gettype($v); + $message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.'); + CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]); + } + } + + return $ok; + } +} diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php new file mode 100644 index 0000000..97476a8 --- /dev/null +++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/AbstractTagAwareAdapter.php @@ -0,0 +1,305 @@ + + * + * 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
+ */
+class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInterface, ResettableInterface
+{
+ use ArrayTrait;
+
+ private $createCacheItem;
+
+ /**
+ * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
+ */
+ public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true)
+ {
+ $this->storeSerialized = $storeSerialized;
+ $this->createCacheItem = \Closure::bind(
+ static function ($key, $value, $isHit) use ($defaultLifetime) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->value = $value;
+ $item->isHit = $isHit;
+ $item->defaultLifetime = $defaultLifetime;
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
+ {
+ $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;
+ $this->save($item->set($callback($item, $save)));
+ }
+
+ return $item->get();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if (!$isHit = $this->hasItem($key)) {
+ $this->values[$key] = $value = null;
+ } else {
+ $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
+ }
+ $f = $this->createCacheItem;
+
+ return $f($key, $value, $isHit);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ foreach ($keys as $key) {
+ if (!\is_string($key) || !isset($this->expiries[$key])) {
+ CacheItem::validateKey($key);
+ }
+ }
+
+ return $this->generateItems($keys, microtime(true), $this->createCacheItem);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ foreach ($keys as $key) {
+ $this->deleteItem($key);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $item = (array) $item;
+ $key = $item["\0*\0key"];
+ $value = $item["\0*\0value"];
+ $expiry = $item["\0*\0expiry"];
+
+ if (null !== $expiry && $expiry <= microtime(true)) {
+ $this->deleteItem($key);
+
+ return true;
+ }
+ if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
+ return false;
+ }
+ if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) {
+ $expiry = microtime(true) + $item["\0*\0defaultLifetime"];
+ }
+
+ $this->values[$key] = $value;
+ $this->expiries[$key] = null !== $expiry ? $expiry : PHP_INT_MAX;
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ return $this->save($item);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete(string $key): bool
+ {
+ return $this->deleteItem($key);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ChainAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ChainAdapter.php
new file mode 100644
index 0000000..0217c80
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ChainAdapter.php
@@ -0,0 +1,310 @@
+
+ *
+ * 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
+ * @author André Rømcke
+ */
+class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
+{
+ use PhpArrayTrait;
+ use ContractsTrait;
+
+ private $createCacheItem;
+
+ /**
+ * @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(string $file, AdapterInterface $fallbackPool)
+ {
+ $this->file = $file;
+ $this->pool = $fallbackPool;
+ $this->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 Fallback when opcache is disabled
+ *
+ * @return CacheItemPoolInterface
+ */
+ public static function create($file, CacheItemPoolInterface $fallbackPool)
+ {
+ // Shared memory is available in PHP 7.0+ with OPCache enabled
+ if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
+ if (!$fallbackPool instanceof AdapterInterface) {
+ $fallbackPool = new ProxyAdapter($fallbackPool);
+ }
+
+ return new static($file, $fallbackPool);
+ }
+
+ return $fallbackPool;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
+ {
+ if (null === $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 $e) {
+ unset($this->keys[$key]);
+ goto get_from_pool;
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $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 $e) {
+ $value = null;
+ $isHit = false;
+ }
+ }
+
+ $f = $this->createCacheItem;
+
+ return $f($key, $value, $isHit);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return $this->generateItems($keys);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return isset($this->keys[$key]) || $this->pool->hasItem($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return !isset($this->keys[$key]) && $this->pool->deleteItem($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ $deleted = true;
+ $fallbackKeys = [];
+
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+
+ if (isset($this->keys[$key])) {
+ $deleted = false;
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ if ($fallbackKeys) {
+ $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted;
+ }
+
+ return $deleted;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return !isset($this->keys[$item->getKey()]) && $this->pool->save($item);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return $this->pool->commit();
+ }
+
+ private function generateItems(array $keys): \Generator
+ {
+ $f = $this->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 $e) {
+ yield $key => $f($key, null, false);
+ }
+ } else {
+ yield $key => $f($key, $value, true);
+ }
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+
+ if ($fallbackKeys) {
+ yield from $this->pool->getItems($fallbackKeys);
+ }
+ }
+
+ /**
+ * @throws \ReflectionException When $class is not found and is required
+ *
+ * @internal to be removed in Symfony 5.0
+ */
+ public static function throwOnRequiredClass($class)
+ {
+ $e = new \ReflectionException("Class $class does not exist");
+ $trace = $e->getTrace();
+ $autoloadFrame = [
+ 'function' => 'spl_autoload_call',
+ 'args' => [$class],
+ ];
+ $i = 1 + array_search($autoloadFrame, $trace, true);
+
+ if (isset($trace[$i]['function']) && !isset($trace[$i]['class'])) {
+ switch ($trace[$i]['function']) {
+ case 'get_class_methods':
+ case 'get_class_vars':
+ case 'get_parent_class':
+ case 'is_a':
+ case 'is_subclass_of':
+ case 'class_exists':
+ case 'class_implements':
+ case 'class_parents':
+ case 'trait_exists':
+ case 'defined':
+ case 'interface_exists':
+ case 'method_exists':
+ case 'property_exists':
+ case 'is_callable':
+ return;
+ }
+ }
+
+ throw $e;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/PhpFilesAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
new file mode 100644
index 0000000..10938a0
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/PhpFilesAdapter.php
@@ -0,0 +1,38 @@
+
+ *
+ * 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\PruneableInterface;
+use Symfony\Component\Cache\Traits\PhpFilesTrait;
+
+class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
+{
+ use PhpFilesTrait;
+
+ /**
+ * @param $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, bool $appendOnly = false)
+ {
+ $this->appendOnly = $appendOnly;
+ self::$startTime = 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);
+ };
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ProxyAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ProxyAdapter.php
new file mode 100644
index 0000000..cddf54a
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/ProxyAdapter.php
@@ -0,0 +1,247 @@
+
+ *
+ * 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 ProxyTrait;
+ use ContractsTrait;
+
+ private $namespace;
+ private $namespaceLen;
+ private $createCacheItem;
+ private $setInnerItem;
+ private $poolHash;
+
+ public function __construct(CacheItemPoolInterface $pool, string $namespace = '', int $defaultLifetime = 0)
+ {
+ $this->pool = $pool;
+ $this->poolHash = $poolHash = spl_object_hash($pool);
+ $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace);
+ $this->namespaceLen = \strlen($namespace);
+ $this->createCacheItem = \Closure::bind(
+ static function ($key, $innerItem) use ($defaultLifetime, $poolHash) {
+ $item = new CacheItem();
+ $item->key = $key;
+
+ if (null === $innerItem) {
+ return $item;
+ }
+
+ $item->value = $v = $innerItem->get();
+ $item->isHit = $innerItem->isHit();
+ $item->innerItem = $innerItem;
+ $item->defaultLifetime = $defaultLifetime;
+ $item->poolHash = $poolHash;
+
+ // Detect wrapped values that encode for their expiry and creation duration
+ // For compactness, these values are packed in the key of an array using
+ // magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
+ if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
+ $item->value = $v[$k];
+ $v = unpack('Ve/Nc', substr($k, 1, -1));
+ $item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;
+ $item->metadata[CacheItem::METADATA_CTIME] = $v['c'];
+ } elseif ($innerItem instanceof CacheItem) {
+ $item->metadata = $innerItem->metadata;
+ }
+ $innerItem->set(null);
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ $this->setInnerItem = \Closure::bind(
+ /**
+ * @param array $item A CacheItem cast to (array); accessing protected properties requires adding the "\0*\0" PHP prefix
+ */
+ static function (CacheItemInterface $innerItem, array $item) {
+ // Tags are stored separately, no need to account for them when considering this item's newly set metadata
+ if (isset(($metadata = $item["\0*\0newMetadata"])[CacheItem::METADATA_TAGS])) {
+ unset($metadata[CacheItem::METADATA_TAGS]);
+ }
+ if ($metadata) {
+ // For compactness, expiry and creation duration are packed in the key of an array, using magic numbers as separators
+ $item["\0*\0value"] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - CacheItem::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $item["\0*\0value"]];
+ }
+ $innerItem->set($item["\0*\0value"]);
+ $innerItem->expiresAt(null !== $item["\0*\0expiry"] ? \DateTime::createFromFormat('U.u', sprintf('%.6f', $item["\0*\0expiry"])) : null);
+ },
+ null,
+ CacheItem::class
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
+ {
+ 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 = ($this->createCacheItem)($key, $innerItem);
+ $item->set($value = $callback($item, $save));
+ ($this->setInnerItem)($innerItem, (array) $item);
+
+ return $value;
+ }, $beta, $metadata);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ $f = $this->createCacheItem;
+ $item = $this->pool->getItem($this->getId($key));
+
+ return $f($key, $item);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ if ($this->namespaceLen) {
+ foreach ($keys as $i => $key) {
+ $keys[$i] = $this->getId($key);
+ }
+ }
+
+ return $this->generateItems($this->pool->getItems($keys));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ return $this->pool->hasItem($this->getId($key));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ return $this->pool->deleteItem($this->getId($key));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ if ($this->namespaceLen) {
+ foreach ($keys as $i => $key) {
+ $keys[$i] = $this->getId($key);
+ }
+ }
+
+ return $this->pool->deleteItems($keys);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ return $this->doSave($item, __FUNCTION__);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ return $this->doSave($item, __FUNCTION__);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return $this->pool->commit();
+ }
+
+ private function doSave(CacheItemInterface $item, $method)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $item = (array) $item;
+ if (null === $item["\0*\0expiry"] && 0 < $item["\0*\0defaultLifetime"]) {
+ $item["\0*\0expiry"] = microtime(true) + $item["\0*\0defaultLifetime"];
+ }
+
+ if ($item["\0*\0poolHash"] === $this->poolHash && $item["\0*\0innerItem"]) {
+ $innerItem = $item["\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
+ $f = $this->createCacheItem;
+ $innerItem = $f($this->namespace.$item["\0*\0key"], null);
+ } else {
+ $innerItem = $this->pool->getItem($this->namespace.$item["\0*\0key"]);
+ }
+
+ ($this->setInnerItem)($innerItem, $item);
+
+ return $this->pool->$method($innerItem);
+ }
+
+ private function generateItems($items)
+ {
+ $f = $this->createCacheItem;
+
+ foreach ($items as $key => $item) {
+ if ($this->namespaceLen) {
+ $key = substr($key, $this->namespaceLen);
+ }
+
+ yield $key => $f($key, $item);
+ }
+ }
+
+ private function getId($key)
+ {
+ CacheItem::validateKey($key);
+
+ return $this->namespace.$key;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/Psr16Adapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/Psr16Adapter.php
new file mode 100644
index 0000000..bb38871
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/Psr16Adapter.php
@@ -0,0 +1,86 @@
+
+ *
+ * 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
+{
+ /**
+ * @internal
+ */
+ protected const NS_SEPARATOR = '_';
+
+ use ProxyTrait;
+
+ private $miss;
+
+ public function __construct(CacheInterface $pool, string $namespace = '', int $defaultLifetime = 0)
+ {
+ parent::__construct($namespace, $defaultLifetime);
+
+ $this->pool = $pool;
+ $this->miss = new \stdClass();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) {
+ if ($this->miss !== $value) {
+ yield $key => $value;
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ return $this->pool->has($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ return $this->pool->deleteMultiple($ids);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisAdapter.php
new file mode 100644
index 0000000..9d3931d
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisAdapter.php
@@ -0,0 +1,30 @@
+
+ *
+ * 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;
+
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient The redis client
+ * @param string $namespace The default namespace
+ * @param int $defaultLifetime The default lifetime
+ */
+ public function __construct($redisClient, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
+ {
+ $this->init($redisClient, $namespace, $defaultLifetime, $marshaller);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
new file mode 100644
index 0000000..0edec18
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/RedisTagAwareAdapter.php
@@ -0,0 +1,208 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Adapter;
+
+use Predis;
+use Predis\Connection\Aggregate\ClusterInterface;
+use Predis\Response\Status;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\LogicException;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\Traits\RedisTrait;
+
+/**
+ * Stores tag id <> cache id relationship as a Redis Set, lookup on invalidation using sPOP.
+ *
+ * Set (tag relation info) is stored without expiry (non-volatile), while cache always gets an expiry (volatile) even
+ * if not set by caller. Thus if you configure redis with the right eviction policy you can be safe this tag <> cache
+ * relationship survives eviction (cache cleanup when Redis runs out of memory).
+ *
+ * Requirements:
+ * - Server: Redis 3.2+
+ * - Client: PHP Redis 3.1.3+ OR Predis
+ * - Redis Server(s) configured with any `volatile-*` eviction policy, OR `noeviction` if it will NEVER fill up memory
+ *
+ * Design limitations:
+ * - Max 2 billion cache keys per cache tag
+ * E.g. If you use a "all" items tag for expiry instead of clear(), that limits you to 2 billion cache items as well
+ *
+ * @see https://redis.io/topics/lru-cache#eviction-policies Documentation for Redis eviction policies.
+ * @see https://redis.io/topics/data-types#sets Documentation for Redis Set datatype.
+ * @see https://redis.io/commands/spop Documentation for sPOP operation, capable of retriving AND emptying a Set at once.
+ *
+ * @author Nicolas Grekas
+ * @author André Rømcke
+ */
+class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface
+{
+ const TAGS_PREFIX = "\0tags\0";
+
+ use ProxyTrait;
+ use ContractsTrait;
+
+ private $deferred = [];
+ private $createCacheItem;
+ private $setCacheItemTags;
+ private $getTagsByKey;
+ private $invalidateTags;
+ private $tags;
+ private $knownTagVersions = [];
+ private $knownTagVersionsTtl;
+
+ public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, float $knownTagVersionsTtl = 0.15)
+ {
+ $this->pool = $itemsPool;
+ $this->tags = $tagsPool ?: $itemsPool;
+ $this->knownTagVersionsTtl = $knownTagVersionsTtl;
+ $this->createCacheItem = \Closure::bind(
+ static function ($key, $value, CacheItem $protoItem) {
+ $item = new CacheItem();
+ $item->key = $key;
+ $item->value = $value;
+ $item->defaultLifetime = $protoItem->defaultLifetime;
+ $item->expiry = $protoItem->expiry;
+ $item->poolHash = $protoItem->poolHash;
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ $this->setCacheItemTags = \Closure::bind(
+ static function (CacheItem $item, $key, array &$itemTags) {
+ $item->isTaggable = true;
+ if (!$item->isHit) {
+ return $item;
+ }
+ if (isset($itemTags[$key])) {
+ foreach ($itemTags[$key] as $tag => $version) {
+ $item->metadata[CacheItem::METADATA_TAGS][$tag] = $tag;
+ }
+ unset($itemTags[$key]);
+ } else {
+ $item->value = null;
+ $item->isHit = false;
+ }
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ $this->getTagsByKey = \Closure::bind(
+ static function ($deferred) {
+ $tagsByKey = [];
+ foreach ($deferred as $key => $item) {
+ $tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? [];
+ }
+
+ return $tagsByKey;
+ },
+ null,
+ CacheItem::class
+ );
+ $this->invalidateTags = \Closure::bind(
+ static function (AdapterInterface $tagsAdapter, array $tags) {
+ foreach ($tags as $v) {
+ $v->defaultLifetime = 0;
+ $v->expiry = null;
+ $tagsAdapter->saveDeferred($v);
+ }
+
+ return $tagsAdapter->commit();
+ },
+ null,
+ CacheItem::class
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function invalidateTags(array $tags)
+ {
+ $ok = true;
+ $tagsByKey = [];
+ $invalidatedTags = [];
+ foreach ($tags as $tag) {
+ CacheItem::validateKey($tag);
+ $invalidatedTags[$tag] = 0;
+ }
+
+ if ($this->deferred) {
+ $items = $this->deferred;
+ foreach ($items as $key => $item) {
+ if (!$this->pool->saveDeferred($item)) {
+ unset($this->deferred[$key]);
+ $ok = false;
+ }
+ }
+
+ $f = $this->getTagsByKey;
+ $tagsByKey = $f($items);
+ $this->deferred = [];
+ }
+
+ $tagVersions = $this->getTagVersions($tagsByKey, $invalidatedTags);
+ $f = $this->createCacheItem;
+
+ foreach ($tagsByKey as $key => $tags) {
+ $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
+ }
+ $ok = $this->pool->commit() && $ok;
+
+ if ($invalidatedTags) {
+ $f = $this->invalidateTags;
+ $ok = $f($this->tags, $invalidatedTags) && $ok;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ if (!$this->pool->hasItem($key)) {
+ return false;
+ }
+ if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) {
+ return true;
+ }
+
+ foreach ($this->getTagVersions([$itemTags]) as $tag => $version) {
+ if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ foreach ($this->getItems([$key]) as $item) {
+ return $item;
+ }
+
+ return null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $tagKeys = [];
+
+ foreach ($keys as $key) {
+ if ('' !== $key && \is_string($key)) {
+ $key = static::TAGS_PREFIX.$key;
+ $tagKeys[$key] = $key;
+ }
+ }
+
+ try {
+ $items = $this->pool->getItems($tagKeys + $keys);
+ } catch (InvalidArgumentException $e) {
+ $this->pool->getItems($keys); // Should throw an exception
+
+ throw $e;
+ }
+
+ return $this->generateItems($items, $tagKeys);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->deferred = [];
+
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ return $this->deleteItems([$key]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ foreach ($keys as $key) {
+ if ('' !== $key && \is_string($key)) {
+ $keys[] = static::TAGS_PREFIX.$key;
+ }
+ }
+
+ return $this->pool->deleteItems($keys);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return $this->commit();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ if (!$item instanceof CacheItem) {
+ return false;
+ }
+ $this->deferred[$item->getKey()] = $item;
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return $this->invalidateTags([]);
+ }
+
+ public function __destruct()
+ {
+ $this->commit();
+ }
+
+ private function generateItems($items, array $tagKeys)
+ {
+ $bufferedItems = $itemTags = [];
+ $f = $this->setCacheItemTags;
+
+ foreach ($items as $key => $item) {
+ if (!$tagKeys) {
+ yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags);
+ continue;
+ }
+ if (!isset($tagKeys[$key])) {
+ $bufferedItems[$key] = $item;
+ continue;
+ }
+
+ unset($tagKeys[$key]);
+ $itemTags[$key] = $item->get() ?: [];
+
+ if (!$tagKeys) {
+ $tagVersions = $this->getTagVersions($itemTags);
+
+ foreach ($itemTags as $key => $tags) {
+ foreach ($tags as $tag => $version) {
+ if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) {
+ unset($itemTags[$key]);
+ continue 2;
+ }
+ }
+ }
+ $tagVersions = $tagKeys = null;
+
+ foreach ($bufferedItems as $key => $item) {
+ yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags);
+ }
+ $bufferedItems = null;
+ }
+ }
+ }
+
+ private function getTagVersions(array $tagsByKey, array &$invalidatedTags = [])
+ {
+ $tagVersions = $invalidatedTags;
+
+ foreach ($tagsByKey as $tags) {
+ $tagVersions += $tags;
+ }
+
+ if (!$tagVersions) {
+ return [];
+ }
+
+ if (!$fetchTagVersions = 1 !== \func_num_args()) {
+ foreach ($tagsByKey as $tags) {
+ foreach ($tags as $tag => $version) {
+ if ($tagVersions[$tag] > $version) {
+ $tagVersions[$tag] = $version;
+ }
+ }
+ }
+ }
+
+ $now = microtime(true);
+ $tags = [];
+ foreach ($tagVersions as $tag => $version) {
+ $tags[$tag.static::TAGS_PREFIX] = $tag;
+ if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) {
+ $fetchTagVersions = true;
+ continue;
+ }
+ $version -= $this->knownTagVersions[$tag][1];
+ if ((0 !== $version && 1 !== $version) || $this->knownTagVersionsTtl > $now - $this->knownTagVersions[$tag][0]) {
+ // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises
+ $fetchTagVersions = true;
+ } else {
+ $this->knownTagVersions[$tag][1] += $version;
+ }
+ }
+
+ if (!$fetchTagVersions) {
+ return $tagVersions;
+ }
+
+ foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) {
+ $tagVersions[$tag = $tags[$tag]] = $version->get() ?: 0;
+ if (isset($invalidatedTags[$tag])) {
+ $invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]);
+ }
+ $this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
+ }
+
+ return $tagVersions;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
new file mode 100644
index 0000000..340048c
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php
@@ -0,0 +1,33 @@
+
+ *
+ * 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
+ *
+ * @return bool True on success
+ *
+ * @throws InvalidArgumentException When $tags is not valid
+ */
+ public function invalidateTags(array $tags);
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableAdapter.php
new file mode 100644
index 0000000..660acf5
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableAdapter.php
@@ -0,0 +1,281 @@
+
+ *
+ * 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
+ */
+class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
+{
+ protected $pool;
+ private $calls = [];
+
+ public function __construct(AdapterInterface $pool)
+ {
+ $this->pool = $pool;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get(string $key, callable $callback, float $beta = null, array &$metadata = null)
+ {
+ if (!$this->pool instanceof CacheInterface) {
+ throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', \get_class($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] = \is_object($value) ? \get_class($value) : \gettype($value);
+ } finally {
+ $event->end = microtime(true);
+ }
+ if ($isHit) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItem($key)
+ {
+ $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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->hasItem($key);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->deleteItem($key);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(CacheItemInterface $item)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$item->getKey()] = $this->pool->save($item);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function saveDeferred(CacheItemInterface $item)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$item->getKey()] = $this->pool->saveDeferred($item);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getItems(array $keys = [])
+ {
+ $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();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->clear();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ $event = $this->start(__FUNCTION__);
+ $event->result['keys'] = $keys;
+ try {
+ return $event->result['result'] = $this->pool->deleteItems($keys);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->commit();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ if (!$this->pool instanceof PruneableInterface) {
+ return false;
+ }
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->prune();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if (!$this->pool instanceof ResetInterface) {
+ return;
+ }
+ $event = $this->start(__FUNCTION__);
+ try {
+ $this->pool->reset();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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()
+ {
+ return $this->calls;
+ }
+
+ public function clearCalls()
+ {
+ $this->calls = [];
+ }
+
+ protected function start($name)
+ {
+ $this->calls[] = $event = new TraceableAdapterEvent();
+ $event->name = $name;
+ $event->start = microtime(true);
+
+ return $event;
+ }
+}
+
+class TraceableAdapterEvent
+{
+ public $name;
+ public $start;
+ public $end;
+ public $result;
+ public $hits = 0;
+ public $misses = 0;
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
new file mode 100644
index 0000000..69461b8
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php
@@ -0,0 +1,38 @@
+
+ *
+ * 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
+ */
+final class CacheItem implements ItemInterface
+{
+ private const METADATA_EXPIRY_OFFSET = 1527506807;
+
+ protected $key;
+ protected $value;
+ protected $isHit = false;
+ protected $expiry;
+ protected $defaultLifetime;
+ protected $metadata = [];
+ protected $newMetadata = [];
+ protected $innerItem;
+ protected $poolHash;
+ protected $isTaggable = false;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get()
+ {
+ return $this->value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isHit()
+ {
+ return $this->isHit;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function set($value)
+ {
+ $this->value = $value;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function expiresAt($expiration)
+ {
+ if (null === $expiration) {
+ $this->expiry = $this->defaultLifetime > 0 ? microtime(true) + $this->defaultLifetime : null;
+ } elseif ($expiration instanceof \DateTimeInterface) {
+ $this->expiry = (float) $expiration->format('U.u');
+ } else {
+ throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given', \is_object($expiration) ? \get_class($expiration) : \gettype($expiration)));
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return $this
+ */
+ public function expiresAfter($time)
+ {
+ if (null === $time) {
+ $this->expiry = $this->defaultLifetime > 0 ? microtime(true) + $this->defaultLifetime : null;
+ } elseif ($time instanceof \DateInterval) {
+ $this->expiry = microtime(true) + \DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+ } elseif (\is_int($time)) {
+ $this->expiry = $time + microtime(true);
+ } else {
+ throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', \is_object($time) ? \get_class($time) : \gettype($time)));
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function tag($tags): ItemInterface
+ {
+ if (!$this->isTaggable) {
+ throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
+ }
+ if (!is_iterable($tags)) {
+ $tags = [$tags];
+ }
+ foreach ($tags as $tag) {
+ if (!\is_string($tag)) {
+ throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', \is_object($tag) ? \get_class($tag) : \gettype($tag)));
+ }
+ if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
+ continue;
+ }
+ if ('' === $tag) {
+ throw new InvalidArgumentException('Cache tag length must be greater than zero');
+ }
+ if (false !== strpbrk($tag, '{}()/\@:')) {
+ throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:', $tag));
+ }
+ $this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata(): array
+ {
+ return $this->metadata;
+ }
+
+ /**
+ * Returns the list of tags bound to the value coming from the pool storage if any.
+ *
+ * @return array
+ *
+ * @deprecated since Symfony 4.2, use the "getMetadata()" method instead.
+ */
+ public function getPreviousTags()
+ {
+ @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "getMetadata()" method instead.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->metadata[self::METADATA_TAGS] ?? [];
+ }
+
+ /**
+ * Validates a cache key according to PSR-6.
+ *
+ * @param string $key The key to validate
+ *
+ * @return string
+ *
+ * @throws InvalidArgumentException When $key is not valid
+ */
+ public static function validateKey($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if ('' === $key) {
+ throw new InvalidArgumentException('Cache key length must be greater than zero');
+ }
+ if (false !== strpbrk($key, '{}()/\@:')) {
+ throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key));
+ }
+
+ return $key;
+ }
+
+ /**
+ * Internal logging helper.
+ *
+ * @internal
+ */
+ public static function log(LoggerInterface $logger = null, $message, $context = [])
+ {
+ if ($logger) {
+ $logger->warning($message, $context);
+ } else {
+ $replace = [];
+ foreach ($context as $k => $v) {
+ if (is_scalar($v)) {
+ $replace['{'.$k.'}'] = $v;
+ }
+ }
+ @trigger_error(strtr($message, $replace), E_USER_WARNING);
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/DataCollector/CacheDataCollector.php b/addons/weliam_smartcity/vendor/symfony/cache/DataCollector/CacheDataCollector.php
new file mode 100644
index 0000000..1ac7029
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/DataCollector/CacheDataCollector.php
@@ -0,0 +1,190 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\DataCollector;
+
+use Symfony\Component\Cache\Adapter\TraceableAdapter;
+use Symfony\Component\Cache\Adapter\TraceableAdapterEvent;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
+
+/**
+ * @author Aaron Scherer
+ */
+class CachePoolClearerPass implements CompilerPassInterface
+{
+ private $cachePoolClearerTag;
+
+ public function __construct(string $cachePoolClearerTag = 'cache.pool.clearer')
+ {
+ $this->cachePoolClearerTag = $cachePoolClearerTag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ $container->getParameterBag()->remove('cache.prefix.seed');
+
+ foreach ($container->findTaggedServiceIds($this->cachePoolClearerTag) as $id => $attr) {
+ $clearer = $container->getDefinition($id);
+ $pools = [];
+ foreach ($clearer->getArgument(0) as $name => $ref) {
+ if ($container->hasDefinition($ref)) {
+ $pools[$name] = new Reference($ref);
+ }
+ }
+ $clearer->replaceArgument(0, $pools);
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPass.php b/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
new file mode 100644
index 0000000..5d7a236
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPass.php
@@ -0,0 +1,177 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\DependencyInjection;
+
+use Symfony\Component\Cache\Adapter\AbstractAdapter;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\DependencyInjection\ChildDefinition;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * @author Nicolas Grekas
+ */
+class CachePoolPass implements CompilerPassInterface
+{
+ private $cachePoolTag;
+ private $kernelResetTag;
+ private $cacheClearerId;
+ private $cachePoolClearerTag;
+ private $cacheSystemClearerId;
+ private $cacheSystemClearerTag;
+
+ public function __construct(string $cachePoolTag = 'cache.pool', string $kernelResetTag = 'kernel.reset', string $cacheClearerId = 'cache.global_clearer', string $cachePoolClearerTag = 'cache.pool.clearer', string $cacheSystemClearerId = 'cache.system_clearer', string $cacheSystemClearerTag = 'kernel.cache_clearer')
+ {
+ $this->cachePoolTag = $cachePoolTag;
+ $this->kernelResetTag = $kernelResetTag;
+ $this->cacheClearerId = $cacheClearerId;
+ $this->cachePoolClearerTag = $cachePoolClearerTag;
+ $this->cacheSystemClearerId = $cacheSystemClearerId;
+ $this->cacheSystemClearerTag = $cacheSystemClearerTag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if ($container->hasParameter('cache.prefix.seed')) {
+ $seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed'));
+ } else {
+ $seed = '_'.$container->getParameter('kernel.project_dir');
+ }
+ $seed .= '.'.$container->getParameter('kernel.container_class');
+
+ $pools = [];
+ $clearers = [];
+ $attributes = [
+ 'provider',
+ 'name',
+ 'namespace',
+ 'default_lifetime',
+ 'reset',
+ ];
+ foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $tags) {
+ $adapter = $pool = $container->getDefinition($id);
+ if ($pool->isAbstract()) {
+ continue;
+ }
+ $class = $adapter->getClass();
+ while ($adapter instanceof ChildDefinition) {
+ $adapter = $container->findDefinition($adapter->getParent());
+ $class = $class ?: $adapter->getClass();
+ if ($t = $adapter->getTag($this->cachePoolTag)) {
+ $tags[0] += $t[0];
+ }
+ }
+ $name = $tags[0]['name'] ?? $id;
+ if (!isset($tags[0]['namespace'])) {
+ if (null !== $class) {
+ $seed .= '.'.$class;
+ }
+
+ $tags[0]['namespace'] = $this->getNamespace($seed, $name);
+ }
+ if (isset($tags[0]['clearer'])) {
+ $clearer = $tags[0]['clearer'];
+ while ($container->hasAlias($clearer)) {
+ $clearer = (string) $container->getAlias($clearer);
+ }
+ } else {
+ $clearer = null;
+ }
+ unset($tags[0]['clearer'], $tags[0]['name']);
+
+ if (isset($tags[0]['provider'])) {
+ $tags[0]['provider'] = new Reference(static::getServiceProvider($container, $tags[0]['provider']));
+ }
+ $i = 0;
+ foreach ($attributes as $attr) {
+ if (!isset($tags[0][$attr])) {
+ // no-op
+ } elseif ('reset' === $attr) {
+ if ($tags[0][$attr]) {
+ $pool->addTag($this->kernelResetTag, ['method' => $tags[0][$attr]]);
+ }
+ } elseif ('namespace' !== $attr || ArrayAdapter::class !== $adapter->getClass()) {
+ $pool->replaceArgument($i++, $tags[0][$attr]);
+ }
+ unset($tags[0][$attr]);
+ }
+ if (!empty($tags[0])) {
+ throw new InvalidArgumentException(sprintf('Invalid "%s" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime" and "reset", found "%s".', $this->cachePoolTag, $id, implode('", "', array_keys($tags[0]))));
+ }
+
+ if (null !== $clearer) {
+ $clearers[$clearer][$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
+ }
+
+ $pools[$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
+ }
+
+ $notAliasedCacheClearerId = $this->cacheClearerId;
+ while ($container->hasAlias($this->cacheClearerId)) {
+ $this->cacheClearerId = (string) $container->getAlias($this->cacheClearerId);
+ }
+ if ($container->hasDefinition($this->cacheClearerId)) {
+ $clearers[$notAliasedCacheClearerId] = $pools;
+ }
+
+ foreach ($clearers as $id => $pools) {
+ $clearer = $container->getDefinition($id);
+ if ($clearer instanceof ChildDefinition) {
+ $clearer->replaceArgument(0, $pools);
+ } else {
+ $clearer->setArgument(0, $pools);
+ }
+ $clearer->addTag($this->cachePoolClearerTag);
+
+ if ($this->cacheSystemClearerId === $id) {
+ $clearer->addTag($this->cacheSystemClearerTag);
+ }
+ }
+
+ if ($container->hasDefinition('console.command.cache_pool_list')) {
+ $container->getDefinition('console.command.cache_pool_list')->replaceArgument(0, array_keys($pools));
+ }
+ }
+
+ private function getNamespace($seed, $id)
+ {
+ return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$seed, true))), 0, 10);
+ }
+
+ /**
+ * @internal
+ */
+ public static function getServiceProvider(ContainerBuilder $container, $name)
+ {
+ $container->resolveEnvPlaceholders($name, null, $usedEnvs);
+
+ if ($usedEnvs || preg_match('#^[a-z]++:#', $name)) {
+ $dsn = $name;
+
+ if (!$container->hasDefinition($name = '.cache_connection.'.ContainerBuilder::hash($dsn))) {
+ $definition = new Definition(AbstractAdapter::class);
+ $definition->setPublic(false);
+ $definition->setFactory([AbstractAdapter::class, 'createConnection']);
+ $definition->setArguments([$dsn, ['lazy' => true]]);
+ $container->setDefinition($name, $definition);
+ }
+ }
+
+ return $name;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php b/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php
new file mode 100644
index 0000000..e569962
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/DependencyInjection/CachePoolPrunerPass.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\DependencyInjection;
+
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * @author Rob Frawley 2nd
+ */
+class DoctrineProvider extends CacheProvider implements PruneableInterface, ResettableInterface
+{
+ private $pool;
+
+ public function __construct(CacheItemPoolInterface $pool)
+ {
+ $this->pool = $pool;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ return $this->pool instanceof PruneableInterface && $this->pool->prune();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+ $this->setNamespace($this->getNamespace());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch($id)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+
+ return $item->isHit() ? $item->get() : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doContains($id)
+ {
+ return $this->pool->hasItem(rawurlencode($id));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave($id, $data, $lifeTime = 0)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+
+ if (0 < $lifeTime) {
+ $item->expiresAfter($lifeTime);
+ }
+
+ return $this->pool->save($item->set($data));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete($id)
+ {
+ return $this->pool->deleteItem(rawurlencode($id));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFlush()
+ {
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doGetStats()
+ {
+ return null;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Exception/CacheException.php b/addons/weliam_smartcity/vendor/symfony/cache/Exception/CacheException.php
new file mode 100644
index 0000000..d2e975b
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Exception/CacheException.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Exception;
+
+use Psr\Cache\CacheException as Psr6CacheInterface;
+use Psr\SimpleCache\CacheException as SimpleCacheInterface;
+
+if (interface_exists(SimpleCacheInterface::class)) {
+ class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class CacheException extends \Exception implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Exception/InvalidArgumentException.php b/addons/weliam_smartcity/vendor/symfony/cache/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..7f9584a
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Exception/InvalidArgumentException.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Exception;
+
+use Psr\Cache\InvalidArgumentException as Psr6CacheInterface;
+use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface;
+
+if (interface_exists(SimpleCacheInterface::class)) {
+ class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Exception/LogicException.php b/addons/weliam_smartcity/vendor/symfony/cache/Exception/LogicException.php
new file mode 100644
index 0000000..9ffa7ed
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Exception/LogicException.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Exception;
+
+use Psr\Cache\CacheException as Psr6CacheInterface;
+use Psr\SimpleCache\CacheException as SimpleCacheInterface;
+
+if (interface_exists(SimpleCacheInterface::class)) {
+ class LogicException extends \LogicException implements Psr6CacheInterface, SimpleCacheInterface
+ {
+ }
+} else {
+ class LogicException extends \LogicException implements Psr6CacheInterface
+ {
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/LICENSE b/addons/weliam_smartcity/vendor/symfony/cache/LICENSE
new file mode 100644
index 0000000..3c464ca
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2016-2019 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/LockRegistry.php b/addons/weliam_smartcity/vendor/symfony/cache/LockRegistry.php
new file mode 100644
index 0000000..676fba5
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/LockRegistry.php
@@ -0,0 +1,150 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Contracts\Cache\CacheInterface;
+use Symfony\Contracts\Cache\ItemInterface;
+
+/**
+ * LockRegistry is used internally by existing adapters to protect against cache stampede.
+ *
+ * It does so by wrapping the computation of items in a pool of locks.
+ * Foreach each apps, there can be at most 20 concurrent processes that
+ * compute items at the same time and only one per cache-key.
+ *
+ * @author Nicolas Grekas
+ */
+final class LockRegistry
+{
+ private static $openedFiles = [];
+ private static $lockedFiles = [];
+
+ /**
+ * The number of items in this list controls the max number of concurrent processes.
+ */
+ private static $files = [
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AbstractTagAwareAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'AdapterInterface.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ApcuAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ArrayAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ChainAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'DoctrineAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'FilesystemTagAwareAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'MemcachedAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'NullAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PdoAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpArrayAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'PhpFilesAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'ProxyAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'Psr16Adapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'RedisTagAwareAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'SimpleCacheAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TagAwareAdapterInterface.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableAdapter.php',
+ __DIR__.\DIRECTORY_SEPARATOR.'Adapter'.\DIRECTORY_SEPARATOR.'TraceableTagAwareAdapter.php',
+ ];
+
+ /**
+ * Defines a set of existing files that will be used as keys to acquire locks.
+ *
+ * @return array The previously defined set of files
+ */
+ public static function setFiles(array $files): array
+ {
+ $previousFiles = self::$files;
+ self::$files = $files;
+
+ foreach (self::$openedFiles as $file) {
+ if ($file) {
+ flock($file, LOCK_UN);
+ fclose($file);
+ }
+ }
+ self::$openedFiles = self::$lockedFiles = [];
+
+ return $previousFiles;
+ }
+
+ public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
+ {
+ $key = self::$files ? crc32($item->getKey()) % \count(self::$files) : -1;
+
+ if ($key < 0 || (self::$lockedFiles[$key] ?? false) || !$lock = self::open($key)) {
+ return $callback($item, $save);
+ }
+
+ while (true) {
+ try {
+ // race to get the lock in non-blocking mode
+ if (flock($lock, LOCK_EX | LOCK_NB)) {
+ $logger && $logger->info('Lock acquired, now computing item "{key}"', ['key' => $item->getKey()]);
+ self::$lockedFiles[$key] = true;
+
+ $value = $callback($item, $save);
+
+ if ($save) {
+ if ($setMetadata) {
+ $setMetadata($item);
+ }
+
+ $pool->save($item->set($value));
+ $save = false;
+ }
+
+ return $value;
+ }
+ // if we failed the race, retry locking in blocking mode to wait for the winner
+ $logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
+ flock($lock, LOCK_SH);
+ } finally {
+ flock($lock, LOCK_UN);
+ unset(self::$lockedFiles[$key]);
+ }
+ static $signalingException, $signalingCallback;
+ $signalingException = $signalingException ?? unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
+ $signalingCallback = $signalingCallback ?? function () use ($signalingException) { throw $signalingException; };
+
+ try {
+ $value = $pool->get($item->getKey(), $signalingCallback, 0);
+ $logger && $logger->info('Item "{key}" retrieved after lock was released', ['key' => $item->getKey()]);
+ $save = false;
+
+ return $value;
+ } catch (\Exception $e) {
+ if ($signalingException !== $e) {
+ throw $e;
+ }
+ $logger && $logger->info('Item "{key}" not found while lock was released, now retrying', ['key' => $item->getKey()]);
+ }
+ }
+ }
+
+ private static function open(int $key)
+ {
+ if (null !== $h = self::$openedFiles[$key] ?? null) {
+ return $h;
+ }
+ set_error_handler(function () {});
+ try {
+ $h = fopen(self::$files[$key], 'r+');
+ } finally {
+ restore_error_handler();
+ }
+
+ return self::$openedFiles[$key] = $h ?: @fopen(self::$files[$key], 'r');
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/DefaultMarshaller.php b/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/DefaultMarshaller.php
new file mode 100644
index 0000000..9c1ef46
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/DefaultMarshaller.php
@@ -0,0 +1,99 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Marshaller;
+
+use Symfony\Component\Cache\Exception\CacheException;
+
+/**
+ * Serializes/unserializes values using igbinary_serialize() if available, serialize() otherwise.
+ *
+ * @author Nicolas Grekas
+ */
+class DefaultMarshaller implements MarshallerInterface
+{
+ private $useIgbinarySerialize = true;
+
+ public function __construct(bool $useIgbinarySerialize = null)
+ {
+ if (null === $useIgbinarySerialize) {
+ $useIgbinarySerialize = \extension_loaded('igbinary');
+ } elseif ($useIgbinarySerialize && !\extension_loaded('igbinary')) {
+ throw new CacheException('The "igbinary" PHP extension is not loaded.');
+ }
+ $this->useIgbinarySerialize = $useIgbinarySerialize;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function marshall(array $values, ?array &$failed): array
+ {
+ $serialized = $failed = [];
+
+ foreach ($values as $id => $value) {
+ try {
+ if ($this->useIgbinarySerialize) {
+ $serialized[$id] = igbinary_serialize($value);
+ } else {
+ $serialized[$id] = serialize($value);
+ }
+ } catch (\Exception $e) {
+ $failed[] = $id;
+ }
+ }
+
+ return $serialized;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unmarshall(string $value)
+ {
+ if ('b:0;' === $value) {
+ return false;
+ }
+ if ('N;' === $value) {
+ return null;
+ }
+ static $igbinaryNull;
+ if ($value === ($igbinaryNull ?? $igbinaryNull = \extension_loaded('igbinary') ? igbinary_serialize(null) : false)) {
+ return null;
+ }
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
+ try {
+ if (':' === ($value[1] ?? ':')) {
+ if (false !== $value = unserialize($value)) {
+ return $value;
+ }
+ } elseif (false === $igbinaryNull) {
+ throw new \RuntimeException('Failed to unserialize values, did you forget to install the "igbinary" extension?');
+ } elseif (null !== $value = igbinary_unserialize($value)) {
+ return $value;
+ }
+
+ throw new \DomainException(error_get_last() ? error_get_last()['message'] : 'Failed to unserialize values.');
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+
+ /**
+ * @internal
+ */
+ public static function handleUnserializeCallback($class)
+ {
+ throw new \DomainException('Class not found: '.$class);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/MarshallerInterface.php b/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/MarshallerInterface.php
new file mode 100644
index 0000000..cdd6c40
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Marshaller/MarshallerInterface.php
@@ -0,0 +1,40 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Marshaller;
+
+/**
+ * Serializes/unserializes PHP values.
+ *
+ * Implementations of this interface MUST deal with errors carefully. They MUST
+ * also deal with forward and backward compatibility at the storage format level.
+ *
+ * @author Nicolas Grekas
+ */
+interface MarshallerInterface
+{
+ /**
+ * Serializes a list of values.
+ *
+ * When serialization fails for a specific value, no exception should be
+ * thrown. Instead, its key should be listed in $failed.
+ */
+ public function marshall(array $values, ?array &$failed): array;
+
+ /**
+ * Unserializes a single value and throws an exception if anything goes wrong.
+ *
+ * @return mixed
+ *
+ * @throws \Exception Whenever unserialization fails
+ */
+ public function unmarshall(string $value);
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/PruneableInterface.php b/addons/weliam_smartcity/vendor/symfony/cache/PruneableInterface.php
new file mode 100644
index 0000000..4261525
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/PruneableInterface.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache;
+
+/**
+ * Interface extends psr-6 and psr-16 caches to allow for pruning (deletion) of all expired cache items.
+ */
+interface PruneableInterface
+{
+ /**
+ * @return bool
+ */
+ public function prune();
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Psr16Cache.php b/addons/weliam_smartcity/vendor/symfony/cache/Psr16Cache.php
new file mode 100644
index 0000000..d67615e
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Psr16Cache.php
@@ -0,0 +1,263 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache;
+
+use Psr\Cache\CacheException as Psr6CacheException;
+use Psr\Cache\CacheItemPoolInterface;
+use Psr\SimpleCache\CacheException as SimpleCacheException;
+use Psr\SimpleCache\CacheInterface;
+use Symfony\Component\Cache\Adapter\AdapterInterface;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\Traits\ProxyTrait;
+
+/**
+ * Turns a PSR-6 cache into a PSR-16 one.
+ *
+ * @author Nicolas Grekas
+ */
+class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterface
+{
+ use ProxyTrait;
+
+ private const METADATA_EXPIRY_OFFSET = 1527506807;
+
+ private $createCacheItem;
+ private $cacheItemPrototype;
+
+ public function __construct(CacheItemPoolInterface $pool)
+ {
+ $this->pool = $pool;
+
+ if (!$pool instanceof AdapterInterface) {
+ return;
+ }
+ $cacheItemPrototype = &$this->cacheItemPrototype;
+ $createCacheItem = \Closure::bind(
+ static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
+ $item = clone $cacheItemPrototype;
+ $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
+ $item->value = $value;
+ $item->isHit = false;
+
+ return $item;
+ },
+ null,
+ CacheItem::class
+ );
+ $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
+ if (null === $this->cacheItemPrototype) {
+ $this->get($allowInt && \is_int($key) ? (string) $key : $key);
+ }
+ $this->createCacheItem = $createCacheItem;
+
+ return $createCacheItem($key, null, $allowInt)->set($value);
+ };
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ try {
+ $item = $this->pool->getItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ if (null === $this->cacheItemPrototype) {
+ $this->cacheItemPrototype = clone $item;
+ $this->cacheItemPrototype->set(null);
+ }
+
+ return $item->isHit() ? $item->get() : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ try {
+ if (null !== $f = $this->createCacheItem) {
+ $item = $f($key, $value);
+ } else {
+ $item = $this->pool->getItem($key)->set($value);
+ }
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ if (null !== $ttl) {
+ $item->expiresAfter($ttl);
+ }
+
+ return $this->pool->save($item);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ try {
+ return $this->pool->deleteItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+
+ try {
+ $items = $this->pool->getItems($keys);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ $values = [];
+
+ if (!$this->pool instanceof AdapterInterface) {
+ foreach ($items as $key => $item) {
+ $values[$key] = $item->isHit() ? $item->get() : $default;
+ }
+
+ return $values;
+ }
+
+ foreach ($items as $key => $item) {
+ if (!$item->isHit()) {
+ $values[$key] = $default;
+ continue;
+ }
+ $values[$key] = $item->get();
+
+ if (!$metadata = $item->getMetadata()) {
+ continue;
+ }
+ unset($metadata[CacheItem::METADATA_TAGS]);
+
+ if ($metadata) {
+ $values[$key] = ["\x9D".pack('VN', (int) $metadata[CacheItem::METADATA_EXPIRY] - self::METADATA_EXPIRY_OFFSET, $metadata[CacheItem::METADATA_CTIME])."\x5F" => $values[$key]];
+ }
+ }
+
+ return $values;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ $valuesIsArray = \is_array($values);
+ if (!$valuesIsArray && !$values instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
+ }
+ $items = [];
+
+ try {
+ if (null !== $f = $this->createCacheItem) {
+ $valuesIsArray = false;
+ foreach ($values as $key => $value) {
+ $items[$key] = $f($key, $value, true);
+ }
+ } elseif ($valuesIsArray) {
+ $items = [];
+ foreach ($values as $key => $value) {
+ $items[] = (string) $key;
+ }
+ $items = $this->pool->getItems($items);
+ } else {
+ foreach ($values as $key => $value) {
+ if (\is_int($key)) {
+ $key = (string) $key;
+ }
+ $items[$key] = $this->pool->getItem($key)->set($value);
+ }
+ }
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ $ok = true;
+
+ foreach ($items as $key => $item) {
+ if ($valuesIsArray) {
+ $item->set($values[$key]);
+ }
+ if (null !== $ttl) {
+ $item->expiresAfter($ttl);
+ }
+ $ok = $this->pool->saveDeferred($item) && $ok;
+ }
+
+ return $this->pool->commit() && $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+
+ try {
+ return $this->pool->deleteItems($keys);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ try {
+ return $this->pool->hasItem($key);
+ } catch (SimpleCacheException $e) {
+ throw $e;
+ } catch (Psr6CacheException $e) {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/README.md b/addons/weliam_smartcity/vendor/symfony/cache/README.md
new file mode 100644
index 0000000..c4ab752
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/README.md
@@ -0,0 +1,18 @@
+Symfony PSR-6 implementation for caching
+========================================
+
+This component provides an extended [PSR-6](http://www.php-fig.org/psr/psr-6/)
+implementation for adding cache to your applications. It is designed to have a
+low overhead so that caching is fastest. It ships with a few caching adapters
+for the most widespread and suited to caching backends. It also provides a
+`doctrine/cache` proxy adapter to cover more advanced caching needs and a proxy
+adapter for greater interoperability between PSR-6 implementations.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/cache.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/ResettableInterface.php b/addons/weliam_smartcity/vendor/symfony/cache/ResettableInterface.php
new file mode 100644
index 0000000..7b0a853
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/ResettableInterface.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache;
+
+use Symfony\Contracts\Service\ResetInterface;
+
+/**
+ * Resets a pool's local state.
+ */
+interface ResettableInterface extends ResetInterface
+{
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/AbstractCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/AbstractCache.php
new file mode 100644
index 0000000..af46bf3
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/AbstractCache.php
@@ -0,0 +1,191 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\Log\LoggerAwareInterface;
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Component\Cache\Adapter\AbstractAdapter;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Component\Cache\Traits\AbstractTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', AbstractCache::class, AbstractAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use AbstractAdapter and type-hint for CacheInterface instead.
+ */
+abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
+{
+ /**
+ * @internal
+ */
+ protected const NS_SEPARATOR = ':';
+
+ use AbstractTrait {
+ deleteItems as private;
+ AbstractTrait::deleteItem as delete;
+ AbstractTrait::hasItem as has;
+ }
+
+ private $defaultLifetime;
+
+ protected function __construct(string $namespace = '', int $defaultLifetime = 0)
+ {
+ $this->defaultLifetime = max(0, $defaultLifetime);
+ $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
+ if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
+ throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, \strlen($namespace), $namespace));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ $id = $this->getId($key);
+
+ try {
+ foreach ($this->doFetch([$id]) as $value) {
+ return $value;
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
+ }
+
+ return $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ CacheItem::validateKey($key);
+
+ return $this->setMultiple([$key => $value], $ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+ $ids = [];
+
+ foreach ($keys as $key) {
+ $ids[] = $this->getId($key);
+ }
+ try {
+ $values = $this->doFetch($ids);
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
+ $values = [];
+ }
+ $ids = array_combine($ids, $keys);
+
+ return $this->generateValues($values, $ids, $default);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ if (!\is_array($values) && !$values instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
+ }
+ $valuesById = [];
+
+ foreach ($values as $key => $value) {
+ if (\is_int($key)) {
+ $key = (string) $key;
+ }
+ $valuesById[$this->getId($key)] = $value;
+ }
+ if (false === $ttl = $this->normalizeTtl($ttl)) {
+ return $this->doDelete(array_keys($valuesById));
+ }
+
+ try {
+ $e = $this->doSave($valuesById, $ttl);
+ } catch (\Exception $e) {
+ }
+ if (true === $e || [] === $e) {
+ return true;
+ }
+ $keys = [];
+ foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) {
+ $keys[] = substr($id, \strlen($this->namespace));
+ }
+ $message = 'Failed to save values'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+
+ return $this->deleteItems($keys);
+ }
+
+ private function normalizeTtl($ttl)
+ {
+ if (null === $ttl) {
+ return $this->defaultLifetime;
+ }
+ if ($ttl instanceof \DateInterval) {
+ $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
+ }
+ if (\is_int($ttl)) {
+ return 0 < $ttl ? $ttl : false;
+ }
+
+ throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl)));
+ }
+
+ private function generateValues($values, &$keys, $default)
+ {
+ try {
+ foreach ($values as $id => $value) {
+ if (!isset($keys[$id])) {
+ $id = key($keys);
+ }
+ $key = $keys[$id];
+ unset($keys[$id]);
+ yield $key => $value;
+ }
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
+ }
+
+ foreach ($keys as $key) {
+ yield $key => $default;
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/ApcuCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ApcuCache.php
new file mode 100644
index 0000000..c22771e
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ApcuCache.php
@@ -0,0 +1,29 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Traits\ApcuTrait;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ApcuCache::class, ApcuAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use ApcuAdapter and type-hint for CacheInterface instead.
+ */
+class ApcuCache extends AbstractCache
+{
+ use ApcuTrait;
+
+ public function __construct(string $namespace = '', int $defaultLifetime = 0, string $version = null)
+ {
+ $this->init($namespace, $defaultLifetime, $version);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/ArrayCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ArrayCache.php
new file mode 100644
index 0000000..5cd228f
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ArrayCache.php
@@ -0,0 +1,159 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\Log\LoggerAwareInterface;
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Component\Cache\Traits\ArrayTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ArrayCache::class, ArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use ArrayAdapter and type-hint for CacheInterface instead.
+ */
+class ArrayCache implements Psr16CacheInterface, LoggerAwareInterface, ResettableInterface
+{
+ use ArrayTrait {
+ ArrayTrait::deleteItem as delete;
+ ArrayTrait::hasItem as has;
+ }
+
+ private $defaultLifetime;
+
+ /**
+ * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise
+ */
+ public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true)
+ {
+ $this->defaultLifetime = $defaultLifetime;
+ $this->storeSerialized = $storeSerialized;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ if (!\is_string($key) || !isset($this->expiries[$key])) {
+ CacheItem::validateKey($key);
+ }
+ if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > microtime(true) || !$this->delete($key))) {
+ $this->values[$key] = null;
+
+ return $default;
+ }
+ if (!$this->storeSerialized) {
+ return $this->values[$key];
+ }
+ $value = $this->unfreeze($key, $isHit);
+
+ return $isHit ? $value : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+ foreach ($keys as $key) {
+ if (!\is_string($key) || !isset($this->expiries[$key])) {
+ CacheItem::validateKey($key);
+ }
+ }
+
+ return $this->generateItems($keys, microtime(true), function ($k, $v, $hit) use ($default) { return $hit ? $v : $default; });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ if (!\is_array($keys) && !$keys instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+ foreach ($keys as $key) {
+ $this->delete($key);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ if (!\is_string($key)) {
+ CacheItem::validateKey($key);
+ }
+
+ return $this->setMultiple([$key => $value], $ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ if (!\is_array($values) && !$values instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
+ }
+ $valuesArray = [];
+
+ foreach ($values as $key => $value) {
+ if (!\is_int($key) && !(\is_string($key) && isset($this->expiries[$key]))) {
+ CacheItem::validateKey($key);
+ }
+ $valuesArray[$key] = $value;
+ }
+ if (false === $ttl = $this->normalizeTtl($ttl)) {
+ return $this->deleteMultiple(array_keys($valuesArray));
+ }
+ $expiry = 0 < $ttl ? microtime(true) + $ttl : PHP_INT_MAX;
+
+ foreach ($valuesArray as $key => $value) {
+ if ($this->storeSerialized && null === $value = $this->freeze($value, $key)) {
+ return false;
+ }
+ $this->values[$key] = $value;
+ $this->expiries[$key] = $expiry;
+ }
+
+ return true;
+ }
+
+ private function normalizeTtl($ttl)
+ {
+ if (null === $ttl) {
+ return $this->defaultLifetime;
+ }
+ if ($ttl instanceof \DateInterval) {
+ $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U');
+ }
+ if (\is_int($ttl)) {
+ return 0 < $ttl ? $ttl : false;
+ }
+
+ throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl)));
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/ChainCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ChainCache.php
new file mode 100644
index 0000000..a0122fd
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/ChainCache.php
@@ -0,0 +1,257 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Component\Cache\Adapter\ChainAdapter;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Contracts\Cache\CacheInterface;
+use Symfony\Contracts\Service\ResetInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', ChainCache::class, ChainAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * Chains several caches together.
+ *
+ * Cached items are fetched from the first cache having them in its data store.
+ * They are saved and deleted in all caches at once.
+ *
+ * @deprecated since Symfony 4.3, use ChainAdapter and type-hint for CacheInterface instead.
+ */
+class ChainCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
+{
+ private $miss;
+ private $caches = [];
+ private $defaultLifetime;
+ private $cacheCount;
+
+ /**
+ * @param Psr16CacheInterface[] $caches The ordered list of caches used to fetch cached items
+ * @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones
+ */
+ public function __construct(array $caches, int $defaultLifetime = 0)
+ {
+ if (!$caches) {
+ throw new InvalidArgumentException('At least one cache must be specified.');
+ }
+
+ foreach ($caches as $cache) {
+ if (!$cache instanceof Psr16CacheInterface) {
+ throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), Psr16CacheInterface::class));
+ }
+ }
+
+ $this->miss = new \stdClass();
+ $this->caches = array_values($caches);
+ $this->cacheCount = \count($this->caches);
+ $this->defaultLifetime = 0 < $defaultLifetime ? $defaultLifetime : null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ $miss = null !== $default && \is_object($default) ? $default : $this->miss;
+
+ foreach ($this->caches as $i => $cache) {
+ $value = $cache->get($key, $miss);
+
+ if ($miss !== $value) {
+ while (0 <= --$i) {
+ $this->caches[$i]->set($key, $value, $this->defaultLifetime);
+ }
+
+ return $value;
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ $miss = null !== $default && \is_object($default) ? $default : $this->miss;
+
+ return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default);
+ }
+
+ private function generateItems($values, $cacheIndex, $miss, $default)
+ {
+ $missing = [];
+ $nextCacheIndex = $cacheIndex + 1;
+ $nextCache = isset($this->caches[$nextCacheIndex]) ? $this->caches[$nextCacheIndex] : null;
+
+ foreach ($values as $k => $value) {
+ if ($miss !== $value) {
+ yield $k => $value;
+ } elseif (!$nextCache) {
+ yield $k => $default;
+ } else {
+ $missing[] = $k;
+ }
+ }
+
+ if ($missing) {
+ $cache = $this->caches[$cacheIndex];
+ $values = $this->generateItems($nextCache->getMultiple($missing, $miss), $nextCacheIndex, $miss, $default);
+
+ foreach ($values as $k => $value) {
+ if ($miss !== $value) {
+ $cache->set($k, $value, $this->defaultLifetime);
+ yield $k => $value;
+ } else {
+ yield $k => $default;
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ foreach ($this->caches as $cache) {
+ if ($cache->has($key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $cleared = true;
+ $i = $this->cacheCount;
+
+ while ($i--) {
+ $cleared = $this->caches[$i]->clear() && $cleared;
+ }
+
+ return $cleared;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ $deleted = true;
+ $i = $this->cacheCount;
+
+ while ($i--) {
+ $deleted = $this->caches[$i]->delete($key) && $deleted;
+ }
+
+ return $deleted;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ }
+ $deleted = true;
+ $i = $this->cacheCount;
+
+ while ($i--) {
+ $deleted = $this->caches[$i]->deleteMultiple($keys) && $deleted;
+ }
+
+ return $deleted;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ $saved = true;
+ $i = $this->cacheCount;
+
+ while ($i--) {
+ $saved = $this->caches[$i]->set($key, $value, $ttl) && $saved;
+ }
+
+ return $saved;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ if ($values instanceof \Traversable) {
+ $valuesIterator = $values;
+ $values = function () use ($valuesIterator, &$values) {
+ $generatedValues = [];
+
+ foreach ($valuesIterator as $key => $value) {
+ yield $key => $value;
+ $generatedValues[$key] = $value;
+ }
+
+ $values = $generatedValues;
+ };
+ $values = $values();
+ }
+ $saved = true;
+ $i = $this->cacheCount;
+
+ while ($i--) {
+ $saved = $this->caches[$i]->setMultiple($values, $ttl) && $saved;
+ }
+
+ return $saved;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ $pruned = true;
+
+ foreach ($this->caches as $cache) {
+ if ($cache instanceof PruneableInterface) {
+ $pruned = $cache->prune() && $pruned;
+ }
+ }
+
+ return $pruned;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ foreach ($this->caches as $cache) {
+ if ($cache instanceof ResetInterface) {
+ $cache->reset();
+ }
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/DoctrineCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/DoctrineCache.php
new file mode 100644
index 0000000..6a6d003
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/DoctrineCache.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Doctrine\Common\Cache\CacheProvider;
+use Symfony\Component\Cache\Adapter\DoctrineAdapter;
+use Symfony\Component\Cache\Traits\DoctrineTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', DoctrineCache::class, DoctrineAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use DoctrineAdapter and type-hint for CacheInterface instead.
+ */
+class DoctrineCache extends AbstractCache
+{
+ use DoctrineTrait;
+
+ public function __construct(CacheProvider $provider, string $namespace = '', int $defaultLifetime = 0)
+ {
+ parent::__construct('', $defaultLifetime);
+ $this->provider = $provider;
+ $provider->setNamespace($namespace);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/FilesystemCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/FilesystemCache.php
new file mode 100644
index 0000000..8891abd
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/FilesystemCache.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Adapter\FilesystemAdapter;
+use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\Traits\FilesystemTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', FilesystemCache::class, FilesystemAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use FilesystemAdapter and type-hint for CacheInterface instead.
+ */
+class FilesystemCache extends AbstractCache implements PruneableInterface
+{
+ use FilesystemTrait;
+
+ 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/addons/weliam_smartcity/vendor/symfony/cache/Simple/MemcachedCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/MemcachedCache.php
new file mode 100644
index 0000000..e193411
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/MemcachedCache.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Adapter\MemcachedAdapter;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\Traits\MemcachedTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', MemcachedCache::class, MemcachedAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use MemcachedAdapter and type-hint for CacheInterface instead.
+ */
+class MemcachedCache extends AbstractCache
+{
+ use MemcachedTrait;
+
+ protected $maxIdLength = 250;
+
+ public function __construct(\Memcached $client, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
+ {
+ $this->init($client, $namespace, $defaultLifetime, $marshaller);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/NullCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/NullCache.php
new file mode 100644
index 0000000..d1ca6f7
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/NullCache.php
@@ -0,0 +1,90 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Components\Cache\Adapter\NullAdapter;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', NullCache::class, NullAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use NullAdapter and type-hint for CacheInterface instead.
+ */
+class NullCache implements Psr16CacheInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ return $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ foreach ($keys as $key) {
+ yield $key => $default;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ return false;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/PdoCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PdoCache.php
new file mode 100644
index 0000000..07849e9
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PdoCache.php
@@ -0,0 +1,59 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Adapter\PdoAdapter;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\Traits\PdoTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PdoCache::class, PdoAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use PdoAdapter and type-hint for CacheInterface instead.
+ */
+class PdoCache extends AbstractCache implements PruneableInterface
+{
+ use PdoTrait;
+
+ protected $maxIdLength = 255;
+
+ /**
+ * You can either pass an existing database connection as PDO instance or
+ * a Doctrine DBAL Connection or a DSN string that will be used to
+ * lazy-connect to the database when the cache is actually used.
+ *
+ * When a Doctrine DBAL Connection is passed, 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]
+ * * 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: []]
+ *
+ * @param \PDO|Connection|string $connOrDsn a \PDO or Connection instance or DSN string or null
+ *
+ * @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($connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], MarshallerInterface $marshaller = null)
+ {
+ $this->init($connOrDsn, $namespace, $defaultLifetime, $options, $marshaller);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpArrayCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpArrayCache.php
new file mode 100644
index 0000000..5666093
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpArrayCache.php
@@ -0,0 +1,248 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Component\Cache\Traits\PhpArrayTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpArrayCache::class, PhpArrayAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead.
+ */
+class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
+{
+ use PhpArrayTrait;
+
+ /**
+ * @param string $file The PHP file were values are cached
+ * @param Psr16CacheInterface $fallbackPool A pool to fallback on when an item is not hit
+ */
+ public function __construct(string $file, Psr16CacheInterface $fallbackPool)
+ {
+ $this->file = $file;
+ $this->pool = $fallbackPool;
+ }
+
+ /**
+ * This adapter takes advantage of how PHP stores arrays in its latest versions.
+ *
+ * @param string $file The PHP file were values are cached
+ *
+ * @return Psr16CacheInterface
+ */
+ public static function create($file, Psr16CacheInterface $fallbackPool)
+ {
+ // Shared memory is available in PHP 7.0+ with OPCache enabled
+ if (filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
+ return new static($file, $fallbackPool);
+ }
+
+ return $fallbackPool;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+ if (!isset($this->keys[$key])) {
+ return $this->pool->get($key, $default);
+ }
+ $value = $this->values[$this->keys[$key]];
+
+ if ('N;' === $value) {
+ return null;
+ }
+ if ($value instanceof \Closure) {
+ try {
+ return $value();
+ } catch (\Throwable $e) {
+ return $default;
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ if ($keys instanceof \Traversable) {
+ $keys = iterator_to_array($keys, false);
+ } elseif (!\is_array($keys)) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return $this->generateItems($keys, $default);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return isset($this->keys[$key]) || $this->pool->has($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return !isset($this->keys[$key]) && $this->pool->delete($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ if (!\is_array($keys) && !$keys instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
+ }
+
+ $deleted = true;
+ $fallbackKeys = [];
+
+ foreach ($keys as $key) {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+
+ if (isset($this->keys[$key])) {
+ $deleted = false;
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ if ($fallbackKeys) {
+ $deleted = $this->pool->deleteMultiple($fallbackKeys) && $deleted;
+ }
+
+ return $deleted;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+ if (null === $this->values) {
+ $this->initialize();
+ }
+
+ return !isset($this->keys[$key]) && $this->pool->set($key, $value, $ttl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ if (!\is_array($values) && !$values instanceof \Traversable) {
+ throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', \is_object($values) ? \get_class($values) : \gettype($values)));
+ }
+
+ $saved = true;
+ $fallbackValues = [];
+
+ foreach ($values as $key => $value) {
+ if (!\is_string($key) && !\is_int($key)) {
+ throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
+ }
+
+ if (isset($this->keys[$key])) {
+ $saved = false;
+ } else {
+ $fallbackValues[$key] = $value;
+ }
+ }
+
+ if ($fallbackValues) {
+ $saved = $this->pool->setMultiple($fallbackValues, $ttl) && $saved;
+ }
+
+ return $saved;
+ }
+
+ private function generateItems(array $keys, $default)
+ {
+ $fallbackKeys = [];
+
+ foreach ($keys as $key) {
+ if (isset($this->keys[$key])) {
+ $value = $this->values[$this->keys[$key]];
+
+ if ('N;' === $value) {
+ yield $key => null;
+ } elseif ($value instanceof \Closure) {
+ try {
+ yield $key => $value();
+ } catch (\Throwable $e) {
+ yield $key => $default;
+ }
+ } else {
+ yield $key => $value;
+ }
+ } else {
+ $fallbackKeys[] = $key;
+ }
+ }
+
+ if ($fallbackKeys) {
+ yield from $this->pool->getMultiple($fallbackKeys, $default);
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpFilesCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpFilesCache.php
new file mode 100644
index 0000000..060244a
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/PhpFilesCache.php
@@ -0,0 +1,45 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
+use Symfony\Component\Cache\Exception\CacheException;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\Traits\PhpFilesTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpFilesCache::class, PhpFilesAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use PhpFilesAdapter and type-hint for CacheInterface instead.
+ */
+class PhpFilesCache extends AbstractCache implements PruneableInterface
+{
+ use PhpFilesTrait;
+
+ /**
+ * @param $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, bool $appendOnly = false)
+ {
+ $this->appendOnly = $appendOnly;
+ self::$startTime = 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);
+ };
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/Psr6Cache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/Psr6Cache.php
new file mode 100644
index 0000000..090f48c
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/Psr6Cache.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Psr16Cache;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Psr6Cache::class, Psr16Cache::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use Psr16Cache instead.
+ */
+class Psr6Cache extends Psr16Cache
+{
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/RedisCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/RedisCache.php
new file mode 100644
index 0000000..a5f1bee
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/RedisCache.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Symfony\Component\Cache\Adapter\RedisAdapter;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+use Symfony\Component\Cache\Traits\RedisTrait;
+use Symfony\Contracts\Cache\CacheInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', RedisCache::class, RedisAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use RedisAdapter and type-hint for CacheInterface instead.
+ */
+class RedisCache extends AbstractCache
+{
+ use RedisTrait;
+
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
+ */
+ public function __construct($redisClient, string $namespace = '', int $defaultLifetime = 0, MarshallerInterface $marshaller = null)
+ {
+ $this->init($redisClient, $namespace, $defaultLifetime, $marshaller);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Simple/TraceableCache.php b/addons/weliam_smartcity/vendor/symfony/cache/Simple/TraceableCache.php
new file mode 100644
index 0000000..ad9bfcf
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Simple/TraceableCache.php
@@ -0,0 +1,243 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Simple;
+
+use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\ResettableInterface;
+use Symfony\Contracts\Cache\CacheInterface;
+use Symfony\Contracts\Service\ResetInterface;
+
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', TraceableCache::class, TraceableAdapter::class, CacheInterface::class), E_USER_DEPRECATED);
+
+/**
+ * @deprecated since Symfony 4.3, use TraceableAdapter and type-hint for CacheInterface instead.
+ */
+class TraceableCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
+{
+ private $pool;
+ private $miss;
+ private $calls = [];
+
+ public function __construct(Psr16CacheInterface $pool)
+ {
+ $this->pool = $pool;
+ $this->miss = new \stdClass();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($key, $default = null)
+ {
+ $miss = null !== $default && \is_object($default) ? $default : $this->miss;
+ $event = $this->start(__FUNCTION__);
+ try {
+ $value = $this->pool->get($key, $miss);
+ } finally {
+ $event->end = microtime(true);
+ }
+ if ($event->result[$key] = $miss !== $value) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ $value = $default;
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->has($key);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($key)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->delete($key);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($key, $value, $ttl = null)
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result[$key] = $this->pool->set($key, $value, $ttl);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setMultiple($values, $ttl = null)
+ {
+ $event = $this->start(__FUNCTION__);
+ $event->result['keys'] = [];
+
+ if ($values instanceof \Traversable) {
+ $values = function () use ($values, $event) {
+ foreach ($values as $k => $v) {
+ $event->result['keys'][] = $k;
+ yield $k => $v;
+ }
+ };
+ $values = $values();
+ } elseif (\is_array($values)) {
+ $event->result['keys'] = array_keys($values);
+ }
+
+ try {
+ return $event->result['result'] = $this->pool->setMultiple($values, $ttl);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultiple($keys, $default = null)
+ {
+ $miss = null !== $default && \is_object($default) ? $default : $this->miss;
+ $event = $this->start(__FUNCTION__);
+ try {
+ $result = $this->pool->getMultiple($keys, $miss);
+ } finally {
+ $event->end = microtime(true);
+ }
+ $f = function () use ($result, $event, $miss, $default) {
+ $event->result = [];
+ foreach ($result as $key => $value) {
+ if ($event->result[$key] = $miss !== $value) {
+ ++$event->hits;
+ } else {
+ ++$event->misses;
+ $value = $default;
+ }
+ yield $key => $value;
+ }
+ };
+
+ return $f();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->clear();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteMultiple($keys)
+ {
+ $event = $this->start(__FUNCTION__);
+ if ($keys instanceof \Traversable) {
+ $keys = $event->result['keys'] = iterator_to_array($keys, false);
+ } else {
+ $event->result['keys'] = $keys;
+ }
+ try {
+ return $event->result['result'] = $this->pool->deleteMultiple($keys);
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ if (!$this->pool instanceof PruneableInterface) {
+ return false;
+ }
+ $event = $this->start(__FUNCTION__);
+ try {
+ return $event->result = $this->pool->prune();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if (!$this->pool instanceof ResetInterface) {
+ return;
+ }
+ $event = $this->start(__FUNCTION__);
+ try {
+ $this->pool->reset();
+ } finally {
+ $event->end = microtime(true);
+ }
+ }
+
+ public function getCalls()
+ {
+ try {
+ return $this->calls;
+ } finally {
+ $this->calls = [];
+ }
+ }
+
+ private function start($name)
+ {
+ $this->calls[] = $event = new TraceableCacheEvent();
+ $event->name = $name;
+ $event->start = microtime(true);
+
+ return $event;
+ }
+}
+
+class TraceableCacheEvent
+{
+ public $name;
+ public $start;
+ public $end;
+ public $result;
+ public $hits = 0;
+ public $misses = 0;
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php
new file mode 100644
index 0000000..2d10240
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Adapter;
+
+use Symfony\Component\Cache\Adapter\RedisAdapter;
+
+abstract class AbstractRedisAdapterTest extends AdapterTestCase
+{
+ protected $skippedTests = [
+ 'testExpiration' => 'Testing expiration slows down the test suite',
+ 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite',
+ 'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
+ ];
+
+ protected static $redis;
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
+ }
+
+ public static function setUpBeforeClass(): void
+ {
+ if (!\extension_loaded('redis')) {
+ self::markTestSkipped('Extension redis required.');
+ }
+ if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) {
+ $e = error_get_last();
+ self::markTestSkipped($e['message']);
+ }
+ }
+
+ public static function tearDownAfterClass(): void
+ {
+ self::$redis = null;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
new file mode 100644
index 0000000..de2562d
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php
@@ -0,0 +1,273 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Adapter;
+
+use Cache\IntegrationTests\CachePoolTest;
+use PHPUnit\Framework\Assert;
+use Psr\Cache\CacheItemInterface;
+use Psr\Cache\CacheItemPoolInterface;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Contracts\Cache\CallbackInterface;
+
+abstract class AdapterTestCase extends CachePoolTest
+{
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) {
+ $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
+ }
+ }
+
+ public function testGet()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool();
+ $cache->clear();
+
+ $value = mt_rand();
+
+ $this->assertSame($value, $cache->get('foo', function (CacheItem $item) use ($value) {
+ $this->assertSame('foo', $item->getKey());
+
+ return $value;
+ }));
+
+ $item = $cache->getItem('foo');
+ $this->assertSame($value, $item->get());
+
+ $isHit = true;
+ $this->assertSame($value, $cache->get('foo', function (CacheItem $item) use (&$isHit) { $isHit = false; }, 0));
+ $this->assertTrue($isHit);
+
+ $this->assertNull($cache->get('foo', function (CacheItem $item) use (&$isHit, $value) {
+ $isHit = false;
+ $this->assertTrue($item->isHit());
+ $this->assertSame($value, $item->get());
+ }, INF));
+ $this->assertFalse($isHit);
+
+ $this->assertSame($value, $cache->get('bar', new class($value) implements CallbackInterface {
+ private $value;
+
+ public function __construct(int $value)
+ {
+ $this->value = $value;
+ }
+
+ public function __invoke(CacheItemInterface $item, bool &$save)
+ {
+ Assert::assertSame('bar', $item->getKey());
+
+ return $this->value;
+ }
+ }));
+ }
+
+ public function testRecursiveGet()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool(0, __FUNCTION__);
+
+ $v = $cache->get('k1', function () use (&$counter, $cache) {
+ $v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
+ $v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
+
+ return $v;
+ });
+
+ $this->assertSame(1, $counter);
+ $this->assertSame(1, $v);
+ $this->assertSame(1, $cache->get('k2', function () { return 2; }));
+ }
+
+ public function testGetMetadata()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool(0, __FUNCTION__);
+
+ $cache->deleteItem('foo');
+ $cache->get('foo', function ($item) {
+ $item->expiresAfter(10);
+ sleep(1);
+
+ return 'bar';
+ });
+
+ $item = $cache->getItem('foo');
+
+ $expected = [
+ CacheItem::METADATA_EXPIRY => 9.5 + time(),
+ CacheItem::METADATA_CTIME => 1000,
+ ];
+ $this->assertEqualsWithDelta($expected, $item->getMetadata(), .6, 'Item metadata should embed expiry and ctime.');
+ }
+
+ public function testDefaultLifeTime()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool(2);
+
+ $item = $cache->getItem('key.dlt');
+ $item->set('value');
+ $cache->save($item);
+ sleep(1);
+
+ $item = $cache->getItem('key.dlt');
+ $this->assertTrue($item->isHit());
+
+ sleep(2);
+ $item = $cache->getItem('key.dlt');
+ $this->assertFalse($item->isHit());
+ }
+
+ public function testExpiration()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool();
+ $cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2));
+ $cache->save($cache->getItem('k2')->set('v2')->expiresAfter(366 * 86400));
+
+ sleep(3);
+ $item = $cache->getItem('k1');
+ $this->assertFalse($item->isHit());
+ $this->assertNull($item->get(), "Item's value must be null when isHit() is false.");
+
+ $item = $cache->getItem('k2');
+ $this->assertTrue($item->isHit());
+ $this->assertSame('v2', $item->get());
+ }
+
+ public function testNotUnserializable()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ $cache = $this->createCachePool();
+
+ $item = $cache->getItem('foo');
+ $cache->save($item->set(new NotUnserializable()));
+
+ $item = $cache->getItem('foo');
+ $this->assertFalse($item->isHit());
+
+ foreach ($cache->getItems(['foo']) as $item) {
+ }
+ $cache->save($item->set(new NotUnserializable()));
+
+ foreach ($cache->getItems(['foo']) as $item) {
+ }
+ $this->assertFalse($item->isHit());
+ }
+
+ public function testPrune()
+ {
+ if (isset($this->skippedTests[__FUNCTION__])) {
+ $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
+ }
+
+ if (!method_exists($this, 'isPruned')) {
+ $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
+ }
+
+ /** @var PruneableInterface|CacheItemPoolInterface $cache */
+ $cache = $this->createCachePool();
+
+ $doSet = function ($name, $value, \DateInterval $expiresAfter = null) use ($cache) {
+ $item = $cache->getItem($name);
+ $item->set($value);
+
+ if ($expiresAfter) {
+ $item->expiresAfter($expiresAfter);
+ }
+
+ $cache->save($item);
+ };
+
+ $doSet('foo', 'foo-val', new \DateInterval('PT05S'));
+ $doSet('bar', 'bar-val', new \DateInterval('PT10S'));
+ $doSet('baz', 'baz-val', new \DateInterval('PT15S'));
+ $doSet('qux', 'qux-val', new \DateInterval('PT20S'));
+
+ sleep(30);
+ $cache->prune();
+ $this->assertTrue($this->isPruned($cache, 'foo'));
+ $this->assertTrue($this->isPruned($cache, 'bar'));
+ $this->assertTrue($this->isPruned($cache, 'baz'));
+ $this->assertTrue($this->isPruned($cache, 'qux'));
+
+ $doSet('foo', 'foo-val');
+ $doSet('bar', 'bar-val', new \DateInterval('PT20S'));
+ $doSet('baz', 'baz-val', new \DateInterval('PT40S'));
+ $doSet('qux', 'qux-val', new \DateInterval('PT80S'));
+
+ $cache->prune();
+ $this->assertFalse($this->isPruned($cache, 'foo'));
+ $this->assertFalse($this->isPruned($cache, 'bar'));
+ $this->assertFalse($this->isPruned($cache, 'baz'));
+ $this->assertFalse($this->isPruned($cache, 'qux'));
+
+ sleep(30);
+ $cache->prune();
+ $this->assertFalse($this->isPruned($cache, 'foo'));
+ $this->assertTrue($this->isPruned($cache, 'bar'));
+ $this->assertFalse($this->isPruned($cache, 'baz'));
+ $this->assertFalse($this->isPruned($cache, 'qux'));
+
+ sleep(30);
+ $cache->prune();
+ $this->assertFalse($this->isPruned($cache, 'foo'));
+ $this->assertTrue($this->isPruned($cache, 'baz'));
+ $this->assertFalse($this->isPruned($cache, 'qux'));
+
+ sleep(30);
+ $cache->prune();
+ $this->assertFalse($this->isPruned($cache, 'foo'));
+ $this->assertTrue($this->isPruned($cache, 'qux'));
+ }
+
+ /**
+ * @group issue-32995
+ *
+ * @runInSeparateProcess https://github.com/symfony/symfony/issues/32995
+ */
+ public function testSavingObject()
+ {
+ parent::testSavingObject();
+ }
+}
+
+class NotUnserializable
+{
+ public function __wakeup()
+ {
+ throw new \Exception(__CLASS__);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php
new file mode 100644
index 0000000..5cca73f
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php
@@ -0,0 +1,124 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Adapter;
+
+use Psr\Log\NullLogger;
+use Symfony\Component\Cache\Adapter\ApcuAdapter;
+
+class ApcuAdapterTest extends AdapterTestCase
+{
+ protected $skippedTests = [
+ 'testExpiration' => 'Testing expiration slows down the test suite',
+ 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite',
+ 'testDefaultLifeTime' => 'Testing expiration slows down the test suite',
+ ];
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN)) {
+ $this->markTestSkipped('APCu extension is required.');
+ }
+ if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) {
+ if ('testWithCliSapi' !== $this->getName()) {
+ $this->markTestSkipped('apc.enable_cli=1 is required.');
+ }
+ }
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Fails transiently on Windows.');
+ }
+
+ return new ApcuAdapter(str_replace('\\', '.', __CLASS__), $defaultLifetime);
+ }
+
+ public function testUnserializable()
+ {
+ $pool = $this->createCachePool();
+
+ $item = $pool->getItem('foo');
+ $item->set(function () {});
+
+ $this->assertFalse($pool->save($item));
+
+ $item = $pool->getItem('foo');
+ $this->assertFalse($item->isHit());
+ }
+
+ public function testVersion()
+ {
+ $namespace = str_replace('\\', '.', \get_class($this));
+
+ $pool1 = new ApcuAdapter($namespace, 0, 'p1');
+
+ $item = $pool1->getItem('foo');
+ $this->assertFalse($item->isHit());
+ $this->assertTrue($pool1->save($item->set('bar')));
+
+ $item = $pool1->getItem('foo');
+ $this->assertTrue($item->isHit());
+ $this->assertSame('bar', $item->get());
+
+ $pool2 = new ApcuAdapter($namespace, 0, 'p2');
+
+ $item = $pool2->getItem('foo');
+ $this->assertFalse($item->isHit());
+ $this->assertNull($item->get());
+
+ $item = $pool1->getItem('foo');
+ $this->assertFalse($item->isHit());
+ $this->assertNull($item->get());
+ }
+
+ public function testNamespace()
+ {
+ $namespace = str_replace('\\', '.', \get_class($this));
+
+ $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1');
+
+ $item = $pool1->getItem('foo');
+ $this->assertFalse($item->isHit());
+ $this->assertTrue($pool1->save($item->set('bar')));
+
+ $item = $pool1->getItem('foo');
+ $this->assertTrue($item->isHit());
+ $this->assertSame('bar', $item->get());
+
+ $pool2 = new ApcuAdapter($namespace.'_2', 0, 'p1');
+
+ $item = $pool2->getItem('foo');
+ $this->assertFalse($item->isHit());
+ $this->assertNull($item->get());
+
+ $item = $pool1->getItem('foo');
+ $this->assertTrue($item->isHit());
+ $this->assertSame('bar', $item->get());
+ }
+
+ public function testWithCliSapi()
+ {
+ try {
+ // disable PHPUnit error handler to mimic a production environment
+ $isCalled = false;
+ set_error_handler(function () use (&$isCalled) {
+ $isCalled = true;
+ });
+ $pool = new ApcuAdapter(str_replace('\\', '.', __CLASS__));
+ $pool->setLogger(new NullLogger());
+
+ $item = $pool->getItem('foo');
+ $item->isHit();
+ $pool->save($item->set('bar'));
+ $this->assertFalse($isCalled);
+ } finally {
+ restore_error_handler();
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php
new file mode 100644
index 0000000..5c72dc6
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php
@@ -0,0 +1,57 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Adapter;
+
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
+
+/**
+ * @group time-sensitive
+ */
+class ArrayAdapterTest extends AdapterTestCase
+{
+ protected $skippedTests = [
+ 'testGetMetadata' => 'ArrayAdapter does not keep metadata.',
+ 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.',
+ 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.',
+ ];
+
+ public function createCachePool($defaultLifetime = 0)
+ {
+ return new ArrayAdapter($defaultLifetime);
+ }
+
+ public function testGetValuesHitAndMiss()
+ {
+ /** @var ArrayAdapter $cache */
+ $cache = $this->createCachePool();
+
+ // Hit
+ $item = $cache->getItem('foo');
+ $item->set('::4711');
+ $cache->save($item);
+
+ $fooItem = $cache->getItem('foo');
+ $this->assertTrue($fooItem->isHit());
+ $this->assertEquals('::4711', $fooItem->get());
+
+ // Miss (should be present as NULL in $values)
+ $cache->getItem('bar');
+
+ $values = $cache->getValues();
+
+ $this->assertCount(2, $values);
+ $this->assertArrayHasKey('foo', $values);
+ $this->assertSame(serialize('::4711'), $values['foo']);
+ $this->assertArrayHasKey('bar', $values);
+ $this->assertNull($values['bar']);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php
new file mode 100644
index 0000000..ac92006
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Tests\Adapter;
+
+use PHPUnit\Framework\MockObject\MockObject;
+use Symfony\Component\Cache\Adapter\AdapterInterface;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\Adapter\ChainAdapter;
+use Symfony\Component\Cache\Adapter\FilesystemAdapter;
+use Symfony\Component\Cache\PruneableInterface;
+use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
+
+/**
+ * @author Kévin Dunglas
+ *
+ * @internal
+ */
+trait AbstractAdapterTrait
+{
+ use AbstractTrait;
+
+ /**
+ * @var \Closure needs to be set by class, signature is function(string
+ *
+ * @internal
+ */
+trait AbstractTrait
+{
+ use LoggerAwareTrait;
+
+ private $namespace;
+ private $namespaceVersion = '';
+ private $versioningIsEnabled = false;
+ private $deferred = [];
+ private $ids = [];
+
+ /**
+ * @var int|null The maximum length to enforce for identifiers or null when no limit applies
+ */
+ protected $maxIdLength;
+
+ /**
+ * Fetches several cache items.
+ *
+ * @param array $ids The cache identifiers to fetch
+ *
+ * @return array|\Traversable The corresponding values found in the cache
+ */
+ abstract protected function doFetch(array $ids);
+
+ /**
+ * Confirms if the cache contains specified cache item.
+ *
+ * @param string $id The identifier for which to check existence
+ *
+ * @return bool True if item exists in the cache, false otherwise
+ */
+ abstract protected function doHave($id);
+
+ /**
+ * Deletes all items in the pool.
+ *
+ * @param string $namespace The prefix used for all identifiers managed by this pool
+ *
+ * @return bool True if the pool was successfully cleared, false otherwise
+ */
+ abstract protected function doClear($namespace);
+
+ /**
+ * Removes multiple items from the pool.
+ *
+ * @param array $ids An array of identifiers that should be removed from the pool
+ *
+ * @return bool True if the items were successfully removed, false otherwise
+ */
+ abstract protected function doDelete(array $ids);
+
+ /**
+ * 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
+ *
+ * @return array|bool The identifiers that failed to be cached or a boolean stating if caching succeeded or not
+ */
+ abstract protected function doSave(array $values, $lifetime);
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ $id = $this->getId($key);
+
+ if (isset($this->deferred[$key])) {
+ $this->commit();
+ }
+
+ try {
+ return $this->doHave($id);
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
+
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->deferred = [];
+ if ($cleared = $this->versioningIsEnabled) {
+ $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5);
+ try {
+ $cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0);
+ } catch (\Exception $e) {
+ $cleared = false;
+ }
+ if ($cleared = true === $cleared || [] === $cleared) {
+ $this->namespaceVersion = $namespaceVersion;
+ $this->ids = [];
+ }
+ }
+
+ try {
+ return $this->doClear($this->namespace) || $cleared;
+ } catch (\Exception $e) {
+ CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
+
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ return $this->deleteItems([$key]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItems(array $keys)
+ {
+ $ids = [];
+
+ foreach ($keys as $key) {
+ $ids[$key] = $this->getId($key);
+ unset($this->deferred[$key]);
+ }
+
+ try {
+ if ($this->doDelete($ids)) {
+ return true;
+ }
+ } catch (\Exception $e) {
+ }
+
+ $ok = true;
+
+ // When bulk-delete failed, retry each item individually
+ foreach ($ids as $key => $id) {
+ try {
+ $e = null;
+ if ($this->doDelete([$id])) {
+ continue;
+ }
+ } catch (\Exception $e) {
+ }
+ $message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
+ $ok = false;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Enables/disables versioning of items.
+ *
+ * When versioning is enabled, clearing the cache is atomic and doesn't require listing existing keys to proceed,
+ * but old keys may need garbage collection and extra round-trips to the back-end are required.
+ *
+ * Calling this method also clears the memoized namespace version and thus forces a resynchonization of it.
+ *
+ * @param bool $enable
+ *
+ * @return bool the previous state of versioning
+ */
+ public function enableVersioning($enable = true)
+ {
+ $wasEnabled = $this->versioningIsEnabled;
+ $this->versioningIsEnabled = (bool) $enable;
+ $this->namespaceVersion = '';
+ $this->ids = [];
+
+ return $wasEnabled;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->deferred) {
+ $this->commit();
+ }
+ $this->namespaceVersion = '';
+ $this->ids = [];
+ }
+
+ /**
+ * Like the native unserialize() function but throws an exception if anything goes wrong.
+ *
+ * @param string $value
+ *
+ * @return mixed
+ *
+ * @throws \Exception
+ *
+ * @deprecated since Symfony 4.2, use DefaultMarshaller instead.
+ */
+ protected static function unserialize($value)
+ {
+ @trigger_error(sprintf('The "%s::unserialize()" method is deprecated since Symfony 4.2, use DefaultMarshaller instead.', __CLASS__), E_USER_DEPRECATED);
+
+ if ('b:0;' === $value) {
+ return false;
+ }
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
+ try {
+ if (false !== $value = unserialize($value)) {
+ return $value;
+ }
+ throw new \DomainException('Failed to unserialize cached value');
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+
+ private function getId($key)
+ {
+ if ($this->versioningIsEnabled && '' === $this->namespaceVersion) {
+ $this->ids = [];
+ $this->namespaceVersion = '1'.static::NS_SEPARATOR;
+ try {
+ foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) {
+ $this->namespaceVersion = $v;
+ }
+ if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) {
+ $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5);
+ $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0);
+ }
+ } catch (\Exception $e) {
+ }
+ }
+
+ if (\is_string($key) && isset($this->ids[$key])) {
+ return $this->namespace.$this->namespaceVersion.$this->ids[$key];
+ }
+ CacheItem::validateKey($key);
+ $this->ids[$key] = $key;
+
+ if (null === $this->maxIdLength) {
+ return $this->namespace.$this->namespaceVersion.$key;
+ }
+ if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
+ // Use MD5 to favor speed over security, which is not an issue here
+ $this->ids[$key] = $id = substr_replace(base64_encode(hash('md5', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 2));
+ $id = $this->namespace.$this->namespaceVersion.$id;
+ }
+
+ return $id;
+ }
+
+ /**
+ * @internal
+ */
+ public static function handleUnserializeCallback($class)
+ {
+ throw new \DomainException('Class not found: '.$class);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/ApcuTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ApcuTrait.php
new file mode 100644
index 0000000..c86b043
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ApcuTrait.php
@@ -0,0 +1,121 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\CacheException;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait ApcuTrait
+{
+ public static function isSupported()
+ {
+ return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN);
+ }
+
+ private function init($namespace, $defaultLifetime, $version)
+ {
+ 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);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
+ try {
+ $values = [];
+ foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) {
+ if (null !== $v || $ok) {
+ $values[$k] = $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);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ return apcu_exists($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN))
+ ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), APC_ITER_KEY))
+ : apcu_clear_cache();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ foreach ($ids as $id) {
+ apcu_delete($id);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ 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(key($values));
+ }
+
+ throw $e;
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/ArrayTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ArrayTrait.php
new file mode 100644
index 0000000..497504c
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ArrayTrait.php
@@ -0,0 +1,165 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Psr\Log\LoggerAwareTrait;
+use Symfony\Component\Cache\CacheItem;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait ArrayTrait
+{
+ use LoggerAwareTrait;
+
+ private $storeSerialized;
+ private $values = [];
+ private $expiries = [];
+
+ /**
+ * Returns all cached values, with cache miss as null.
+ *
+ * @return array
+ */
+ public function getValues()
+ {
+ 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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasItem($key)
+ {
+ if (\is_string($key) && isset($this->expiries[$key]) && $this->expiries[$key] > microtime(true)) {
+ return true;
+ }
+ CacheItem::validateKey($key);
+
+ return isset($this->expiries[$key]) && !$this->deleteItem($key);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->values = $this->expiries = [];
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function deleteItem($key)
+ {
+ if (!\is_string($key) || !isset($this->expiries[$key])) {
+ CacheItem::validateKey($key);
+ }
+ unset($this->values[$key], $this->expiries[$key]);
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ $this->clear();
+ }
+
+ private function generateItems(array $keys, $now, $f)
+ {
+ foreach ($keys as $i => $key) {
+ if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) {
+ $this->values[$key] = $value = null;
+ } else {
+ $value = $this->storeSerialized ? $this->unfreeze($key, $isHit) : $this->values[$key];
+ }
+ unset($keys[$i]);
+
+ yield $key => $f($key, $value, $isHit);
+ }
+
+ foreach ($keys as $key) {
+ yield $key => $f($key, null, false);
+ }
+ }
+
+ private function freeze($value, $key)
+ {
+ 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) {
+ $type = \is_object($value) ? \get_class($value) : \gettype($value);
+ $message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
+ CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
+
+ 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)
+ {
+ 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]);
+ $value = false;
+ }
+ if (false === $value) {
+ $this->values[$key] = $value = null;
+ $isHit = false;
+ }
+ }
+
+ return $value;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/ContractsTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ContractsTrait.php
new file mode 100644
index 0000000..7f99f65
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/ContractsTrait.php
@@ -0,0 +1,97 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Cache\Adapter\AdapterInterface;
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\LockRegistry;
+use Symfony\Contracts\Cache\CacheInterface;
+use Symfony\Contracts\Cache\CacheTrait;
+use Symfony\Contracts\Cache\ItemInterface;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait ContractsTrait
+{
+ use CacheTrait {
+ doGet as private contractsGet;
+ }
+
+ private $callbackWrapper = [LockRegistry::class, 'compute'];
+ private $computing = [];
+
+ /**
+ * Wraps the callback passed to ->get() in a callable.
+ *
+ * @return callable the previous callback wrapper
+ */
+ public function setCallbackWrapper(?callable $callbackWrapper): callable
+ {
+ $previousWrapper = $this->callbackWrapper;
+ $this->callbackWrapper = $callbackWrapper ?? function (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) {
+ return $callback($item, $save);
+ };
+
+ return $previousWrapper;
+ }
+
+ private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null)
+ {
+ if (0 > $beta = $beta ?? 1.0) {
+ throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta));
+ }
+
+ static $setMetadata;
+
+ $setMetadata = $setMetadata ?? \Closure::bind(
+ static function (CacheItem $item, float $startTime, ?array &$metadata) {
+ if ($item->expiry > $endTime = microtime(true)) {
+ $item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
+ $item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = 1000 * (int) ($endTime - $startTime);
+ } else {
+ unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME]);
+ }
+ },
+ null,
+ CacheItem::class
+ );
+
+ return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
+ // don't wrap nor save recursive calls
+ if (isset($this->computing[$key])) {
+ $value = $callback($item, $save);
+ $save = false;
+
+ return $value;
+ }
+
+ $this->computing[$key] = $key;
+ $startTime = microtime(true);
+
+ try {
+ $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
+ $setMetadata($item, $startTime, $metadata);
+ }, $this->logger ?? null);
+ $setMetadata($item, $startTime, $metadata);
+
+ return $value;
+ } finally {
+ unset($this->computing[$key]);
+ }
+ }, $beta, $metadata, $this->logger ?? null);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/DoctrineTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/DoctrineTrait.php
new file mode 100644
index 0000000..c87ecab
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/DoctrineTrait.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait DoctrineTrait
+{
+ private $provider;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ parent::reset();
+ $this->provider->setNamespace($this->provider->getNamespace());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ $unserializeCallbackHandler = ini_set('unserialize_callback_func', parent::class.'::handleUnserializeCallback');
+ try {
+ return $this->provider->fetchMultiple($ids);
+ } catch (\Error $e) {
+ $trace = $e->getTrace();
+
+ if (isset($trace[0]['function']) && !isset($trace[0]['class'])) {
+ switch ($trace[0]['function']) {
+ case 'unserialize':
+ case 'apcu_fetch':
+ case 'apc_fetch':
+ throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
+ }
+ }
+
+ throw $e;
+ } finally {
+ ini_set('unserialize_callback_func', $unserializeCallbackHandler);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ return $this->provider->contains($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ $namespace = $this->provider->getNamespace();
+
+ return isset($namespace[0])
+ ? $this->provider->deleteAll()
+ : $this->provider->flushAll();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = true;
+ foreach ($ids as $id) {
+ $ok = $this->provider->delete($id) && $ok;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ return $this->provider->saveMultiple($values, $lifetime);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
new file mode 100644
index 0000000..37e1fd1
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemCommonTrait.php
@@ -0,0 +1,144 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+trait FilesystemCommonTrait
+{
+ private $directory;
+ private $tmp;
+
+ private function init($namespace, $directory)
+ {
+ if (!isset($directory[0])) {
+ $directory = sys_get_temp_dir().'/symfony-cache';
+ } else {
+ $directory = realpath($directory) ?: $directory;
+ }
+ if (isset($namespace[0])) {
+ if (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]));
+ }
+ $directory .= \DIRECTORY_SEPARATOR.$namespace;
+ }
+ if (!file_exists($directory)) {
+ @mkdir($directory, 0777, true);
+ }
+ $directory .= \DIRECTORY_SEPARATOR;
+ // On Windows the whole path is limited to 258 chars
+ if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) {
+ throw new InvalidArgumentException(sprintf('Cache directory too long (%s)', $directory));
+ }
+
+ $this->directory = $directory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ $ok = true;
+
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS)) as $file) {
+ $ok = ($file->isDir() || $this->doUnlink($file) || !file_exists($file)) && $ok;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = true;
+
+ foreach ($ids as $id) {
+ $file = $this->getFile($id);
+ $ok = (!file_exists($file) || $this->doUnlink($file) || !file_exists($file)) && $ok;
+ }
+
+ return $ok;
+ }
+
+ protected function doUnlink($file)
+ {
+ return @unlink($file);
+ }
+
+ private function write($file, $data, $expiresAt = null)
+ {
+ set_error_handler(__CLASS__.'::throwError');
+ try {
+ if (null === $this->tmp) {
+ $this->tmp = $this->directory.uniqid('', true);
+ }
+ file_put_contents($this->tmp, $data);
+
+ if (null !== $expiresAt) {
+ touch($this->tmp, $expiresAt);
+ }
+
+ return rename($this->tmp, $file);
+ } finally {
+ restore_error_handler();
+ }
+ }
+
+ private function getFile($id, $mkdir = false, string $directory = null)
+ {
+ // Use MD5 to favor speed over security, which is not an issue here
+ $hash = str_replace('/', '-', base64_encode(hash('md5', static::class.$id, true)));
+ $dir = ($directory ?? $this->directory).strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR);
+
+ if ($mkdir && !file_exists($dir)) {
+ @mkdir($dir, 0777, true);
+ }
+
+ return $dir.substr($hash, 2, 20);
+ }
+
+ /**
+ * @internal
+ */
+ public static function throwError($type, $message, $file, $line)
+ {
+ throw new \ErrorException($message, 0, $type, $file, $line);
+ }
+
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
+ }
+
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
+ }
+
+ public function __destruct()
+ {
+ if (method_exists(parent::class, '__destruct')) {
+ parent::__destruct();
+ }
+ if (null !== $this->tmp && file_exists($this->tmp)) {
+ unlink($this->tmp);
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemTrait.php
new file mode 100644
index 0000000..9c444f9
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/FilesystemTrait.php
@@ -0,0 +1,111 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Symfony\Component\Cache\Exception\CacheException;
+
+/**
+ * @author Nicolas Grekas
+ * @author Rob Frawley 2nd
+ *
+ * @internal
+ */
+trait MemcachedTrait
+{
+ private static $defaultClientOptions = [
+ 'persistent_id' => null,
+ 'username' => null,
+ 'password' => null,
+ 'serializer' => 'php',
+ ];
+
+ private $marshaller;
+ private $client;
+ private $lazyClient;
+
+ public static function isSupported()
+ {
+ return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>=');
+ }
+
+ private function init(\Memcached $client, $namespace, $defaultLifetime, ?MarshallerInterface $marshaller)
+ {
+ if (!static::isSupported()) {
+ throw new CacheException('Memcached >= 2.2.0 is required');
+ }
+ if ('Memcached' === \get_class($client)) {
+ $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();
+ }
+
+ /**
+ * 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
+ * @param array $options An array of options
+ *
+ * @return \Memcached
+ *
+ * @throws \ErrorException When invalid options or servers are provided
+ */
+ public static function createConnection($servers, array $options = [])
+ {
+ if (\is_string($servers)) {
+ $servers = [$servers];
+ } elseif (!\is_array($servers)) {
+ throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, %s given.', \gettype($servers)));
+ }
+ if (!static::isSupported()) {
+ throw new CacheException('Memcached >= 2.2.0 is required');
+ }
+ set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); });
+ try {
+ $options += static::$defaultClientOptions;
+ $client = new \Memcached($options['persistent_id']);
+ $username = $options['username'];
+ $password = $options['password'];
+
+ // parse any DSN in $servers
+ foreach ($servers as $i => $dsn) {
+ if (\is_array($dsn)) {
+ continue;
+ }
+ if (0 !== strpos($dsn, 'memcached:')) {
+ throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s does not start with "memcached:"', $dsn));
+ }
+ $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
+ if (!empty($m[2])) {
+ list($username, $password) = explode(':', $m[2], 2) + [1 => null];
+ }
+
+ return 'file:'.($m[1] ?? '');
+ }, $dsn);
+ if (false === $params = parse_url($params)) {
+ throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $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(sprintf('Invalid Memcached DSN: %s', $dsn));
+ }
+ 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(sprintf('Invalid Memcached DSN: %s', $dsn));
+ }
+ 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' => isset($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));
+ }
+ $opt = \constant('Memcached::OPT_'.$name);
+
+ unset($options[$name]);
+ $options[$opt] = $value;
+ }
+ $client->setOptions($options);
+
+ // 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();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+
+ if ($lifetime && $lifetime > 30 * 86400) {
+ $lifetime += time();
+ }
+
+ $encodedValues = [];
+ foreach ($values as $key => $value) {
+ $encodedValues[rawurlencode($key)] = $value;
+ }
+
+ return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)) ? $failed : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ try {
+ $encodedIds = array_map('rawurlencode', $ids);
+
+ $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds));
+
+ $result = [];
+ foreach ($encodedResult as $key => $value) {
+ $result[rawurldecode($key)] = $this->marshaller->unmarshall($value);
+ }
+
+ return $result;
+ } catch (\Error $e) {
+ throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ return false !== $this->getClient()->get(rawurlencode($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $ok = true;
+ $encodedIds = array_map('rawurlencode', $ids);
+ foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) {
+ if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
+ $ok = false;
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ return '' === $namespace && $this->getClient()->flush();
+ }
+
+ private function checkResultCode($result)
+ {
+ $code = $this->client->getResultCode();
+
+ if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) {
+ return $result;
+ }
+
+ throw new CacheException(sprintf('MemcachedAdapter client error: %s.', strtolower($this->client->getResultMessage())));
+ }
+
+ /**
+ * @return \Memcached
+ */
+ private function getClient()
+ {
+ if ($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;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/PdoTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PdoTrait.php
new file mode 100644
index 0000000..ec34e72
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PdoTrait.php
@@ -0,0 +1,424 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\DBALException;
+use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Exception\TableNotFoundException;
+use Doctrine\DBAL\Schema\Schema;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
+use Symfony\Component\Cache\Marshaller\MarshallerInterface;
+
+/**
+ * @internal
+ */
+trait PdoTrait
+{
+ private $marshaller;
+ private $conn;
+ private $dsn;
+ private $driver;
+ private $serverVersion;
+ private $table = 'cache_items';
+ private $idCol = 'item_id';
+ private $dataCol = 'item_data';
+ private $lifetimeCol = 'item_lifetime';
+ private $timeCol = 'item_time';
+ private $username = '';
+ private $password = '';
+ private $connectionOptions = [];
+ private $namespace;
+
+ private function init($connOrDsn, $namespace, $defaultLifetime, array $options, ?MarshallerInterface $marshaller)
+ {
+ 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;
+ } elseif ($connOrDsn instanceof Connection) {
+ $this->conn = $connOrDsn;
+ } elseif (\is_string($connOrDsn)) {
+ $this->dsn = $connOrDsn;
+ } else {
+ throw new InvalidArgumentException(sprintf('"%s" requires PDO or Doctrine\DBAL\Connection instance or DSN string as first argument, "%s" given.', __CLASS__, \is_object($connOrDsn) ? \get_class($connOrDsn) : \gettype($connOrDsn)));
+ }
+
+ $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table;
+ $this->idCol = isset($options['db_id_col']) ? $options['db_id_col'] : $this->idCol;
+ $this->dataCol = isset($options['db_data_col']) ? $options['db_data_col'] : $this->dataCol;
+ $this->lifetimeCol = isset($options['db_lifetime_col']) ? $options['db_lifetime_col'] : $this->lifetimeCol;
+ $this->timeCol = isset($options['db_time_col']) ? $options['db_time_col'] : $this->timeCol;
+ $this->username = isset($options['db_username']) ? $options['db_username'] : $this->username;
+ $this->password = isset($options['db_password']) ? $options['db_password'] : $this->password;
+ $this->connectionOptions = isset($options['db_connection_options']) ? $options['db_connection_options'] : $this->connectionOptions;
+ $this->namespace = $namespace;
+ $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 \PDOException When the table already exists
+ * @throws DBALException When the table already exists
+ * @throws \DomainException When an unsupported PDO driver is used
+ */
+ public function createTable()
+ {
+ // connect if we are not yet
+ $conn = $this->getConnection();
+
+ if ($conn instanceof Connection) {
+ $types = [
+ 'mysql' => 'binary',
+ 'sqlite' => 'text',
+ 'pgsql' => 'string',
+ 'oci' => 'string',
+ 'sqlsrv' => 'string',
+ ];
+ if (!isset($types[$this->driver])) {
+ throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver));
+ }
+
+ $schema = new Schema();
+ $table = $schema->createTable($this->table);
+ $table->addColumn($this->idCol, $types[$this->driver], ['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]);
+
+ foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
+ $conn->exec($sql);
+ }
+
+ return;
+ }
+
+ switch ($this->driver) {
+ case 'mysql':
+ // 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
+ $sql = "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 utf8_bin, ENGINE = InnoDB";
+ break;
+ case 'sqlite':
+ $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)";
+ break;
+ case 'pgsql':
+ $sql = "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)";
+ break;
+ case 'oci':
+ $sql = "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)";
+ break;
+ case 'sqlsrv':
+ $sql = "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)";
+ break;
+ default:
+ throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver));
+ }
+
+ $conn->exec($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ $deleteSql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= :time";
+
+ if ('' !== $this->namespace) {
+ $deleteSql .= " AND $this->idCol LIKE :namespace";
+ }
+
+ try {
+ $delete = $this->getConnection()->prepare($deleteSql);
+ } catch (TableNotFoundException $e) {
+ 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 (TableNotFoundException $e) {
+ return true;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ $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 = $this->getConnection()->prepare($sql);
+ $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT);
+ foreach ($ids as $id) {
+ $stmt->bindValue(++$i, $id);
+ }
+ $stmt->execute();
+
+ while ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
+ 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 = $this->getConnection()->prepare($sql);
+ $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT);
+ foreach ($expired as $id) {
+ $stmt->bindValue(++$i, $id);
+ }
+ $stmt->execute();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ $sql = "SELECT 1 FROM $this->table WHERE $this->idCol = :id AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > :time)";
+ $stmt = $this->getConnection()->prepare($sql);
+
+ $stmt->bindValue(':id', $id);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $stmt->execute();
+
+ return (bool) $stmt->fetchColumn();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ $conn = $this->getConnection();
+
+ if ('' === $namespace) {
+ if ('sqlite' === $this->driver) {
+ $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 (TableNotFoundException $e) {
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ $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 (TableNotFoundException $e) {
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+
+ $conn = $this->getConnection();
+ $driver = $this->driver;
+ $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 (TableNotFoundException $e) {
+ if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
+ $this->createTable();
+ }
+ $stmt = $conn->prepare($sql);
+ }
+
+ 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 (TableNotFoundException $e) {
+ if (!$conn->isTransactionActive() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
+ $this->createTable();
+ }
+ $stmt->execute();
+ }
+ if (null === $driver && !$stmt->rowCount()) {
+ try {
+ $insertStmt->execute();
+ } catch (DBALException $e) {
+ } catch (\PDOException $e) {
+ // A concurrent write won, let it be
+ }
+ }
+ }
+
+ return $failed;
+ }
+
+ /**
+ * @return \PDO|Connection
+ */
+ private function getConnection()
+ {
+ if (null === $this->conn) {
+ $this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
+ $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ }
+ if (null === $this->driver) {
+ if ($this->conn instanceof \PDO) {
+ $this->driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME);
+ } else {
+ switch ($this->driver = $this->conn->getDriver()->getName()) {
+ case 'mysqli':
+ case 'pdo_mysql':
+ case 'drizzle_pdo_mysql':
+ $this->driver = 'mysql';
+ break;
+ case 'pdo_sqlite':
+ $this->driver = 'sqlite';
+ break;
+ case 'pdo_pgsql':
+ $this->driver = 'pgsql';
+ break;
+ case 'oci8':
+ case 'pdo_oracle':
+ $this->driver = 'oci';
+ break;
+ case 'pdo_sqlsrv':
+ $this->driver = 'sqlsrv';
+ break;
+ }
+ }
+ }
+
+ return $this->conn;
+ }
+
+ /**
+ * @return string
+ */
+ private function getServerVersion()
+ {
+ if (null === $this->serverVersion) {
+ $conn = $this->conn instanceof \PDO ? $this->conn : $this->conn->getWrappedConnection();
+ if ($conn instanceof \PDO) {
+ $this->serverVersion = $conn->getAttribute(\PDO::ATTR_SERVER_VERSION);
+ } elseif ($conn instanceof ServerInfoAwareConnection) {
+ $this->serverVersion = $conn->getServerVersion();
+ } else {
+ $this->serverVersion = '0';
+ }
+ }
+
+ return $this->serverVersion;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpArrayTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpArrayTrait.php
new file mode 100644
index 0000000..4395de0
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpArrayTrait.php
@@ -0,0 +1,152 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Symfony\Component\Cache\CacheItem;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\VarExporter\VarExporter;
+
+/**
+ * @author Titouan Galopin
+ *
+ * @internal
+ */
+trait PhpArrayTrait
+{
+ use ProxyTrait;
+
+ private $file;
+ private $keys;
+ private $values;
+
+ /**
+ * Store an array of cached values.
+ *
+ * @param array $values The cached values
+ */
+ public function warmUp(array $values)
+ {
+ 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));
+ }
+ }
+
+ $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);
+ } catch (\Exception $e) {
+ throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, \is_object($value) ? \get_class($value) : 'array'), 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, \gettype($value)));
+ } else {
+ $value = var_export($value, true);
+ }
+
+ if (!$isStaticValue) {
+ $value = str_replace("\n", "\n ", $value);
+ $value = "static function () {\n return {$value};\n}";
+ }
+ $hash = hash('md5', $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);
+
+ $this->initialize();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->keys = $this->values = [];
+
+ $cleared = @unlink($this->file) || !file_exists($this->file);
+
+ return $this->pool->clear() && $cleared;
+ }
+
+ /**
+ * Load the cache file.
+ */
+ private function initialize()
+ {
+ if (!file_exists($this->file)) {
+ $this->keys = $this->values = [];
+
+ return;
+ }
+ $values = (include $this->file) ?: [[], []];
+
+ if (2 !== \count($values) || !isset($values[0], $values[1])) {
+ $this->keys = $this->values = [];
+ } else {
+ list($this->keys, $this->values) = $values;
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpFilesTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpFilesTrait.php
new file mode 100644
index 0000000..5ed4d60
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/PhpFilesTrait.php
@@ -0,0 +1,282 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Symfony\Component\Cache\Exception\CacheException;
+use Symfony\Component\Cache\Exception\InvalidArgumentException;
+use Symfony\Component\VarExporter\VarExporter;
+
+/**
+ * @author Piotr Stankowski
+ * @author Rob Frawley 2nd
+ *
+ * @internal
+ */
+trait ProxyTrait
+{
+ private $pool;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune()
+ {
+ return $this->pool instanceof PruneableInterface && $this->pool->prune();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset()
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisClusterProxy.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisClusterProxy.php
new file mode 100644
index 0000000..b4cef59
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisClusterProxy.php
@@ -0,0 +1,63 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+/**
+ * @author Alessandro Chitolina
+ *
+ * @internal
+ */
+class RedisProxy
+{
+ private $redis;
+ private $initializer;
+ private $ready = false;
+
+ public function __construct(\Redis $redis, \Closure $initializer)
+ {
+ $this->redis = $redis;
+ $this->initializer = $initializer;
+ }
+
+ public function __call($method, array $args)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+
+ return $this->redis->{$method}(...$args);
+ }
+
+ public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+
+ return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+
+ public function scan(&$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+
+ return $this->redis->scan($iIterator, $strPattern, $iCount);
+ }
+
+ public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+
+ return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+
+ public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null)
+ {
+ $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis);
+
+ return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount);
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisTrait.php b/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisTrait.php
new file mode 100644
index 0000000..b2faca6
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/Traits/RedisTrait.php
@@ -0,0 +1,489 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Cache\Traits;
+
+use Predis\Connection\Aggregate\ClusterInterface;
+use Predis\Connection\Aggregate\RedisCluster;
+use Predis\Response\Status;
+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 Aurimas Niekis
+ *
+ * @internal
+ */
+trait RedisTrait
+{
+ private static $defaultConnectionOptions = [
+ 'class' => null,
+ 'persistent' => 0,
+ 'persistent_id' => null,
+ 'timeout' => 30,
+ 'read_timeout' => 0,
+ 'retry_interval' => 0,
+ 'compression' => true,
+ 'tcp_keepalive' => 0,
+ 'lazy' => null,
+ 'redis_cluster' => false,
+ 'dbindex' => 0,
+ 'failover' => 'none',
+ ];
+ private $redis;
+ private $marshaller;
+
+ /**
+ * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient
+ */
+ private function init($redisClient, $namespace, $defaultLifetime, ?MarshallerInterface $marshaller)
+ {
+ parent::__construct($namespace, $defaultLifetime);
+
+ if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
+ throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
+ }
+ if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy && !$redisClient instanceof RedisClusterProxy) {
+ throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given.', __METHOD__, \is_object($redisClient) ? \get_class($redisClient) : \gettype($redisClient)));
+ }
+ $this->redis = $redisClient;
+ $this->marshaller = $marshaller ?? new DefaultMarshaller();
+ }
+
+ /**
+ * Creates a Redis connection using a DSN configuration.
+ *
+ * Example DSN:
+ * - redis://localhost
+ * - redis://example.com:1234
+ * - redis://secret@example.com/13
+ * - redis:///var/run/redis.sock
+ * - redis://secret@/var/run/redis.sock/13
+ *
+ * @param string $dsn
+ * @param array $options See self::$defaultConnectionOptions
+ *
+ * @throws InvalidArgumentException when the DSN is invalid
+ *
+ * @return \Redis|\RedisCluster|\Predis\Client According to the "class" option
+ */
+ public static function createConnection($dsn, array $options = [])
+ {
+ if (0 === strpos($dsn, 'redis:')) {
+ $scheme = 'redis';
+ } elseif (0 === strpos($dsn, 'rediss:')) {
+ $scheme = 'rediss';
+ } else {
+ throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis:" or "rediss".', $dsn));
+ }
+
+ if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) {
+ throw new CacheException(sprintf('Cannot find the "redis" extension nor the "predis/predis" package: %s', $dsn));
+ }
+
+ $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
+ if (isset($m[2])) {
+ $auth = $m[2];
+ }
+
+ return 'file:'.($m[1] ?? '');
+ }, $dsn);
+
+ if (false === $params = parse_url($params)) {
+ throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s', $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(sprintf('Invalid Redis DSN: %s', $dsn));
+ }
+ foreach ($hosts as $host => $parameters) {
+ if (\is_string($parameters)) {
+ parse_str($parameters, $parameters);
+ }
+ if (false === $i = strrpos($host, ':')) {
+ $hosts[$host] = ['scheme' => 'tcp', 'host' => $host, 'port' => 6379] + $parameters;
+ } elseif ($port = (int) substr($host, 1 + $i)) {
+ $hosts[$host] = ['scheme' => 'tcp', 'host' => substr($host, 0, $i), 'port' => $port] + $parameters;
+ } else {
+ $hosts[$host] = ['scheme' => 'unix', 'path' => substr($host, 0, $i)] + $parameters;
+ }
+ }
+ $hosts = array_values($hosts);
+ }
+ }
+
+ if (isset($params['host']) || isset($params['path'])) {
+ if (!isset($params['dbindex']) && isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
+ $params['dbindex'] = $m[1];
+ $params['path'] = substr($params['path'], 0, -\strlen($m[0]));
+ }
+
+ if (isset($params['host'])) {
+ array_unshift($hosts, ['scheme' => 'tcp', 'host' => $params['host'], 'port' => $params['port'] ?? 6379]);
+ } else {
+ array_unshift($hosts, ['scheme' => 'unix', 'path' => $params['path']]);
+ }
+ }
+
+ if (!$hosts) {
+ throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s', $dsn));
+ }
+
+ $params += $query + $options + self::$defaultConnectionOptions;
+
+ if (null === $params['class'] && \extension_loaded('redis')) {
+ $class = $params['redis_cluster'] ? \RedisCluster::class : (1 < \count($hosts) ? \RedisArray::class : \Redis::class);
+ } else {
+ $class = null === $params['class'] ? \Predis\Client::class : $params['class'];
+ }
+
+ if (is_a($class, \Redis::class, true)) {
+ $connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect';
+ $redis = new $class();
+
+ $initializer = function ($redis) use ($connect, $params, $dsn, $auth, $hosts) {
+ try {
+ @$redis->{$connect}($hosts[0]['host'] ?? $hosts[0]['path'], $hosts[0]['port'] ?? null, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval']);
+ } catch (\RedisException $e) {
+ throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn));
+ }
+
+ set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
+ $isConnected = $redis->isConnected();
+ restore_error_handler();
+ if (!$isConnected) {
+ $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : '';
+ throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $error, $dsn));
+ }
+
+ if ((null !== $auth && !$redis->auth($auth))
+ || ($params['dbindex'] && !$redis->select($params['dbindex']))
+ || ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout']))
+ ) {
+ $e = preg_replace('/^ERR /', '', $redis->getLastError());
+ throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e, $dsn));
+ }
+
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
+ $redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
+ }
+
+ return true;
+ };
+
+ if ($params['lazy']) {
+ $redis = new RedisProxy($redis, $initializer);
+ } else {
+ $initializer($redis);
+ }
+ } elseif (is_a($class, \RedisArray::class, true)) {
+ foreach ($hosts as $i => $host) {
+ $hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
+ }
+ $params['lazy_connect'] = $params['lazy'] ?? true;
+ $params['connect_timeout'] = $params['timeout'];
+
+ try {
+ $redis = new $class($hosts, $params);
+ } catch (\RedisClusterException $e) {
+ throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn));
+ }
+
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
+ $redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
+ }
+ } elseif (is_a($class, \RedisCluster::class, true)) {
+ $initializer = function () use ($class, $params, $dsn, $hosts) {
+ foreach ($hosts as $i => $host) {
+ $hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
+ }
+
+ try {
+ $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent']);
+ } catch (\RedisClusterException $e) {
+ throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn));
+ }
+
+ if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) {
+ $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
+ }
+ if ($params['compression'] && \defined('Redis::COMPRESSION_LZF')) {
+ $redis->setOption(\Redis::OPT_COMPRESSION, \Redis::COMPRESSION_LZF);
+ }
+ switch ($params['failover']) {
+ case 'error': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_ERROR); break;
+ case 'distribute': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE); break;
+ case 'slaves': $redis->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES); break;
+ }
+
+ return $redis;
+ };
+
+ $redis = $params['lazy'] ? new RedisClusterProxy($initializer) : $initializer();
+ } elseif (is_a($class, \Predis\Client::class, true)) {
+ if ($params['redis_cluster']) {
+ $params['cluster'] = 'redis';
+ }
+ $params += ['parameters' => []];
+ $params['parameters'] += [
+ 'persistent' => $params['persistent'],
+ 'timeout' => $params['timeout'],
+ 'read_write_timeout' => $params['read_timeout'],
+ 'tcp_nodelay' => true,
+ ];
+ if ($params['dbindex']) {
+ $params['parameters']['database'] = $params['dbindex'];
+ }
+ if (null !== $auth) {
+ $params['parameters']['password'] = $auth;
+ }
+ if (1 === \count($hosts) && !$params['redis_cluster']) {
+ $hosts = $hosts[0];
+ } elseif (\in_array($params['failover'], ['slaves', 'distribute'], true) && !isset($params['replication'])) {
+ $params['replication'] = true;
+ $hosts[0] += ['alias' => 'master'];
+ }
+
+ $redis = new $class($hosts, array_diff_key($params, self::$defaultConnectionOptions));
+ } elseif (class_exists($class, false)) {
+ throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster" nor "Predis\Client".', $class));
+ } else {
+ throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
+ }
+
+ return $redis;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch(array $ids)
+ {
+ if (!$ids) {
+ return [];
+ }
+
+ $result = [];
+
+ if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) {
+ $values = $this->pipeline(function () use ($ids) {
+ foreach ($ids as $id) {
+ yield 'get' => [$id];
+ }
+ });
+ } else {
+ $values = array_combine($ids, $this->redis->mget($ids));
+ }
+
+ foreach ($values as $id => $v) {
+ if ($v) {
+ $result[$id] = $this->marshaller->unmarshall($v);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doHave($id)
+ {
+ return (bool) $this->redis->exists($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClear($namespace)
+ {
+ $cleared = true;
+ if ($this->redis instanceof \Predis\Client) {
+ $evalArgs = [0, $namespace];
+ } else {
+ $evalArgs = [[$namespace], 0];
+ }
+
+ foreach ($this->getHosts() as $host) {
+ if (!isset($namespace[0])) {
+ $cleared = $host->flushDb() && $cleared;
+ continue;
+ }
+
+ $info = $host->info('Server');
+ $info = isset($info['Server']) ? $info['Server'] : $info;
+
+ if (!version_compare($info['redis_version'], '2.8', '>=')) {
+ // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS
+ // can hang your server when it is executed against large databases (millions of items).
+ // Whenever you hit this scale, you should really consider upgrading to Redis 2.8 or above.
+ $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]..'*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $evalArgs[0], $evalArgs[1]) && $cleared;
+ continue;
+ }
+
+ $cursor = null;
+ do {
+ $keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000);
+ if (isset($keys[1]) && \is_array($keys[1])) {
+ $cursor = $keys[0];
+ $keys = $keys[1];
+ }
+ if ($keys) {
+ $this->doDelete($keys);
+ }
+ } while ($cursor = (int) $cursor);
+ }
+
+ return $cleared;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doDelete(array $ids)
+ {
+ if (!$ids) {
+ return true;
+ }
+
+ if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) {
+ $this->pipeline(function () use ($ids) {
+ foreach ($ids as $id) {
+ yield 'del' => [$id];
+ }
+ })->rewind();
+ } else {
+ $this->redis->del($ids);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doSave(array $values, $lifetime)
+ {
+ if (!$values = $this->marshaller->marshall($values, $failed)) {
+ return $failed;
+ }
+
+ $results = $this->pipeline(function () use ($values, $lifetime) {
+ foreach ($values as $id => $value) {
+ if (0 >= $lifetime) {
+ yield 'set' => [$id, $value];
+ } else {
+ yield 'setEx' => [$id, $lifetime, $value];
+ }
+ }
+ });
+ foreach ($results as $id => $result) {
+ if (true !== $result && (!$result instanceof Status || $result !== Status::get('OK'))) {
+ $failed[] = $id;
+ }
+ }
+
+ return $failed;
+ }
+
+ private function pipeline(\Closure $generator)
+ {
+ $ids = [];
+
+ if ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof RedisCluster)) {
+ // phpredis & predis don't support pipelining with RedisCluster
+ // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining
+ // see https://github.com/nrk/predis/issues/267#issuecomment-123781423
+ $results = [];
+ foreach ($generator() as $command => $args) {
+ $results[] = $this->redis->{$command}(...$args);
+ $ids[] = $args[0];
+ }
+ } elseif ($this->redis instanceof \Predis\Client) {
+ $results = $this->redis->pipeline(function ($redis) use ($generator, &$ids) {
+ foreach ($generator() as $command => $args) {
+ $redis->{$command}(...$args);
+ $ids[] = $args[0];
+ }
+ });
+ } elseif ($this->redis instanceof \RedisArray) {
+ $connections = $results = $ids = [];
+ foreach ($generator() as $command => $args) {
+ if (!isset($connections[$h = $this->redis->_target($args[0])])) {
+ $connections[$h] = [$this->redis->_instance($h), -1];
+ $connections[$h][0]->multi(\Redis::PIPELINE);
+ }
+ $connections[$h][0]->{$command}(...$args);
+ $results[] = [$h, ++$connections[$h][1]];
+ $ids[] = $args[0];
+ }
+ foreach ($connections as $h => $c) {
+ $connections[$h] = $c[0]->exec();
+ }
+ foreach ($results as $k => list($h, $c)) {
+ $results[$k] = $connections[$h][$c];
+ }
+ } else {
+ $this->redis->multi(\Redis::PIPELINE);
+ foreach ($generator() as $command => $args) {
+ $this->redis->{$command}(...$args);
+ $ids[] = $args[0];
+ }
+ $results = $this->redis->exec();
+ }
+
+ foreach ($ids as $k => $id) {
+ yield $id => $results[$k];
+ }
+ }
+
+ private function getHosts(): array
+ {
+ $hosts = [$this->redis];
+ if ($this->redis instanceof \Predis\Client) {
+ $connection = $this->redis->getConnection();
+ if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) {
+ $hosts = [];
+ foreach ($connection as $c) {
+ $hosts[] = new \Predis\Client($c);
+ }
+ }
+ } elseif ($this->redis instanceof \RedisArray) {
+ $hosts = [];
+ foreach ($this->redis->_hosts() as $host) {
+ $hosts[] = $this->redis->_instance($host);
+ }
+ } elseif ($this->redis instanceof RedisClusterProxy || $this->redis instanceof \RedisCluster) {
+ $hosts = [];
+ foreach ($this->redis->_masters() as $host) {
+ $hosts[] = $h = new \Redis();
+ $h->connect($host[0], $host[1]);
+ }
+ }
+
+ return $hosts;
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/composer.json b/addons/weliam_smartcity/vendor/symfony/cache/composer.json
new file mode 100644
index 0000000..05bed1c
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/cache",
+ "type": "library",
+ "description": "Symfony Cache component with PSR-6, PSR-16, and tags",
+ "keywords": ["caching", "psr6"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "provide": {
+ "psr/cache-implementation": "1.0",
+ "psr/simple-cache-implementation": "1.0",
+ "symfony/cache-implementation": "1.0"
+ },
+ "require": {
+ "php": "^7.1.3",
+ "psr/cache": "~1.0",
+ "psr/log": "~1.0",
+ "symfony/cache-contracts": "^1.1",
+ "symfony/service-contracts": "^1.1",
+ "symfony/var-exporter": "^4.2"
+ },
+ "require-dev": {
+ "cache/integration-tests": "dev-master",
+ "doctrine/cache": "~1.6",
+ "doctrine/dbal": "~2.5",
+ "predis/predis": "~1.1",
+ "psr/simple-cache": "^1.0",
+ "symfony/config": "~4.2",
+ "symfony/dependency-injection": "~3.4|~4.1",
+ "symfony/var-dumper": "^4.1.1"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.5",
+ "symfony/dependency-injection": "<3.4",
+ "symfony/var-dumper": "<3.4"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Cache\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.3-dev"
+ }
+ }
+}
diff --git a/addons/weliam_smartcity/vendor/symfony/cache/phpunit.xml.dist b/addons/weliam_smartcity/vendor/symfony/cache/phpunit.xml.dist
new file mode 100644
index 0000000..591046c
--- /dev/null
+++ b/addons/weliam_smartcity/vendor/symfony/cache/phpunit.xml.dist
@@ -0,0 +1,51 @@
+
+
+